Merge branch 'rth/atomic/ppc'
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blobf01353b894233b94eb2224b53f1507235d360d84
1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "recog.h"
35 #include "obstack.h"
36 #include "tree.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "except.h"
40 #include "function.h"
41 #include "output.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "hashtab.h"
48 #include "tm_p.h"
49 #include "target.h"
50 #include "target-def.h"
51 #include "common/common-target.h"
52 #include "langhooks.h"
53 #include "reload.h"
54 #include "cfglayout.h"
55 #include "cfgloop.h"
56 #include "sched-int.h"
57 #include "gimple.h"
58 #include "tree-flow.h"
59 #include "intl.h"
60 #include "params.h"
61 #include "tm-constrs.h"
62 #include "opts.h"
63 #if TARGET_XCOFF
64 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
65 #endif
66 #if TARGET_MACHO
67 #include "gstab.h" /* for N_SLINE */
68 #endif
70 #ifndef TARGET_NO_PROTOTYPE
71 #define TARGET_NO_PROTOTYPE 0
72 #endif
74 #define min(A,B) ((A) < (B) ? (A) : (B))
75 #define max(A,B) ((A) > (B) ? (A) : (B))
77 /* Structure used to define the rs6000 stack */
78 typedef struct rs6000_stack {
79 int reload_completed; /* stack info won't change from here on */
80 int first_gp_reg_save; /* first callee saved GP register used */
81 int first_fp_reg_save; /* first callee saved FP register used */
82 int first_altivec_reg_save; /* first callee saved AltiVec register used */
83 int lr_save_p; /* true if the link reg needs to be saved */
84 int cr_save_p; /* true if the CR reg needs to be saved */
85 unsigned int vrsave_mask; /* mask of vec registers to save */
86 int push_p; /* true if we need to allocate stack space */
87 int calls_p; /* true if the function makes any calls */
88 int world_save_p; /* true if we're saving *everything*:
89 r13-r31, cr, f14-f31, vrsave, v20-v31 */
90 enum rs6000_abi abi; /* which ABI to use */
91 int gp_save_offset; /* offset to save GP regs from initial SP */
92 int fp_save_offset; /* offset to save FP regs from initial SP */
93 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
94 int lr_save_offset; /* offset to save LR from initial SP */
95 int cr_save_offset; /* offset to save CR from initial SP */
96 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
97 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
98 int varargs_save_offset; /* offset to save the varargs registers */
99 int ehrd_offset; /* offset to EH return data */
100 int reg_size; /* register size (4 or 8) */
101 HOST_WIDE_INT vars_size; /* variable save area size */
102 int parm_size; /* outgoing parameter size */
103 int save_size; /* save area size */
104 int fixed_size; /* fixed size of stack frame */
105 int gp_size; /* size of saved GP registers */
106 int fp_size; /* size of saved FP registers */
107 int altivec_size; /* size of saved AltiVec registers */
108 int cr_size; /* size to hold CR if not in save_size */
109 int vrsave_size; /* size to hold VRSAVE if not in save_size */
110 int altivec_padding_size; /* size of altivec alignment padding if
111 not in save_size */
112 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
113 int spe_padding_size;
114 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
115 int spe_64bit_regs_used;
116 int savres_strategy;
117 } rs6000_stack_t;
119 /* A C structure for machine-specific, per-function data.
120 This is added to the cfun structure. */
121 typedef struct GTY(()) machine_function
123 /* Some local-dynamic symbol. */
124 const char *some_ld_name;
125 /* Whether the instruction chain has been scanned already. */
126 int insn_chain_scanned_p;
127 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
128 int ra_needs_full_frame;
129 /* Flags if __builtin_return_address (0) was used. */
130 int ra_need_lr;
131 /* Cache lr_save_p after expansion of builtin_eh_return. */
132 int lr_save_state;
133 /* Whether we need to save the TOC to the reserved stack location in the
134 function prologue. */
135 bool save_toc_in_prologue;
136 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
137 varargs save area. */
138 HOST_WIDE_INT varargs_save_offset;
139 /* Temporary stack slot to use for SDmode copies. This slot is
140 64-bits wide and is allocated early enough so that the offset
141 does not overflow the 16-bit load/store offset field. */
142 rtx sdmode_stack_slot;
143 } machine_function;
145 /* Support targetm.vectorize.builtin_mask_for_load. */
146 static GTY(()) tree altivec_builtin_mask_for_load;
148 /* Set to nonzero once AIX common-mode calls have been defined. */
149 static GTY(()) int common_mode_defined;
151 /* Label number of label created for -mrelocatable, to call to so we can
152 get the address of the GOT section */
153 static int rs6000_pic_labelno;
155 #ifdef USING_ELFOS_H
156 /* Counter for labels which are to be placed in .fixup. */
157 int fixuplabelno = 0;
158 #endif
160 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
161 int dot_symbols;
163 /* Specify the machine mode that pointers have. After generation of rtl, the
164 compiler makes no further distinction between pointers and any other objects
165 of this machine mode. The type is unsigned since not all things that
166 include rs6000.h also include machmode.h. */
167 unsigned rs6000_pmode;
169 /* Width in bits of a pointer. */
170 unsigned rs6000_pointer_size;
172 #ifdef HAVE_AS_GNU_ATTRIBUTE
173 /* Flag whether floating point values have been passed/returned. */
174 static bool rs6000_passes_float;
175 /* Flag whether vector values have been passed/returned. */
176 static bool rs6000_passes_vector;
177 /* Flag whether small (<= 8 byte) structures have been returned. */
178 static bool rs6000_returns_struct;
179 #endif
181 /* Value is TRUE if register/mode pair is acceptable. */
182 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
184 /* Maximum number of registers needed for a given register class and mode. */
185 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
187 /* How many registers are needed for a given register and mode. */
188 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
190 /* Map register number to register class. */
191 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
193 /* Reload functions based on the type and the vector unit. */
194 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
196 static int dbg_cost_ctrl;
198 /* Built in types. */
199 tree rs6000_builtin_types[RS6000_BTI_MAX];
200 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
202 /* Flag to say the TOC is initialized */
203 int toc_initialized;
204 char toc_label_name[10];
206 /* Cached value of rs6000_variable_issue. This is cached in
207 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
208 static short cached_can_issue_more;
210 static GTY(()) section *read_only_data_section;
211 static GTY(()) section *private_data_section;
212 static GTY(()) section *read_only_private_data_section;
213 static GTY(()) section *sdata2_section;
214 static GTY(()) section *toc_section;
216 struct builtin_description
218 /* mask is not const because we're going to alter it below. This
219 nonsense will go away when we rewrite the -march infrastructure
220 to give us more target flag bits. */
221 unsigned int mask;
222 const enum insn_code icode;
223 const char *const name;
224 const enum rs6000_builtins code;
227 /* Describe the vector unit used for modes. */
228 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
229 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
231 /* Register classes for various constraints that are based on the target
232 switches. */
233 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
235 /* Describe the alignment of a vector. */
236 int rs6000_vector_align[NUM_MACHINE_MODES];
238 /* Map selected modes to types for builtins. */
239 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
241 /* What modes to automatically generate reciprocal divide estimate (fre) and
242 reciprocal sqrt (frsqrte) for. */
243 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
245 /* Masks to determine which reciprocal esitmate instructions to generate
246 automatically. */
247 enum rs6000_recip_mask {
248 RECIP_SF_DIV = 0x001, /* Use divide estimate */
249 RECIP_DF_DIV = 0x002,
250 RECIP_V4SF_DIV = 0x004,
251 RECIP_V2DF_DIV = 0x008,
253 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
254 RECIP_DF_RSQRT = 0x020,
255 RECIP_V4SF_RSQRT = 0x040,
256 RECIP_V2DF_RSQRT = 0x080,
258 /* Various combination of flags for -mrecip=xxx. */
259 RECIP_NONE = 0,
260 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
261 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
262 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
264 RECIP_HIGH_PRECISION = RECIP_ALL,
266 /* On low precision machines like the power5, don't enable double precision
267 reciprocal square root estimate, since it isn't accurate enough. */
268 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
271 /* -mrecip options. */
272 static struct
274 const char *string; /* option name */
275 unsigned int mask; /* mask bits to set */
276 } recip_options[] = {
277 { "all", RECIP_ALL },
278 { "none", RECIP_NONE },
279 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
280 | RECIP_V2DF_DIV) },
281 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
282 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
283 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
284 | RECIP_V2DF_RSQRT) },
285 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
286 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
289 /* 2 argument gen function typedef. */
290 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
293 /* Target cpu costs. */
295 struct processor_costs {
296 const int mulsi; /* cost of SImode multiplication. */
297 const int mulsi_const; /* cost of SImode multiplication by constant. */
298 const int mulsi_const9; /* cost of SImode mult by short constant. */
299 const int muldi; /* cost of DImode multiplication. */
300 const int divsi; /* cost of SImode division. */
301 const int divdi; /* cost of DImode division. */
302 const int fp; /* cost of simple SFmode and DFmode insns. */
303 const int dmul; /* cost of DFmode multiplication (and fmadd). */
304 const int sdiv; /* cost of SFmode division (fdivs). */
305 const int ddiv; /* cost of DFmode division (fdiv). */
306 const int cache_line_size; /* cache line size in bytes. */
307 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
308 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
309 const int simultaneous_prefetches; /* number of parallel prefetch
310 operations. */
313 const struct processor_costs *rs6000_cost;
315 /* Processor costs (relative to an add) */
317 /* Instruction size costs on 32bit processors. */
318 static const
319 struct processor_costs size32_cost = {
320 COSTS_N_INSNS (1), /* mulsi */
321 COSTS_N_INSNS (1), /* mulsi_const */
322 COSTS_N_INSNS (1), /* mulsi_const9 */
323 COSTS_N_INSNS (1), /* muldi */
324 COSTS_N_INSNS (1), /* divsi */
325 COSTS_N_INSNS (1), /* divdi */
326 COSTS_N_INSNS (1), /* fp */
327 COSTS_N_INSNS (1), /* dmul */
328 COSTS_N_INSNS (1), /* sdiv */
329 COSTS_N_INSNS (1), /* ddiv */
336 /* Instruction size costs on 64bit processors. */
337 static const
338 struct processor_costs size64_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 */
349 128,
355 /* Instruction costs on RIOS1 processors. */
356 static const
357 struct processor_costs rios1_cost = {
358 COSTS_N_INSNS (5), /* mulsi */
359 COSTS_N_INSNS (4), /* mulsi_const */
360 COSTS_N_INSNS (3), /* mulsi_const9 */
361 COSTS_N_INSNS (5), /* muldi */
362 COSTS_N_INSNS (19), /* divsi */
363 COSTS_N_INSNS (19), /* divdi */
364 COSTS_N_INSNS (2), /* fp */
365 COSTS_N_INSNS (2), /* dmul */
366 COSTS_N_INSNS (19), /* sdiv */
367 COSTS_N_INSNS (19), /* ddiv */
368 128, /* cache line size */
369 64, /* l1 cache */
370 512, /* l2 cache */
371 0, /* streams */
374 /* Instruction costs on RIOS2 processors. */
375 static const
376 struct processor_costs rios2_cost = {
377 COSTS_N_INSNS (2), /* mulsi */
378 COSTS_N_INSNS (2), /* mulsi_const */
379 COSTS_N_INSNS (2), /* mulsi_const9 */
380 COSTS_N_INSNS (2), /* muldi */
381 COSTS_N_INSNS (13), /* divsi */
382 COSTS_N_INSNS (13), /* divdi */
383 COSTS_N_INSNS (2), /* fp */
384 COSTS_N_INSNS (2), /* dmul */
385 COSTS_N_INSNS (17), /* sdiv */
386 COSTS_N_INSNS (17), /* ddiv */
387 256, /* cache line size */
388 256, /* l1 cache */
389 1024, /* l2 cache */
390 0, /* streams */
393 /* Instruction costs on RS64A processors. */
394 static const
395 struct processor_costs rs64a_cost = {
396 COSTS_N_INSNS (20), /* mulsi */
397 COSTS_N_INSNS (12), /* mulsi_const */
398 COSTS_N_INSNS (8), /* mulsi_const9 */
399 COSTS_N_INSNS (34), /* muldi */
400 COSTS_N_INSNS (65), /* divsi */
401 COSTS_N_INSNS (67), /* divdi */
402 COSTS_N_INSNS (4), /* fp */
403 COSTS_N_INSNS (4), /* dmul */
404 COSTS_N_INSNS (31), /* sdiv */
405 COSTS_N_INSNS (31), /* ddiv */
406 128, /* cache line size */
407 128, /* l1 cache */
408 2048, /* l2 cache */
409 1, /* streams */
412 /* Instruction costs on MPCCORE processors. */
413 static const
414 struct processor_costs mpccore_cost = {
415 COSTS_N_INSNS (2), /* mulsi */
416 COSTS_N_INSNS (2), /* mulsi_const */
417 COSTS_N_INSNS (2), /* mulsi_const9 */
418 COSTS_N_INSNS (2), /* muldi */
419 COSTS_N_INSNS (6), /* divsi */
420 COSTS_N_INSNS (6), /* divdi */
421 COSTS_N_INSNS (4), /* fp */
422 COSTS_N_INSNS (5), /* dmul */
423 COSTS_N_INSNS (10), /* sdiv */
424 COSTS_N_INSNS (17), /* ddiv */
425 32, /* cache line size */
426 4, /* l1 cache */
427 16, /* l2 cache */
428 1, /* streams */
431 /* Instruction costs on PPC403 processors. */
432 static const
433 struct processor_costs ppc403_cost = {
434 COSTS_N_INSNS (4), /* mulsi */
435 COSTS_N_INSNS (4), /* mulsi_const */
436 COSTS_N_INSNS (4), /* mulsi_const9 */
437 COSTS_N_INSNS (4), /* muldi */
438 COSTS_N_INSNS (33), /* divsi */
439 COSTS_N_INSNS (33), /* divdi */
440 COSTS_N_INSNS (11), /* fp */
441 COSTS_N_INSNS (11), /* dmul */
442 COSTS_N_INSNS (11), /* sdiv */
443 COSTS_N_INSNS (11), /* ddiv */
444 32, /* cache line size */
445 4, /* l1 cache */
446 16, /* l2 cache */
447 1, /* streams */
450 /* Instruction costs on PPC405 processors. */
451 static const
452 struct processor_costs ppc405_cost = {
453 COSTS_N_INSNS (5), /* mulsi */
454 COSTS_N_INSNS (4), /* mulsi_const */
455 COSTS_N_INSNS (3), /* mulsi_const9 */
456 COSTS_N_INSNS (5), /* muldi */
457 COSTS_N_INSNS (35), /* divsi */
458 COSTS_N_INSNS (35), /* 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 16, /* l1 cache */
465 128, /* l2 cache */
466 1, /* streams */
469 /* Instruction costs on PPC440 processors. */
470 static const
471 struct processor_costs ppc440_cost = {
472 COSTS_N_INSNS (3), /* mulsi */
473 COSTS_N_INSNS (2), /* mulsi_const */
474 COSTS_N_INSNS (2), /* mulsi_const9 */
475 COSTS_N_INSNS (3), /* muldi */
476 COSTS_N_INSNS (34), /* divsi */
477 COSTS_N_INSNS (34), /* divdi */
478 COSTS_N_INSNS (5), /* fp */
479 COSTS_N_INSNS (5), /* dmul */
480 COSTS_N_INSNS (19), /* sdiv */
481 COSTS_N_INSNS (33), /* ddiv */
482 32, /* cache line size */
483 32, /* l1 cache */
484 256, /* l2 cache */
485 1, /* streams */
488 /* Instruction costs on PPC476 processors. */
489 static const
490 struct processor_costs ppc476_cost = {
491 COSTS_N_INSNS (4), /* mulsi */
492 COSTS_N_INSNS (4), /* mulsi_const */
493 COSTS_N_INSNS (4), /* mulsi_const9 */
494 COSTS_N_INSNS (4), /* muldi */
495 COSTS_N_INSNS (11), /* divsi */
496 COSTS_N_INSNS (11), /* divdi */
497 COSTS_N_INSNS (6), /* fp */
498 COSTS_N_INSNS (6), /* dmul */
499 COSTS_N_INSNS (19), /* sdiv */
500 COSTS_N_INSNS (33), /* ddiv */
501 32, /* l1 cache line size */
502 32, /* l1 cache */
503 512, /* l2 cache */
504 1, /* streams */
507 /* Instruction costs on PPC601 processors. */
508 static const
509 struct processor_costs ppc601_cost = {
510 COSTS_N_INSNS (5), /* mulsi */
511 COSTS_N_INSNS (5), /* mulsi_const */
512 COSTS_N_INSNS (5), /* mulsi_const9 */
513 COSTS_N_INSNS (5), /* muldi */
514 COSTS_N_INSNS (36), /* divsi */
515 COSTS_N_INSNS (36), /* divdi */
516 COSTS_N_INSNS (4), /* fp */
517 COSTS_N_INSNS (5), /* dmul */
518 COSTS_N_INSNS (17), /* sdiv */
519 COSTS_N_INSNS (31), /* ddiv */
520 32, /* cache line size */
521 32, /* l1 cache */
522 256, /* l2 cache */
523 1, /* streams */
526 /* Instruction costs on PPC603 processors. */
527 static const
528 struct processor_costs ppc603_cost = {
529 COSTS_N_INSNS (5), /* mulsi */
530 COSTS_N_INSNS (3), /* mulsi_const */
531 COSTS_N_INSNS (2), /* mulsi_const9 */
532 COSTS_N_INSNS (5), /* muldi */
533 COSTS_N_INSNS (37), /* divsi */
534 COSTS_N_INSNS (37), /* divdi */
535 COSTS_N_INSNS (3), /* fp */
536 COSTS_N_INSNS (4), /* dmul */
537 COSTS_N_INSNS (18), /* sdiv */
538 COSTS_N_INSNS (33), /* ddiv */
539 32, /* cache line size */
540 8, /* l1 cache */
541 64, /* l2 cache */
542 1, /* streams */
545 /* Instruction costs on PPC604 processors. */
546 static const
547 struct processor_costs ppc604_cost = {
548 COSTS_N_INSNS (4), /* mulsi */
549 COSTS_N_INSNS (4), /* mulsi_const */
550 COSTS_N_INSNS (4), /* mulsi_const9 */
551 COSTS_N_INSNS (4), /* muldi */
552 COSTS_N_INSNS (20), /* divsi */
553 COSTS_N_INSNS (20), /* divdi */
554 COSTS_N_INSNS (3), /* fp */
555 COSTS_N_INSNS (3), /* dmul */
556 COSTS_N_INSNS (18), /* sdiv */
557 COSTS_N_INSNS (32), /* ddiv */
558 32, /* cache line size */
559 16, /* l1 cache */
560 512, /* l2 cache */
561 1, /* streams */
564 /* Instruction costs on PPC604e processors. */
565 static const
566 struct processor_costs ppc604e_cost = {
567 COSTS_N_INSNS (2), /* mulsi */
568 COSTS_N_INSNS (2), /* mulsi_const */
569 COSTS_N_INSNS (2), /* mulsi_const9 */
570 COSTS_N_INSNS (2), /* 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 32, /* l1 cache */
579 1024, /* l2 cache */
580 1, /* streams */
583 /* Instruction costs on PPC620 processors. */
584 static const
585 struct processor_costs ppc620_cost = {
586 COSTS_N_INSNS (5), /* mulsi */
587 COSTS_N_INSNS (4), /* mulsi_const */
588 COSTS_N_INSNS (3), /* mulsi_const9 */
589 COSTS_N_INSNS (7), /* muldi */
590 COSTS_N_INSNS (21), /* divsi */
591 COSTS_N_INSNS (37), /* 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 128, /* cache line size */
597 32, /* l1 cache */
598 1024, /* l2 cache */
599 1, /* streams */
602 /* Instruction costs on PPC630 processors. */
603 static const
604 struct processor_costs ppc630_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 (17), /* sdiv */
614 COSTS_N_INSNS (21), /* ddiv */
615 128, /* cache line size */
616 64, /* l1 cache */
617 1024, /* l2 cache */
618 1, /* streams */
621 /* Instruction costs on Cell processor. */
622 /* COSTS_N_INSNS (1) ~ one add. */
623 static const
624 struct processor_costs ppccell_cost = {
625 COSTS_N_INSNS (9/2)+2, /* mulsi */
626 COSTS_N_INSNS (6/2), /* mulsi_const */
627 COSTS_N_INSNS (6/2), /* mulsi_const9 */
628 COSTS_N_INSNS (15/2)+2, /* muldi */
629 COSTS_N_INSNS (38/2), /* divsi */
630 COSTS_N_INSNS (70/2), /* divdi */
631 COSTS_N_INSNS (10/2), /* fp */
632 COSTS_N_INSNS (10/2), /* dmul */
633 COSTS_N_INSNS (74/2), /* sdiv */
634 COSTS_N_INSNS (74/2), /* ddiv */
635 128, /* cache line size */
636 32, /* l1 cache */
637 512, /* l2 cache */
638 6, /* streams */
641 /* Instruction costs on PPC750 and PPC7400 processors. */
642 static const
643 struct processor_costs ppc750_cost = {
644 COSTS_N_INSNS (5), /* mulsi */
645 COSTS_N_INSNS (3), /* mulsi_const */
646 COSTS_N_INSNS (2), /* mulsi_const9 */
647 COSTS_N_INSNS (5), /* muldi */
648 COSTS_N_INSNS (17), /* divsi */
649 COSTS_N_INSNS (17), /* divdi */
650 COSTS_N_INSNS (3), /* fp */
651 COSTS_N_INSNS (3), /* dmul */
652 COSTS_N_INSNS (17), /* sdiv */
653 COSTS_N_INSNS (31), /* ddiv */
654 32, /* cache line size */
655 32, /* l1 cache */
656 512, /* l2 cache */
657 1, /* streams */
660 /* Instruction costs on PPC7450 processors. */
661 static const
662 struct processor_costs ppc7450_cost = {
663 COSTS_N_INSNS (4), /* mulsi */
664 COSTS_N_INSNS (3), /* mulsi_const */
665 COSTS_N_INSNS (3), /* mulsi_const9 */
666 COSTS_N_INSNS (4), /* muldi */
667 COSTS_N_INSNS (23), /* divsi */
668 COSTS_N_INSNS (23), /* divdi */
669 COSTS_N_INSNS (5), /* fp */
670 COSTS_N_INSNS (5), /* dmul */
671 COSTS_N_INSNS (21), /* sdiv */
672 COSTS_N_INSNS (35), /* ddiv */
673 32, /* cache line size */
674 32, /* l1 cache */
675 1024, /* l2 cache */
676 1, /* streams */
679 /* Instruction costs on PPC8540 processors. */
680 static const
681 struct processor_costs ppc8540_cost = {
682 COSTS_N_INSNS (4), /* mulsi */
683 COSTS_N_INSNS (4), /* mulsi_const */
684 COSTS_N_INSNS (4), /* mulsi_const9 */
685 COSTS_N_INSNS (4), /* muldi */
686 COSTS_N_INSNS (19), /* divsi */
687 COSTS_N_INSNS (19), /* divdi */
688 COSTS_N_INSNS (4), /* fp */
689 COSTS_N_INSNS (4), /* dmul */
690 COSTS_N_INSNS (29), /* sdiv */
691 COSTS_N_INSNS (29), /* ddiv */
692 32, /* cache line size */
693 32, /* l1 cache */
694 256, /* l2 cache */
695 1, /* prefetch streams /*/
698 /* Instruction costs on E300C2 and E300C3 cores. */
699 static const
700 struct processor_costs ppce300c2c3_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 (3), /* fp */
708 COSTS_N_INSNS (4), /* dmul */
709 COSTS_N_INSNS (18), /* sdiv */
710 COSTS_N_INSNS (33), /* ddiv */
712 16, /* l1 cache */
713 16, /* l2 cache */
714 1, /* prefetch streams /*/
717 /* Instruction costs on PPCE500MC processors. */
718 static const
719 struct processor_costs ppce500mc_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 (14), /* divsi */
725 COSTS_N_INSNS (14), /* divdi */
726 COSTS_N_INSNS (8), /* fp */
727 COSTS_N_INSNS (10), /* dmul */
728 COSTS_N_INSNS (36), /* sdiv */
729 COSTS_N_INSNS (66), /* ddiv */
730 64, /* cache line size */
731 32, /* l1 cache */
732 128, /* l2 cache */
733 1, /* prefetch streams /*/
736 /* Instruction costs on PPCE500MC64 processors. */
737 static const
738 struct processor_costs ppce500mc64_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 (4), /* 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 AppliedMicro Titan processors. */
756 static const
757 struct processor_costs titan_cost = {
758 COSTS_N_INSNS (5), /* mulsi */
759 COSTS_N_INSNS (5), /* mulsi_const */
760 COSTS_N_INSNS (5), /* mulsi_const9 */
761 COSTS_N_INSNS (5), /* muldi */
762 COSTS_N_INSNS (18), /* divsi */
763 COSTS_N_INSNS (18), /* divdi */
764 COSTS_N_INSNS (10), /* fp */
765 COSTS_N_INSNS (10), /* dmul */
766 COSTS_N_INSNS (46), /* sdiv */
767 COSTS_N_INSNS (72), /* ddiv */
768 32, /* cache line size */
769 32, /* l1 cache */
770 512, /* l2 cache */
771 1, /* prefetch streams /*/
774 /* Instruction costs on POWER4 and POWER5 processors. */
775 static const
776 struct processor_costs power4_cost = {
777 COSTS_N_INSNS (3), /* mulsi */
778 COSTS_N_INSNS (2), /* mulsi_const */
779 COSTS_N_INSNS (2), /* mulsi_const9 */
780 COSTS_N_INSNS (4), /* muldi */
781 COSTS_N_INSNS (18), /* divsi */
782 COSTS_N_INSNS (34), /* divdi */
783 COSTS_N_INSNS (3), /* fp */
784 COSTS_N_INSNS (3), /* dmul */
785 COSTS_N_INSNS (17), /* sdiv */
786 COSTS_N_INSNS (17), /* ddiv */
787 128, /* cache line size */
788 32, /* l1 cache */
789 1024, /* l2 cache */
790 8, /* prefetch streams /*/
793 /* Instruction costs on POWER6 processors. */
794 static const
795 struct processor_costs power6_cost = {
796 COSTS_N_INSNS (8), /* mulsi */
797 COSTS_N_INSNS (8), /* mulsi_const */
798 COSTS_N_INSNS (8), /* mulsi_const9 */
799 COSTS_N_INSNS (8), /* muldi */
800 COSTS_N_INSNS (22), /* divsi */
801 COSTS_N_INSNS (28), /* divdi */
802 COSTS_N_INSNS (3), /* fp */
803 COSTS_N_INSNS (3), /* dmul */
804 COSTS_N_INSNS (13), /* sdiv */
805 COSTS_N_INSNS (16), /* ddiv */
806 128, /* cache line size */
807 64, /* l1 cache */
808 2048, /* l2 cache */
809 16, /* prefetch streams */
812 /* Instruction costs on POWER7 processors. */
813 static const
814 struct processor_costs power7_cost = {
815 COSTS_N_INSNS (2), /* mulsi */
816 COSTS_N_INSNS (2), /* mulsi_const */
817 COSTS_N_INSNS (2), /* mulsi_const9 */
818 COSTS_N_INSNS (2), /* muldi */
819 COSTS_N_INSNS (18), /* divsi */
820 COSTS_N_INSNS (34), /* 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 32, /* l1 cache */
827 256, /* l2 cache */
828 12, /* prefetch streams */
831 /* Instruction costs on POWER A2 processors. */
832 static const
833 struct processor_costs ppca2_cost = {
834 COSTS_N_INSNS (16), /* mulsi */
835 COSTS_N_INSNS (16), /* mulsi_const */
836 COSTS_N_INSNS (16), /* mulsi_const9 */
837 COSTS_N_INSNS (16), /* muldi */
838 COSTS_N_INSNS (22), /* divsi */
839 COSTS_N_INSNS (28), /* divdi */
840 COSTS_N_INSNS (3), /* fp */
841 COSTS_N_INSNS (3), /* dmul */
842 COSTS_N_INSNS (59), /* sdiv */
843 COSTS_N_INSNS (72), /* ddiv */
845 16, /* l1 cache */
846 2048, /* l2 cache */
847 16, /* prefetch streams */
851 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
852 #undef RS6000_BUILTIN
853 #undef RS6000_BUILTIN_EQUATE
854 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
855 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
857 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
859 #include "rs6000-builtin.def"
862 #undef RS6000_BUILTIN
863 #undef RS6000_BUILTIN_EQUATE
865 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
866 static tree (*rs6000_veclib_handler) (tree, tree, tree);
869 static bool rs6000_function_ok_for_sibcall (tree, tree);
870 static const char *rs6000_invalid_within_doloop (const_rtx);
871 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
872 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
873 static rtx rs6000_generate_compare (rtx, enum machine_mode);
874 static void rs6000_emit_stack_tie (void);
875 static bool spe_func_has_64bit_regs_p (void);
876 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
877 static unsigned rs6000_hash_constant (rtx);
878 static unsigned toc_hash_function (const void *);
879 static int toc_hash_eq (const void *, const void *);
880 static bool reg_offset_addressing_ok_p (enum machine_mode);
881 static bool virtual_stack_registers_memory_p (rtx);
882 static bool constant_pool_expr_p (rtx);
883 static bool legitimate_small_data_p (enum machine_mode, rtx);
884 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
885 static struct machine_function * rs6000_init_machine_status (void);
886 static bool rs6000_assemble_integer (rtx, unsigned int, int);
887 static bool no_global_regs_above (int, bool);
888 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
889 static void rs6000_assemble_visibility (tree, int);
890 #endif
891 static int rs6000_ra_ever_killed (void);
892 static bool rs6000_attribute_takes_identifier_p (const_tree);
893 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
894 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
895 static bool rs6000_ms_bitfield_layout_p (const_tree);
896 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
897 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
898 static const char *rs6000_mangle_type (const_tree);
899 static void rs6000_set_default_type_attributes (tree);
900 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
901 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
902 static bool rs6000_reg_live_or_pic_offset_p (int);
903 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
904 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
905 static void rs6000_restore_saved_cr (rtx, int);
906 static bool rs6000_output_addr_const_extra (FILE *, rtx);
907 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
908 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
909 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
910 tree);
911 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
912 static bool rs6000_return_in_memory (const_tree, const_tree);
913 static rtx rs6000_function_value (const_tree, const_tree, bool);
914 static void rs6000_file_start (void);
915 #if TARGET_ELF
916 static int rs6000_elf_reloc_rw_mask (void);
917 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
918 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
919 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
920 static void rs6000_elf_asm_init_sections (void);
921 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
922 unsigned HOST_WIDE_INT);
923 static void rs6000_elf_encode_section_info (tree, rtx, int)
924 ATTRIBUTE_UNUSED;
925 #endif
926 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
927 static void rs6000_alloc_sdmode_stack_slot (void);
928 static void rs6000_instantiate_decls (void);
929 #if TARGET_XCOFF
930 static void rs6000_xcoff_asm_output_anchor (rtx);
931 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
932 static void rs6000_xcoff_asm_init_sections (void);
933 static int rs6000_xcoff_reloc_rw_mask (void);
934 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
935 static section *rs6000_xcoff_select_section (tree, int,
936 unsigned HOST_WIDE_INT);
937 static void rs6000_xcoff_unique_section (tree, int);
938 static section *rs6000_xcoff_select_rtx_section
939 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
940 static const char * rs6000_xcoff_strip_name_encoding (const char *);
941 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
942 static void rs6000_xcoff_file_start (void);
943 static void rs6000_xcoff_file_end (void);
944 #endif
945 static int rs6000_variable_issue (FILE *, int, rtx, int);
946 static int rs6000_register_move_cost (enum machine_mode,
947 reg_class_t, reg_class_t);
948 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
949 static bool rs6000_rtx_costs (rtx, int, int, int, int *, bool);
950 static bool rs6000_debug_rtx_costs (rtx, int, int, int, int *, bool);
951 static int rs6000_debug_address_cost (rtx, bool);
952 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
953 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
954 static void rs6000_sched_init (FILE *, int, int);
955 static bool is_microcoded_insn (rtx);
956 static bool is_nonpipeline_insn (rtx);
957 static bool is_cracked_insn (rtx);
958 static bool is_branch_slot_insn (rtx);
959 static bool is_load_insn (rtx);
960 static rtx get_store_dest (rtx pat);
961 static bool is_store_insn (rtx);
962 static bool set_to_load_agen (rtx,rtx);
963 static bool adjacent_mem_locations (rtx,rtx);
964 static int rs6000_adjust_priority (rtx, int);
965 static int rs6000_issue_rate (void);
966 static bool rs6000_is_costly_dependence (dep_t, int, int);
967 static rtx get_next_active_insn (rtx, rtx);
968 static bool insn_terminates_group_p (rtx , enum group_termination);
969 static bool insn_must_be_first_in_group (rtx);
970 static bool insn_must_be_last_in_group (rtx);
971 static bool is_costly_group (rtx *, rtx);
972 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
973 static int redefine_groups (FILE *, int, rtx, rtx);
974 static int pad_groups (FILE *, int, rtx, rtx);
975 static void rs6000_sched_finish (FILE *, int);
976 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
977 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
978 static int rs6000_use_sched_lookahead (void);
979 static int rs6000_use_sched_lookahead_guard (rtx);
980 static void * rs6000_alloc_sched_context (void);
981 static void rs6000_init_sched_context (void *, bool);
982 static void rs6000_set_sched_context (void *);
983 static void rs6000_free_sched_context (void *);
984 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
985 static tree rs6000_builtin_mask_for_load (void);
986 static tree rs6000_builtin_mul_widen_even (tree);
987 static tree rs6000_builtin_mul_widen_odd (tree);
988 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
989 static bool rs6000_builtin_support_vector_misalignment (enum
990 machine_mode,
991 const_tree,
992 int, bool);
993 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
994 tree, int);
995 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
997 static void def_builtin (int, const char *, tree, int);
998 static bool rs6000_vector_alignment_reachable (const_tree, bool);
999 static void rs6000_init_builtins (void);
1000 static tree rs6000_builtin_decl (unsigned, bool);
1002 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1003 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1004 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1005 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1006 static void altivec_init_builtins (void);
1007 static unsigned builtin_hash_function (const void *);
1008 static int builtin_hash_eq (const void *, const void *);
1009 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1010 enum machine_mode, enum machine_mode,
1011 enum rs6000_builtins, const char *name);
1012 static void rs6000_common_init_builtins (void);
1013 static void rs6000_init_libfuncs (void);
1015 static void paired_init_builtins (void);
1016 static rtx paired_expand_builtin (tree, rtx, bool *);
1017 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1018 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1019 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1021 static void enable_mask_for_builtins (struct builtin_description *, int,
1022 enum rs6000_builtins,
1023 enum rs6000_builtins);
1024 static void spe_init_builtins (void);
1025 static rtx spe_expand_builtin (tree, rtx, bool *);
1026 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1027 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1028 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1029 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1030 static rs6000_stack_t *rs6000_stack_info (void);
1031 static void debug_stack_info (rs6000_stack_t *);
1033 static rtx altivec_expand_builtin (tree, rtx, bool *);
1034 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1035 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1036 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1037 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1038 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1039 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1040 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1041 static rtx altivec_expand_vec_set_builtin (tree);
1042 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1043 static int get_element_number (tree, tree);
1044 static void rs6000_option_override (void);
1045 static int rs6000_loop_align_max_skip (rtx);
1046 static int first_altivec_reg_to_save (void);
1047 static unsigned int compute_vrsave_mask (void);
1048 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1049 static void is_altivec_return_reg (rtx, void *);
1050 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1051 int easy_vector_constant (rtx, enum machine_mode);
1052 static rtx rs6000_dwarf_register_span (rtx);
1053 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1054 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1055 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1056 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1057 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1058 static rtx rs6000_delegitimize_address (rtx);
1059 static rtx rs6000_tls_get_addr (void);
1060 static rtx rs6000_got_sym (void);
1061 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1062 static const char *rs6000_get_some_local_dynamic_name (void);
1063 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1064 static rtx rs6000_complex_function_value (enum machine_mode);
1065 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1066 enum machine_mode, const_tree);
1067 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1068 HOST_WIDE_INT, int);
1069 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1070 const_tree,
1071 HOST_WIDE_INT);
1072 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1073 HOST_WIDE_INT,
1074 rtx[], int *);
1075 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1076 const_tree, HOST_WIDE_INT,
1077 rtx[], int *);
1078 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1079 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1080 static void rs6000_function_arg_advance (cumulative_args_t, enum machine_mode,
1081 const_tree, bool);
1082 static rtx rs6000_function_arg (cumulative_args_t, enum machine_mode,
1083 const_tree, bool);
1084 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1085 const_tree);
1086 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1087 static void setup_incoming_varargs (cumulative_args_t,
1088 enum machine_mode, tree,
1089 int *, int);
1090 static bool rs6000_pass_by_reference (cumulative_args_t, enum machine_mode,
1091 const_tree, bool);
1092 static int rs6000_arg_partial_bytes (cumulative_args_t, enum machine_mode,
1093 tree, bool);
1094 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1095 #if TARGET_MACHO
1096 static void macho_branch_islands (void);
1097 static int no_previous_def (tree function_name);
1098 static tree get_prev_label (tree function_name);
1099 static void rs6000_darwin_file_start (void);
1100 #endif
1102 static tree rs6000_build_builtin_va_list (void);
1103 static void rs6000_va_start (tree, rtx);
1104 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1105 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1106 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1107 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1108 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1109 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1110 enum machine_mode);
1111 static tree rs6000_stack_protect_fail (void);
1113 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1114 int, int *);
1116 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1117 int, int, int *);
1119 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1120 int, int *)
1121 = rs6000_legitimize_reload_address;
1123 static bool rs6000_mode_dependent_address_p (const_rtx);
1124 static bool rs6000_mode_dependent_address (const_rtx);
1125 static bool rs6000_debug_mode_dependent_address (const_rtx);
1126 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1127 = rs6000_mode_dependent_address;
1129 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1130 enum machine_mode, rtx);
1131 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1132 enum machine_mode,
1133 rtx);
1134 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1135 enum machine_mode, rtx)
1136 = rs6000_secondary_reload_class;
1138 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1139 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1140 enum reg_class);
1141 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1142 = rs6000_preferred_reload_class;
1144 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1145 enum machine_mode);
1147 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1148 enum reg_class,
1149 enum machine_mode);
1151 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1152 enum machine_mode)
1153 = rs6000_secondary_memory_needed;
1155 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1156 enum machine_mode,
1157 enum reg_class);
1158 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1159 enum machine_mode,
1160 enum reg_class);
1162 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1163 enum machine_mode,
1164 enum reg_class)
1165 = rs6000_cannot_change_mode_class;
1167 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1168 enum machine_mode,
1169 struct secondary_reload_info *);
1171 const int INSN_NOT_AVAILABLE = -1;
1172 static enum machine_mode rs6000_eh_return_filter_mode (void);
1173 static bool rs6000_can_eliminate (const int, const int);
1174 static void rs6000_conditional_register_usage (void);
1175 static void rs6000_trampoline_init (rtx, tree, rtx);
1176 static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
1177 static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
1178 static bool rs6000_save_toc_in_prologue_p (void);
1179 static void rs6000_code_end (void) ATTRIBUTE_UNUSED;
1181 /* Hash table stuff for keeping track of TOC entries. */
1183 struct GTY(()) toc_hash_struct
1185 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1186 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1187 rtx key;
1188 enum machine_mode key_mode;
1189 int labelno;
1192 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1194 /* Hash table to keep track of the argument types for builtin functions. */
1196 struct GTY(()) builtin_hash_struct
1198 tree type;
1199 enum machine_mode mode[4]; /* return value + 3 arguments. */
1200 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1203 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1205 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1206 static void rs6000_function_specific_save (struct cl_target_option *);
1207 static void rs6000_function_specific_restore (struct cl_target_option *);
1208 static void rs6000_function_specific_print (FILE *, int,
1209 struct cl_target_option *);
1210 static bool rs6000_can_inline_p (tree, tree);
1211 static void rs6000_set_current_function (tree);
1214 /* Default register names. */
1215 char rs6000_reg_names[][8] =
1217 "0", "1", "2", "3", "4", "5", "6", "7",
1218 "8", "9", "10", "11", "12", "13", "14", "15",
1219 "16", "17", "18", "19", "20", "21", "22", "23",
1220 "24", "25", "26", "27", "28", "29", "30", "31",
1221 "0", "1", "2", "3", "4", "5", "6", "7",
1222 "8", "9", "10", "11", "12", "13", "14", "15",
1223 "16", "17", "18", "19", "20", "21", "22", "23",
1224 "24", "25", "26", "27", "28", "29", "30", "31",
1225 "mq", "lr", "ctr","ap",
1226 "0", "1", "2", "3", "4", "5", "6", "7",
1227 "ca",
1228 /* AltiVec registers. */
1229 "0", "1", "2", "3", "4", "5", "6", "7",
1230 "8", "9", "10", "11", "12", "13", "14", "15",
1231 "16", "17", "18", "19", "20", "21", "22", "23",
1232 "24", "25", "26", "27", "28", "29", "30", "31",
1233 "vrsave", "vscr",
1234 /* SPE registers. */
1235 "spe_acc", "spefscr",
1236 /* Soft frame pointer. */
1237 "sfp"
1240 #ifdef TARGET_REGNAMES
1241 static const char alt_reg_names[][8] =
1243 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1244 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1245 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1246 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1247 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1248 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1249 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1250 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1251 "mq", "lr", "ctr", "ap",
1252 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1253 "ca",
1254 /* AltiVec registers. */
1255 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1256 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1257 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1258 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1259 "vrsave", "vscr",
1260 /* SPE registers. */
1261 "spe_acc", "spefscr",
1262 /* Soft frame pointer. */
1263 "sfp"
1265 #endif
1267 /* Table of valid machine attributes. */
1269 static const struct attribute_spec rs6000_attribute_table[] =
1271 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1272 affects_type_identity } */
1273 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1274 false },
1275 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1276 false },
1277 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1278 false },
1279 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1280 false },
1281 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1282 false },
1283 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1284 SUBTARGET_ATTRIBUTE_TABLE,
1285 #endif
1286 { NULL, 0, 0, false, false, false, NULL, false }
1289 #ifndef MASK_STRICT_ALIGN
1290 #define MASK_STRICT_ALIGN 0
1291 #endif
1292 #ifndef TARGET_PROFILE_KERNEL
1293 #define TARGET_PROFILE_KERNEL 0
1294 #endif
1296 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1297 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1299 /* Initialize the GCC target structure. */
1300 #undef TARGET_ATTRIBUTE_TABLE
1301 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1302 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1303 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1304 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1305 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1307 #undef TARGET_ASM_ALIGNED_DI_OP
1308 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1310 /* Default unaligned ops are only provided for ELF. Find the ops needed
1311 for non-ELF systems. */
1312 #ifndef OBJECT_FORMAT_ELF
1313 #if TARGET_XCOFF
1314 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1315 64-bit targets. */
1316 #undef TARGET_ASM_UNALIGNED_HI_OP
1317 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1318 #undef TARGET_ASM_UNALIGNED_SI_OP
1319 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1320 #undef TARGET_ASM_UNALIGNED_DI_OP
1321 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1322 #else
1323 /* For Darwin. */
1324 #undef TARGET_ASM_UNALIGNED_HI_OP
1325 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1326 #undef TARGET_ASM_UNALIGNED_SI_OP
1327 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1328 #undef TARGET_ASM_UNALIGNED_DI_OP
1329 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1330 #undef TARGET_ASM_ALIGNED_DI_OP
1331 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1332 #endif
1333 #endif
1335 /* This hook deals with fixups for relocatable code and DI-mode objects
1336 in 64-bit code. */
1337 #undef TARGET_ASM_INTEGER
1338 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1340 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
1341 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1342 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1343 #endif
1345 #undef TARGET_HAVE_TLS
1346 #define TARGET_HAVE_TLS HAVE_AS_TLS
1348 #undef TARGET_CANNOT_FORCE_CONST_MEM
1349 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1351 #undef TARGET_DELEGITIMIZE_ADDRESS
1352 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1354 #undef TARGET_ASM_FUNCTION_PROLOGUE
1355 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1356 #undef TARGET_ASM_FUNCTION_EPILOGUE
1357 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1359 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1360 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1362 #undef TARGET_LEGITIMIZE_ADDRESS
1363 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1365 #undef TARGET_SCHED_VARIABLE_ISSUE
1366 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1368 #undef TARGET_SCHED_ISSUE_RATE
1369 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1370 #undef TARGET_SCHED_ADJUST_COST
1371 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1372 #undef TARGET_SCHED_ADJUST_PRIORITY
1373 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1374 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1375 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1376 #undef TARGET_SCHED_INIT
1377 #define TARGET_SCHED_INIT rs6000_sched_init
1378 #undef TARGET_SCHED_FINISH
1379 #define TARGET_SCHED_FINISH rs6000_sched_finish
1380 #undef TARGET_SCHED_REORDER
1381 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1382 #undef TARGET_SCHED_REORDER2
1383 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1385 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1386 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1388 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1389 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1391 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1392 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1393 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1394 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1395 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1396 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1397 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1398 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1400 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1401 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1402 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1403 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1404 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1405 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1406 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1407 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1408 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1409 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1410 rs6000_builtin_support_vector_misalignment
1411 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1412 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1413 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1414 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1415 rs6000_builtin_vectorization_cost
1416 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1417 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1418 rs6000_preferred_simd_mode
1420 #undef TARGET_INIT_BUILTINS
1421 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1422 #undef TARGET_BUILTIN_DECL
1423 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1425 #undef TARGET_EXPAND_BUILTIN
1426 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1428 #undef TARGET_MANGLE_TYPE
1429 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1431 #undef TARGET_INIT_LIBFUNCS
1432 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1434 #if TARGET_MACHO
1435 #undef TARGET_BINDS_LOCAL_P
1436 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1437 #endif
1439 #undef TARGET_MS_BITFIELD_LAYOUT_P
1440 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1442 #undef TARGET_ASM_OUTPUT_MI_THUNK
1443 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1445 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1446 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1448 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1449 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1451 #undef TARGET_INVALID_WITHIN_DOLOOP
1452 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1454 #undef TARGET_REGISTER_MOVE_COST
1455 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1456 #undef TARGET_MEMORY_MOVE_COST
1457 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1458 #undef TARGET_RTX_COSTS
1459 #define TARGET_RTX_COSTS rs6000_rtx_costs
1460 #undef TARGET_ADDRESS_COST
1461 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1463 #undef TARGET_DWARF_REGISTER_SPAN
1464 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1466 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1467 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1469 /* On rs6000, function arguments are promoted, as are function return
1470 values. */
1471 #undef TARGET_PROMOTE_FUNCTION_MODE
1472 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1474 #undef TARGET_RETURN_IN_MEMORY
1475 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1477 #undef TARGET_SETUP_INCOMING_VARARGS
1478 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1480 /* Always strict argument naming on rs6000. */
1481 #undef TARGET_STRICT_ARGUMENT_NAMING
1482 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1483 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1484 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1485 #undef TARGET_SPLIT_COMPLEX_ARG
1486 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1487 #undef TARGET_MUST_PASS_IN_STACK
1488 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1489 #undef TARGET_PASS_BY_REFERENCE
1490 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1491 #undef TARGET_ARG_PARTIAL_BYTES
1492 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1493 #undef TARGET_FUNCTION_ARG_ADVANCE
1494 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1495 #undef TARGET_FUNCTION_ARG
1496 #define TARGET_FUNCTION_ARG rs6000_function_arg
1497 #undef TARGET_FUNCTION_ARG_BOUNDARY
1498 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1500 #undef TARGET_BUILD_BUILTIN_VA_LIST
1501 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1503 #undef TARGET_EXPAND_BUILTIN_VA_START
1504 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1506 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1507 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1509 #undef TARGET_EH_RETURN_FILTER_MODE
1510 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1512 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1513 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1515 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1516 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1518 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1519 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1521 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1522 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1524 #undef TARGET_OPTION_OVERRIDE
1525 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1527 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1528 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1529 rs6000_builtin_vectorized_function
1531 #ifndef TARGET_MACHO
1532 #undef TARGET_STACK_PROTECT_FAIL
1533 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1534 #endif
1536 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1537 The PowerPC architecture requires only weak consistency among
1538 processors--that is, memory accesses between processors need not be
1539 sequentially consistent and memory accesses among processors can occur
1540 in any order. The ability to order memory accesses weakly provides
1541 opportunities for more efficient use of the system bus. Unless a
1542 dependency exists, the 604e allows read operations to precede store
1543 operations. */
1544 #undef TARGET_RELAXED_ORDERING
1545 #define TARGET_RELAXED_ORDERING true
1547 #ifdef HAVE_AS_TLS
1548 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1549 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1550 #endif
1552 /* Use a 32-bit anchor range. This leads to sequences like:
1554 addis tmp,anchor,high
1555 add dest,tmp,low
1557 where tmp itself acts as an anchor, and can be shared between
1558 accesses to the same 64k page. */
1559 #undef TARGET_MIN_ANCHOR_OFFSET
1560 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1561 #undef TARGET_MAX_ANCHOR_OFFSET
1562 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1563 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1564 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1566 #undef TARGET_BUILTIN_RECIPROCAL
1567 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1569 #undef TARGET_EXPAND_TO_RTL_HOOK
1570 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1572 #undef TARGET_INSTANTIATE_DECLS
1573 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1575 #undef TARGET_SECONDARY_RELOAD
1576 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1578 #undef TARGET_LEGITIMATE_ADDRESS_P
1579 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1581 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1582 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1584 #undef TARGET_CAN_ELIMINATE
1585 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1587 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1588 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1590 #undef TARGET_TRAMPOLINE_INIT
1591 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1593 #undef TARGET_FUNCTION_VALUE
1594 #define TARGET_FUNCTION_VALUE rs6000_function_value
1596 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1597 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1599 #undef TARGET_OPTION_SAVE
1600 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1602 #undef TARGET_OPTION_RESTORE
1603 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1605 #undef TARGET_OPTION_PRINT
1606 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1608 #undef TARGET_CAN_INLINE_P
1609 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1611 #undef TARGET_SET_CURRENT_FUNCTION
1612 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1614 #undef TARGET_LEGITIMATE_CONSTANT_P
1615 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1619 /* Simplifications for entries below. */
1621 enum {
1622 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1623 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1626 /* Some OSs don't support saving the high part of 64-bit registers on context
1627 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1628 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1629 either, the user must explicitly specify them and we won't interfere with
1630 the user's specification. */
1632 enum {
1633 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1634 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1635 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1636 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1637 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1638 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1639 | MASK_RECIP_PRECISION)
1642 /* Masks for instructions set at various powerpc ISAs. */
1643 enum {
1644 ISA_2_1_MASKS = MASK_MFCRF,
1645 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1646 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1648 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1649 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1650 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1651 server and embedded. */
1652 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1653 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1654 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1656 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1657 altivec is a win so enable it. */
1658 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1659 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1660 | MASK_VSX)
1663 struct rs6000_ptt
1665 const char *const name; /* Canonical processor name. */
1666 const enum processor_type processor; /* Processor type enum value. */
1667 const int target_enable; /* Target flags to enable. */
1670 static struct rs6000_ptt const processor_target_table[] =
1672 #define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
1673 #include "rs6000-cpus.def"
1674 #undef RS6000_CPU
1677 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1678 name is invalid. */
1680 static int
1681 rs6000_cpu_name_lookup (const char *name)
1683 size_t i;
1685 if (name != NULL)
1687 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1688 if (! strcmp (name, processor_target_table[i].name))
1689 return (int)i;
1692 return -1;
1696 /* Return number of consecutive hard regs needed starting at reg REGNO
1697 to hold something of mode MODE.
1698 This is ordinarily the length in words of a value of mode MODE
1699 but can be less for certain modes in special long registers.
1701 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1702 scalar instructions. The upper 32 bits are only available to the
1703 SIMD instructions.
1705 POWER and PowerPC GPRs hold 32 bits worth;
1706 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1708 static int
1709 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1711 unsigned HOST_WIDE_INT reg_size;
1713 if (FP_REGNO_P (regno))
1714 reg_size = (VECTOR_MEM_VSX_P (mode)
1715 ? UNITS_PER_VSX_WORD
1716 : UNITS_PER_FP_WORD);
1718 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1719 reg_size = UNITS_PER_SPE_WORD;
1721 else if (ALTIVEC_REGNO_P (regno))
1722 reg_size = UNITS_PER_ALTIVEC_WORD;
1724 /* The value returned for SCmode in the E500 double case is 2 for
1725 ABI compatibility; storing an SCmode value in a single register
1726 would require function_arg and rs6000_spe_function_arg to handle
1727 SCmode so as to pass the value correctly in a pair of
1728 registers. */
1729 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1730 && !DECIMAL_FLOAT_MODE_P (mode))
1731 reg_size = UNITS_PER_FP_WORD;
1733 else
1734 reg_size = UNITS_PER_WORD;
1736 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1739 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1740 MODE. */
1741 static int
1742 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1744 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1746 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1747 implementations. Don't allow an item to be split between a FP register
1748 and an Altivec register. */
1749 if (VECTOR_MEM_VSX_P (mode))
1751 if (FP_REGNO_P (regno))
1752 return FP_REGNO_P (last_regno);
1754 if (ALTIVEC_REGNO_P (regno))
1755 return ALTIVEC_REGNO_P (last_regno);
1758 /* The GPRs can hold any mode, but values bigger than one register
1759 cannot go past R31. */
1760 if (INT_REGNO_P (regno))
1761 return INT_REGNO_P (last_regno);
1763 /* The float registers (except for VSX vector modes) can only hold floating
1764 modes and DImode. This excludes the 32-bit decimal float mode for
1765 now. */
1766 if (FP_REGNO_P (regno))
1768 if (SCALAR_FLOAT_MODE_P (mode)
1769 && (mode != TDmode || (regno % 2) == 0)
1770 && FP_REGNO_P (last_regno))
1771 return 1;
1773 if (GET_MODE_CLASS (mode) == MODE_INT
1774 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1775 return 1;
1777 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1778 && PAIRED_VECTOR_MODE (mode))
1779 return 1;
1781 return 0;
1784 /* The CR register can only hold CC modes. */
1785 if (CR_REGNO_P (regno))
1786 return GET_MODE_CLASS (mode) == MODE_CC;
1788 if (CA_REGNO_P (regno))
1789 return mode == BImode;
1791 /* AltiVec only in AldyVec registers. */
1792 if (ALTIVEC_REGNO_P (regno))
1793 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1795 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1796 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1797 return 1;
1799 /* We cannot put TImode anywhere except general register and it must be able
1800 to fit within the register set. In the future, allow TImode in the
1801 Altivec or VSX registers. */
1803 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1806 /* Print interesting facts about registers. */
1807 static void
1808 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1810 int r, m;
1812 for (r = first_regno; r <= last_regno; ++r)
1814 const char *comma = "";
1815 int len;
1817 if (first_regno == last_regno)
1818 fprintf (stderr, "%s:\t", reg_name);
1819 else
1820 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1822 len = 8;
1823 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1824 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1826 if (len > 70)
1828 fprintf (stderr, ",\n\t");
1829 len = 8;
1830 comma = "";
1833 if (rs6000_hard_regno_nregs[m][r] > 1)
1834 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1835 rs6000_hard_regno_nregs[m][r]);
1836 else
1837 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1839 comma = ", ";
1842 if (call_used_regs[r])
1844 if (len > 70)
1846 fprintf (stderr, ",\n\t");
1847 len = 8;
1848 comma = "";
1851 len += fprintf (stderr, "%s%s", comma, "call-used");
1852 comma = ", ";
1855 if (fixed_regs[r])
1857 if (len > 70)
1859 fprintf (stderr, ",\n\t");
1860 len = 8;
1861 comma = "";
1864 len += fprintf (stderr, "%s%s", comma, "fixed");
1865 comma = ", ";
1868 if (len > 70)
1870 fprintf (stderr, ",\n\t");
1871 comma = "";
1874 fprintf (stderr, "%sregno = %d\n", comma, r);
1878 #define DEBUG_FMT_D "%-32s= %d\n"
1879 #define DEBUG_FMT_S "%-32s= %s\n"
1881 /* Print various interesting information with -mdebug=reg. */
1882 static void
1883 rs6000_debug_reg_global (void)
1885 static const char *const tf[2] = { "false", "true" };
1886 const char *nl = (const char *)0;
1887 int m;
1888 char costly_num[20];
1889 char nop_num[20];
1890 const char *costly_str;
1891 const char *nop_str;
1892 const char *trace_str;
1893 const char *abi_str;
1894 const char *cmodel_str;
1896 /* Map enum rs6000_vector to string. */
1897 static const char *rs6000_debug_vector_unit[] = {
1898 "none",
1899 "altivec",
1900 "vsx",
1901 "paired",
1902 "spe",
1903 "other"
1906 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1907 LAST_VIRTUAL_REGISTER);
1908 rs6000_debug_reg_print (0, 31, "gr");
1909 rs6000_debug_reg_print (32, 63, "fp");
1910 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1911 LAST_ALTIVEC_REGNO,
1912 "vs");
1913 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1914 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1915 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1916 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1917 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1918 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1919 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1920 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1921 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1923 fprintf (stderr,
1924 "\n"
1925 "d reg_class = %s\n"
1926 "f reg_class = %s\n"
1927 "v reg_class = %s\n"
1928 "wa reg_class = %s\n"
1929 "wd reg_class = %s\n"
1930 "wf reg_class = %s\n"
1931 "ws reg_class = %s\n\n",
1932 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1933 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1934 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1935 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1936 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1937 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1938 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1940 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1941 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1943 nl = "\n";
1944 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1945 GET_MODE_NAME (m),
1946 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1947 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1950 if (nl)
1951 fputs (nl, stderr);
1953 if (rs6000_recip_control)
1955 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1957 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1958 if (rs6000_recip_bits[m])
1960 fprintf (stderr,
1961 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1962 GET_MODE_NAME (m),
1963 (RS6000_RECIP_AUTO_RE_P (m)
1964 ? "auto"
1965 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1966 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1967 ? "auto"
1968 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1971 fputs ("\n", stderr);
1974 if (rs6000_cpu_index >= 0)
1975 fprintf (stderr, DEBUG_FMT_S, "cpu",
1976 processor_target_table[rs6000_cpu_index].name);
1978 if (rs6000_tune_index >= 0)
1979 fprintf (stderr, DEBUG_FMT_S, "tune",
1980 processor_target_table[rs6000_tune_index].name);
1982 switch (rs6000_sched_costly_dep)
1984 case max_dep_latency:
1985 costly_str = "max_dep_latency";
1986 break;
1988 case no_dep_costly:
1989 costly_str = "no_dep_costly";
1990 break;
1992 case all_deps_costly:
1993 costly_str = "all_deps_costly";
1994 break;
1996 case true_store_to_load_dep_costly:
1997 costly_str = "true_store_to_load_dep_costly";
1998 break;
2000 case store_to_load_dep_costly:
2001 costly_str = "store_to_load_dep_costly";
2002 break;
2004 default:
2005 costly_str = costly_num;
2006 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2007 break;
2010 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2012 switch (rs6000_sched_insert_nops)
2014 case sched_finish_regroup_exact:
2015 nop_str = "sched_finish_regroup_exact";
2016 break;
2018 case sched_finish_pad_groups:
2019 nop_str = "sched_finish_pad_groups";
2020 break;
2022 case sched_finish_none:
2023 nop_str = "sched_finish_none";
2024 break;
2026 default:
2027 nop_str = nop_num;
2028 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2029 break;
2032 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2034 switch (rs6000_sdata)
2036 default:
2037 case SDATA_NONE:
2038 break;
2040 case SDATA_DATA:
2041 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2042 break;
2044 case SDATA_SYSV:
2045 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2046 break;
2048 case SDATA_EABI:
2049 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2050 break;
2054 switch (rs6000_traceback)
2056 case traceback_default: trace_str = "default"; break;
2057 case traceback_none: trace_str = "none"; break;
2058 case traceback_part: trace_str = "part"; break;
2059 case traceback_full: trace_str = "full"; break;
2060 default: trace_str = "unknown"; break;
2063 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2065 switch (rs6000_current_cmodel)
2067 case CMODEL_SMALL: cmodel_str = "small"; break;
2068 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2069 case CMODEL_LARGE: cmodel_str = "large"; break;
2070 default: cmodel_str = "unknown"; break;
2073 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2075 switch (rs6000_current_abi)
2077 case ABI_NONE: abi_str = "none"; break;
2078 case ABI_AIX: abi_str = "aix"; break;
2079 case ABI_V4: abi_str = "V4"; break;
2080 case ABI_DARWIN: abi_str = "darwin"; break;
2081 default: abi_str = "unknown"; break;
2084 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2086 if (rs6000_altivec_abi)
2087 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2089 if (rs6000_spe_abi)
2090 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2092 if (rs6000_darwin64_abi)
2093 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2095 if (rs6000_float_gprs)
2096 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2098 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2099 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2100 tf[!!rs6000_align_branch_targets]);
2101 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2102 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2103 rs6000_long_double_type_size);
2104 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2105 (int)rs6000_sched_restricted_insns_priority);
2108 /* Initialize the various global tables that are based on register size. */
2109 static void
2110 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2112 int r, m, c;
2113 int align64;
2114 int align32;
2116 /* Precalculate REGNO_REG_CLASS. */
2117 rs6000_regno_regclass[0] = GENERAL_REGS;
2118 for (r = 1; r < 32; ++r)
2119 rs6000_regno_regclass[r] = BASE_REGS;
2121 for (r = 32; r < 64; ++r)
2122 rs6000_regno_regclass[r] = FLOAT_REGS;
2124 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2125 rs6000_regno_regclass[r] = NO_REGS;
2127 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2128 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2130 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2131 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2132 rs6000_regno_regclass[r] = CR_REGS;
2134 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2135 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2136 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2137 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2138 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2139 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2140 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2141 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2142 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2143 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2145 /* Precalculate vector information, this must be set up before the
2146 rs6000_hard_regno_nregs_internal below. */
2147 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2149 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2150 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2151 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2154 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2155 rs6000_constraints[c] = NO_REGS;
2157 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2158 believes it can use native alignment or still uses 128-bit alignment. */
2159 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2161 align64 = 64;
2162 align32 = 32;
2164 else
2166 align64 = 128;
2167 align32 = 128;
2170 /* V2DF mode, VSX only. */
2171 if (TARGET_VSX)
2173 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2174 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2175 rs6000_vector_align[V2DFmode] = align64;
2178 /* V4SF mode, either VSX or Altivec. */
2179 if (TARGET_VSX)
2181 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2182 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2183 rs6000_vector_align[V4SFmode] = align32;
2185 else if (TARGET_ALTIVEC)
2187 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2188 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2189 rs6000_vector_align[V4SFmode] = align32;
2192 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2193 and stores. */
2194 if (TARGET_ALTIVEC)
2196 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2197 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2198 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2199 rs6000_vector_align[V4SImode] = align32;
2200 rs6000_vector_align[V8HImode] = align32;
2201 rs6000_vector_align[V16QImode] = align32;
2203 if (TARGET_VSX)
2205 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2206 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2207 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2209 else
2211 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2212 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2213 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2217 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2218 Altivec doesn't have 64-bit support. */
2219 if (TARGET_VSX)
2221 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2222 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2223 rs6000_vector_align[V2DImode] = align64;
2226 /* DFmode, see if we want to use the VSX unit. */
2227 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2229 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2230 rs6000_vector_mem[DFmode]
2231 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2232 rs6000_vector_align[DFmode] = align64;
2235 /* TODO add SPE and paired floating point vector support. */
2237 /* Register class constaints for the constraints that depend on compile
2238 switches. */
2239 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2240 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2242 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2243 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2245 if (TARGET_VSX)
2247 /* At present, we just use VSX_REGS, but we have different constraints
2248 based on the use, in case we want to fine tune the default register
2249 class used. wa = any VSX register, wf = register class to use for
2250 V4SF, wd = register class to use for V2DF, and ws = register classs to
2251 use for DF scalars. */
2252 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2253 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2254 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2255 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2256 ? VSX_REGS
2257 : FLOAT_REGS);
2260 if (TARGET_ALTIVEC)
2261 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2263 /* Set up the reload helper functions. */
2264 if (TARGET_VSX || TARGET_ALTIVEC)
2266 if (TARGET_64BIT)
2268 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2269 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2270 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2271 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2272 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2273 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2274 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2275 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2276 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2277 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2278 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2279 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2281 else
2283 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2284 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2285 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2286 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2287 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2288 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2289 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2290 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2291 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2292 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2293 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2294 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2298 /* Precalculate HARD_REGNO_NREGS. */
2299 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2300 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2301 rs6000_hard_regno_nregs[m][r]
2302 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2304 /* Precalculate HARD_REGNO_MODE_OK. */
2305 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2306 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2307 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2308 rs6000_hard_regno_mode_ok_p[m][r] = true;
2310 /* Precalculate CLASS_MAX_NREGS sizes. */
2311 for (c = 0; c < LIM_REG_CLASSES; ++c)
2313 int reg_size;
2315 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2316 reg_size = UNITS_PER_VSX_WORD;
2318 else if (c == ALTIVEC_REGS)
2319 reg_size = UNITS_PER_ALTIVEC_WORD;
2321 else if (c == FLOAT_REGS)
2322 reg_size = UNITS_PER_FP_WORD;
2324 else
2325 reg_size = UNITS_PER_WORD;
2327 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2328 rs6000_class_max_nregs[m][c]
2329 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2332 if (TARGET_E500_DOUBLE)
2333 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2335 /* Calculate which modes to automatically generate code to use a the
2336 reciprocal divide and square root instructions. In the future, possibly
2337 automatically generate the instructions even if the user did not specify
2338 -mrecip. The older machines double precision reciprocal sqrt estimate is
2339 not accurate enough. */
2340 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2341 if (TARGET_FRES)
2342 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2343 if (TARGET_FRE)
2344 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2345 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2346 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2347 if (VECTOR_UNIT_VSX_P (V2DFmode))
2348 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2350 if (TARGET_FRSQRTES)
2351 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2352 if (TARGET_FRSQRTE)
2353 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2354 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2355 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2356 if (VECTOR_UNIT_VSX_P (V2DFmode))
2357 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2359 if (rs6000_recip_control)
2361 if (!flag_finite_math_only)
2362 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2363 if (flag_trapping_math)
2364 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2365 if (!flag_reciprocal_math)
2366 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2367 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2369 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2370 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2371 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2373 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2374 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2375 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2377 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2378 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2379 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2381 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2382 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2383 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2385 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2386 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2387 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2389 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2390 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2391 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2393 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2394 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2395 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2397 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2398 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2399 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2403 if (global_init_p || TARGET_DEBUG_TARGET)
2405 if (TARGET_DEBUG_REG)
2406 rs6000_debug_reg_global ();
2408 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2409 fprintf (stderr,
2410 "SImode variable mult cost = %d\n"
2411 "SImode constant mult cost = %d\n"
2412 "SImode short constant mult cost = %d\n"
2413 "DImode multipliciation cost = %d\n"
2414 "SImode division cost = %d\n"
2415 "DImode division cost = %d\n"
2416 "Simple fp operation cost = %d\n"
2417 "DFmode multiplication cost = %d\n"
2418 "SFmode division cost = %d\n"
2419 "DFmode division cost = %d\n"
2420 "cache line size = %d\n"
2421 "l1 cache size = %d\n"
2422 "l2 cache size = %d\n"
2423 "simultaneous prefetches = %d\n"
2424 "\n",
2425 rs6000_cost->mulsi,
2426 rs6000_cost->mulsi_const,
2427 rs6000_cost->mulsi_const9,
2428 rs6000_cost->muldi,
2429 rs6000_cost->divsi,
2430 rs6000_cost->divdi,
2431 rs6000_cost->fp,
2432 rs6000_cost->dmul,
2433 rs6000_cost->sdiv,
2434 rs6000_cost->ddiv,
2435 rs6000_cost->cache_line_size,
2436 rs6000_cost->l1_cache_size,
2437 rs6000_cost->l2_cache_size,
2438 rs6000_cost->simultaneous_prefetches);
2442 #if TARGET_MACHO
2443 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2445 static void
2446 darwin_rs6000_override_options (void)
2448 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2449 off. */
2450 rs6000_altivec_abi = 1;
2451 TARGET_ALTIVEC_VRSAVE = 1;
2453 if (DEFAULT_ABI == ABI_DARWIN
2454 && TARGET_64BIT)
2455 darwin_one_byte_bool = 1;
2457 if (TARGET_64BIT && ! TARGET_POWERPC64)
2459 target_flags |= MASK_POWERPC64;
2460 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2462 if (flag_mkernel)
2464 rs6000_default_long_calls = 1;
2465 target_flags |= MASK_SOFT_FLOAT;
2468 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2469 Altivec. */
2470 if (!flag_mkernel && !flag_apple_kext
2471 && TARGET_64BIT
2472 && ! (target_flags_explicit & MASK_ALTIVEC))
2473 target_flags |= MASK_ALTIVEC;
2475 /* Unless the user (not the configurer) has explicitly overridden
2476 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2477 G4 unless targetting the kernel. */
2478 if (!flag_mkernel
2479 && !flag_apple_kext
2480 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2481 && ! (target_flags_explicit & MASK_ALTIVEC)
2482 && ! global_options_set.x_rs6000_cpu_index)
2484 target_flags |= MASK_ALTIVEC;
2487 #endif
2489 /* If not otherwise specified by a target, make 'long double' equivalent to
2490 'double'. */
2492 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2493 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2494 #endif
2496 /* Override command line options. Mostly we process the processor type and
2497 sometimes adjust other TARGET_ options. */
2499 static bool
2500 rs6000_option_override_internal (bool global_init_p)
2502 bool ret = true;
2503 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2504 int set_masks;
2505 int cpu_index;
2506 int tune_index;
2507 struct cl_target_option *main_target_opt
2508 = ((global_init_p || target_option_default_node == NULL)
2509 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2511 /* On 64-bit Darwin, power alignment is ABI-incompatible with some C
2512 library functions, so warn about it. The flag may be useful for
2513 performance studies from time to time though, so don't disable it
2514 entirely. */
2515 if (global_options_set.x_rs6000_alignment_flags
2516 && rs6000_alignment_flags == MASK_ALIGN_POWER
2517 && DEFAULT_ABI == ABI_DARWIN
2518 && TARGET_64BIT)
2519 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2520 " it is incompatible with the installed C and C++ libraries");
2522 if (global_options_set.x_rs6000_spe_abi
2523 && rs6000_spe_abi
2524 && !TARGET_SPE_ABI)
2525 error ("not configured for SPE ABI");
2527 /* Numerous experiment shows that IRA based loop pressure
2528 calculation works better for RTL loop invariant motion on targets
2529 with enough (>= 32) registers. It is an expensive optimization.
2530 So it is on only for peak performance. */
2531 if (optimize >= 3 && global_init_p)
2532 flag_ira_loop_pressure = 1;
2534 /* Set the pointer size. */
2535 if (TARGET_64BIT)
2537 rs6000_pmode = (int)DImode;
2538 rs6000_pointer_size = 64;
2540 else
2542 rs6000_pmode = (int)SImode;
2543 rs6000_pointer_size = 32;
2546 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2547 #ifdef OS_MISSING_POWERPC64
2548 if (OS_MISSING_POWERPC64)
2549 set_masks &= ~MASK_POWERPC64;
2550 #endif
2551 #ifdef OS_MISSING_ALTIVEC
2552 if (OS_MISSING_ALTIVEC)
2553 set_masks &= ~MASK_ALTIVEC;
2554 #endif
2556 /* Don't override by the processor default if given explicitly. */
2557 set_masks &= ~target_flags_explicit;
2559 /* Identify the processor type. */
2560 if (!default_cpu)
2562 if (TARGET_POWERPC64)
2563 default_cpu = "powerpc64";
2564 else if (TARGET_POWERPC)
2565 default_cpu = "powerpc";
2568 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2569 the cpu in a target attribute or pragma, but did not specify a tuning
2570 option, use the cpu for the tuning option rather than the option specified
2571 with -mtune on the command line. */
2572 if (rs6000_cpu_index > 0)
2573 cpu_index = rs6000_cpu_index;
2574 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2575 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2576 else
2577 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2579 if (rs6000_tune_index > 0)
2580 tune_index = rs6000_tune_index;
2581 else
2582 rs6000_tune_index = tune_index = cpu_index;
2584 if (cpu_index >= 0)
2586 target_flags &= ~set_masks;
2587 target_flags |= (processor_target_table[cpu_index].target_enable
2588 & set_masks);
2591 rs6000_cpu = ((tune_index >= 0)
2592 ? processor_target_table[tune_index].processor
2593 : (TARGET_POWERPC64
2594 ? PROCESSOR_DEFAULT64
2595 : PROCESSOR_DEFAULT));
2597 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2598 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2600 if (TARGET_ALTIVEC)
2601 error ("AltiVec not supported in this target");
2602 if (TARGET_SPE)
2603 error ("SPE not supported in this target");
2606 /* Disable Cell microcode if we are optimizing for the Cell
2607 and not optimizing for size. */
2608 if (rs6000_gen_cell_microcode == -1)
2609 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2610 && !optimize_size);
2612 /* If we are optimizing big endian systems for space and it's OK to
2613 use instructions that would be microcoded on the Cell, use the
2614 load/store multiple and string instructions. */
2615 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2616 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2618 /* Don't allow -mmultiple or -mstring on little endian systems
2619 unless the cpu is a 750, because the hardware doesn't support the
2620 instructions used in little endian mode, and causes an alignment
2621 trap. The 750 does not cause an alignment trap (except when the
2622 target is unaligned). */
2624 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2626 if (TARGET_MULTIPLE)
2628 target_flags &= ~MASK_MULTIPLE;
2629 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2630 warning (0, "-mmultiple is not supported on little endian systems");
2633 if (TARGET_STRING)
2635 target_flags &= ~MASK_STRING;
2636 if ((target_flags_explicit & MASK_STRING) != 0)
2637 warning (0, "-mstring is not supported on little endian systems");
2641 /* Add some warnings for VSX. */
2642 if (TARGET_VSX)
2644 const char *msg = NULL;
2645 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2646 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2648 if (target_flags_explicit & MASK_VSX)
2649 msg = N_("-mvsx requires hardware floating point");
2650 else
2651 target_flags &= ~ MASK_VSX;
2653 else if (TARGET_PAIRED_FLOAT)
2654 msg = N_("-mvsx and -mpaired are incompatible");
2655 /* The hardware will allow VSX and little endian, but until we make sure
2656 things like vector select, etc. work don't allow VSX on little endian
2657 systems at this point. */
2658 else if (!BYTES_BIG_ENDIAN)
2659 msg = N_("-mvsx used with little endian code");
2660 else if (TARGET_AVOID_XFORM > 0)
2661 msg = N_("-mvsx needs indexed addressing");
2662 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2664 if (target_flags_explicit & MASK_VSX)
2665 msg = N_("-mvsx and -mno-altivec are incompatible");
2666 else
2667 msg = N_("-mno-altivec disables vsx");
2670 if (msg)
2672 warning (0, msg);
2673 target_flags &= ~ MASK_VSX;
2674 target_flags_explicit |= MASK_VSX;
2678 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2679 unless the user explicitly used the -mno-<option> to disable the code. */
2680 if (TARGET_VSX)
2681 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2682 else if (TARGET_POPCNTD)
2683 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2684 else if (TARGET_DFP)
2685 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2686 else if (TARGET_CMPB)
2687 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2688 else if (TARGET_FPRND)
2689 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2690 else if (TARGET_POPCNTB)
2691 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2692 else if (TARGET_ALTIVEC)
2693 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2695 /* E500mc does "better" if we inline more aggressively. Respect the
2696 user's opinion, though. */
2697 if (rs6000_block_move_inline_limit == 0
2698 && (rs6000_cpu == PROCESSOR_PPCE500MC
2699 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2700 rs6000_block_move_inline_limit = 128;
2702 /* store_one_arg depends on expand_block_move to handle at least the
2703 size of reg_parm_stack_space. */
2704 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2705 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2707 if (global_init_p)
2709 /* If the appropriate debug option is enabled, replace the target hooks
2710 with debug versions that call the real version and then prints
2711 debugging information. */
2712 if (TARGET_DEBUG_COST)
2714 targetm.rtx_costs = rs6000_debug_rtx_costs;
2715 targetm.address_cost = rs6000_debug_address_cost;
2716 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2719 if (TARGET_DEBUG_ADDR)
2721 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2722 targetm.legitimize_address = rs6000_debug_legitimize_address;
2723 rs6000_secondary_reload_class_ptr
2724 = rs6000_debug_secondary_reload_class;
2725 rs6000_secondary_memory_needed_ptr
2726 = rs6000_debug_secondary_memory_needed;
2727 rs6000_cannot_change_mode_class_ptr
2728 = rs6000_debug_cannot_change_mode_class;
2729 rs6000_preferred_reload_class_ptr
2730 = rs6000_debug_preferred_reload_class;
2731 rs6000_legitimize_reload_address_ptr
2732 = rs6000_debug_legitimize_reload_address;
2733 rs6000_mode_dependent_address_ptr
2734 = rs6000_debug_mode_dependent_address;
2737 if (rs6000_veclibabi_name)
2739 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2740 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2741 else
2743 error ("unknown vectorization library ABI type (%s) for "
2744 "-mveclibabi= switch", rs6000_veclibabi_name);
2745 ret = false;
2750 if (!global_options_set.x_rs6000_long_double_type_size)
2752 if (main_target_opt != NULL
2753 && (main_target_opt->x_rs6000_long_double_type_size
2754 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2755 error ("target attribute or pragma changes long double size");
2756 else
2757 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2760 #ifndef POWERPC_LINUX
2761 if (!global_options_set.x_rs6000_ieeequad)
2762 rs6000_ieeequad = 1;
2763 #endif
2765 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2766 target attribute or pragma which automatically enables both options,
2767 unless the altivec ABI was set. This is set by default for 64-bit, but
2768 not for 32-bit. */
2769 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2770 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2772 /* Enable Altivec ABI for AIX -maltivec. */
2773 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2775 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2776 error ("target attribute or pragma changes AltiVec ABI");
2777 else
2778 rs6000_altivec_abi = 1;
2781 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2782 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2783 be explicitly overridden in either case. */
2784 if (TARGET_ELF)
2786 if (!global_options_set.x_rs6000_altivec_abi
2787 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2789 if (main_target_opt != NULL &&
2790 !main_target_opt->x_rs6000_altivec_abi)
2791 error ("target attribute or pragma changes AltiVec ABI");
2792 else
2793 rs6000_altivec_abi = 1;
2796 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2797 if (!global_options_set.x_TARGET_ALTIVEC_VRSAVE)
2798 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2801 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2802 So far, the only darwin64 targets are also MACH-O. */
2803 if (TARGET_MACHO
2804 && DEFAULT_ABI == ABI_DARWIN
2805 && TARGET_64BIT)
2807 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2808 error ("target attribute or pragma changes darwin64 ABI");
2809 else
2811 rs6000_darwin64_abi = 1;
2812 /* Default to natural alignment, for better performance. */
2813 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2817 /* Place FP constants in the constant pool instead of TOC
2818 if section anchors enabled. */
2819 if (flag_section_anchors)
2820 TARGET_NO_FP_IN_TOC = 1;
2822 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2823 SUBTARGET_OVERRIDE_OPTIONS;
2824 #endif
2825 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2826 SUBSUBTARGET_OVERRIDE_OPTIONS;
2827 #endif
2828 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2829 SUB3TARGET_OVERRIDE_OPTIONS;
2830 #endif
2832 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2833 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2835 /* The e500 and e500mc do not have string instructions, and we set
2836 MASK_STRING above when optimizing for size. */
2837 if ((target_flags & MASK_STRING) != 0)
2838 target_flags = target_flags & ~MASK_STRING;
2840 else if (global_options_set.x_rs6000_cpu_index)
2842 /* For the powerpc-eabispe configuration, we set all these by
2843 default, so let's unset them if we manually set another
2844 CPU that is not the E500. */
2845 if (main_target_opt != NULL
2846 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2847 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2848 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2849 error ("target attribute or pragma changes SPE ABI");
2850 else
2852 if (!global_options_set.x_rs6000_spe_abi)
2853 rs6000_spe_abi = 0;
2854 if (!global_options_set.x_rs6000_spe)
2855 rs6000_spe = 0;
2856 if (!global_options_set.x_rs6000_float_gprs)
2857 rs6000_float_gprs = 0;
2859 if (!(target_flags_explicit & MASK_ISEL))
2860 target_flags &= ~MASK_ISEL;
2863 /* Detect invalid option combinations with E500. */
2864 CHECK_E500_OPTIONS;
2866 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2867 && rs6000_cpu != PROCESSOR_POWER5
2868 && rs6000_cpu != PROCESSOR_POWER6
2869 && rs6000_cpu != PROCESSOR_POWER7
2870 && rs6000_cpu != PROCESSOR_PPCA2
2871 && rs6000_cpu != PROCESSOR_CELL);
2872 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2873 || rs6000_cpu == PROCESSOR_POWER5
2874 || rs6000_cpu == PROCESSOR_POWER7);
2875 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2876 || rs6000_cpu == PROCESSOR_POWER5
2877 || rs6000_cpu == PROCESSOR_POWER6
2878 || rs6000_cpu == PROCESSOR_POWER7
2879 || rs6000_cpu == PROCESSOR_PPCE500MC
2880 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2882 /* Allow debug switches to override the above settings. These are set to -1
2883 in rs6000.opt to indicate the user hasn't directly set the switch. */
2884 if (TARGET_ALWAYS_HINT >= 0)
2885 rs6000_always_hint = TARGET_ALWAYS_HINT;
2887 if (TARGET_SCHED_GROUPS >= 0)
2888 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2890 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
2891 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2893 rs6000_sched_restricted_insns_priority
2894 = (rs6000_sched_groups ? 1 : 0);
2896 /* Handle -msched-costly-dep option. */
2897 rs6000_sched_costly_dep
2898 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2900 if (rs6000_sched_costly_dep_str)
2902 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2903 rs6000_sched_costly_dep = no_dep_costly;
2904 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2905 rs6000_sched_costly_dep = all_deps_costly;
2906 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2907 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2908 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2909 rs6000_sched_costly_dep = store_to_load_dep_costly;
2910 else
2911 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2912 atoi (rs6000_sched_costly_dep_str));
2915 /* Handle -minsert-sched-nops option. */
2916 rs6000_sched_insert_nops
2917 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2919 if (rs6000_sched_insert_nops_str)
2921 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2922 rs6000_sched_insert_nops = sched_finish_none;
2923 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2924 rs6000_sched_insert_nops = sched_finish_pad_groups;
2925 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2926 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2927 else
2928 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2929 atoi (rs6000_sched_insert_nops_str));
2932 if (global_init_p)
2934 #ifdef TARGET_REGNAMES
2935 /* If the user desires alternate register names, copy in the
2936 alternate names now. */
2937 if (TARGET_REGNAMES)
2938 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2939 #endif
2941 /* Set aix_struct_return last, after the ABI is determined.
2942 If -maix-struct-return or -msvr4-struct-return was explicitly
2943 used, don't override with the ABI default. */
2944 if (!global_options_set.x_aix_struct_return)
2945 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2947 #if 0
2948 /* IBM XL compiler defaults to unsigned bitfields. */
2949 if (TARGET_XL_COMPAT)
2950 flag_signed_bitfields = 0;
2951 #endif
2953 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2954 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2956 if (TARGET_TOC)
2957 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2959 /* We can only guarantee the availability of DI pseudo-ops when
2960 assembling for 64-bit targets. */
2961 if (!TARGET_64BIT)
2963 targetm.asm_out.aligned_op.di = NULL;
2964 targetm.asm_out.unaligned_op.di = NULL;
2968 /* Set branch target alignment, if not optimizing for size. */
2969 if (!optimize_size)
2971 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2972 aligned 8byte to avoid misprediction by the branch predictor. */
2973 if (rs6000_cpu == PROCESSOR_TITAN
2974 || rs6000_cpu == PROCESSOR_CELL)
2976 if (align_functions <= 0)
2977 align_functions = 8;
2978 if (align_jumps <= 0)
2979 align_jumps = 8;
2980 if (align_loops <= 0)
2981 align_loops = 8;
2983 if (rs6000_align_branch_targets)
2985 if (align_functions <= 0)
2986 align_functions = 16;
2987 if (align_jumps <= 0)
2988 align_jumps = 16;
2989 if (align_loops <= 0)
2991 can_override_loop_align = 1;
2992 align_loops = 16;
2995 if (align_jumps_max_skip <= 0)
2996 align_jumps_max_skip = 15;
2997 if (align_loops_max_skip <= 0)
2998 align_loops_max_skip = 15;
3001 /* Arrange to save and restore machine status around nested functions. */
3002 init_machine_status = rs6000_init_machine_status;
3004 /* We should always be splitting complex arguments, but we can't break
3005 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3006 if (DEFAULT_ABI != ABI_AIX)
3007 targetm.calls.split_complex_arg = NULL;
3010 /* Initialize rs6000_cost with the appropriate target costs. */
3011 if (optimize_size)
3012 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3013 else
3014 switch (rs6000_cpu)
3016 case PROCESSOR_RIOS1:
3017 rs6000_cost = &rios1_cost;
3018 break;
3020 case PROCESSOR_RIOS2:
3021 rs6000_cost = &rios2_cost;
3022 break;
3024 case PROCESSOR_RS64A:
3025 rs6000_cost = &rs64a_cost;
3026 break;
3028 case PROCESSOR_MPCCORE:
3029 rs6000_cost = &mpccore_cost;
3030 break;
3032 case PROCESSOR_PPC403:
3033 rs6000_cost = &ppc403_cost;
3034 break;
3036 case PROCESSOR_PPC405:
3037 rs6000_cost = &ppc405_cost;
3038 break;
3040 case PROCESSOR_PPC440:
3041 rs6000_cost = &ppc440_cost;
3042 break;
3044 case PROCESSOR_PPC476:
3045 rs6000_cost = &ppc476_cost;
3046 break;
3048 case PROCESSOR_PPC601:
3049 rs6000_cost = &ppc601_cost;
3050 break;
3052 case PROCESSOR_PPC603:
3053 rs6000_cost = &ppc603_cost;
3054 break;
3056 case PROCESSOR_PPC604:
3057 rs6000_cost = &ppc604_cost;
3058 break;
3060 case PROCESSOR_PPC604e:
3061 rs6000_cost = &ppc604e_cost;
3062 break;
3064 case PROCESSOR_PPC620:
3065 rs6000_cost = &ppc620_cost;
3066 break;
3068 case PROCESSOR_PPC630:
3069 rs6000_cost = &ppc630_cost;
3070 break;
3072 case PROCESSOR_CELL:
3073 rs6000_cost = &ppccell_cost;
3074 break;
3076 case PROCESSOR_PPC750:
3077 case PROCESSOR_PPC7400:
3078 rs6000_cost = &ppc750_cost;
3079 break;
3081 case PROCESSOR_PPC7450:
3082 rs6000_cost = &ppc7450_cost;
3083 break;
3085 case PROCESSOR_PPC8540:
3086 rs6000_cost = &ppc8540_cost;
3087 break;
3089 case PROCESSOR_PPCE300C2:
3090 case PROCESSOR_PPCE300C3:
3091 rs6000_cost = &ppce300c2c3_cost;
3092 break;
3094 case PROCESSOR_PPCE500MC:
3095 rs6000_cost = &ppce500mc_cost;
3096 break;
3098 case PROCESSOR_PPCE500MC64:
3099 rs6000_cost = &ppce500mc64_cost;
3100 break;
3102 case PROCESSOR_TITAN:
3103 rs6000_cost = &titan_cost;
3104 break;
3106 case PROCESSOR_POWER4:
3107 case PROCESSOR_POWER5:
3108 rs6000_cost = &power4_cost;
3109 break;
3111 case PROCESSOR_POWER6:
3112 rs6000_cost = &power6_cost;
3113 break;
3115 case PROCESSOR_POWER7:
3116 rs6000_cost = &power7_cost;
3117 break;
3119 case PROCESSOR_PPCA2:
3120 rs6000_cost = &ppca2_cost;
3121 break;
3123 default:
3124 gcc_unreachable ();
3127 if (global_init_p)
3129 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3130 rs6000_cost->simultaneous_prefetches,
3131 global_options.x_param_values,
3132 global_options_set.x_param_values);
3133 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3134 global_options.x_param_values,
3135 global_options_set.x_param_values);
3136 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3137 rs6000_cost->cache_line_size,
3138 global_options.x_param_values,
3139 global_options_set.x_param_values);
3140 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3141 global_options.x_param_values,
3142 global_options_set.x_param_values);
3144 /* If using typedef char *va_list, signal that
3145 __builtin_va_start (&ap, 0) can be optimized to
3146 ap = __builtin_next_arg (0). */
3147 if (DEFAULT_ABI != ABI_V4)
3148 targetm.expand_builtin_va_start = NULL;
3151 /* Set up single/double float flags.
3152 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3153 then set both flags. */
3154 if (TARGET_HARD_FLOAT && TARGET_FPRS
3155 && rs6000_single_float == 0 && rs6000_double_float == 0)
3156 rs6000_single_float = rs6000_double_float = 1;
3158 /* Reset single and double FP flags if target is E500. */
3159 if (TARGET_E500)
3161 rs6000_single_float = rs6000_double_float = 0;
3162 if (TARGET_E500_SINGLE)
3163 rs6000_single_float = 1;
3164 if (TARGET_E500_DOUBLE)
3165 rs6000_single_float = rs6000_double_float = 1;
3168 if (main_target_opt)
3170 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3171 error ("target attribute or pragma changes single precision floating "
3172 "point");
3173 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3174 error ("target attribute or pragma changes double precision floating "
3175 "point");
3178 /* If not explicitly specified via option, decide whether to generate indexed
3179 load/store instructions. */
3180 if (TARGET_AVOID_XFORM == -1)
3181 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3182 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3183 need indexed accesses and the type used is the scalar type of the element
3184 being loaded or stored. */
3185 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3186 && !TARGET_ALTIVEC);
3188 /* Set the -mrecip options. */
3189 if (rs6000_recip_name)
3191 char *p = ASTRDUP (rs6000_recip_name);
3192 char *q;
3193 unsigned int mask, i;
3194 bool invert;
3196 while ((q = strtok (p, ",")) != NULL)
3198 p = NULL;
3199 if (*q == '!')
3201 invert = true;
3202 q++;
3204 else
3205 invert = false;
3207 if (!strcmp (q, "default"))
3208 mask = ((TARGET_RECIP_PRECISION)
3209 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3210 else
3212 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3213 if (!strcmp (q, recip_options[i].string))
3215 mask = recip_options[i].mask;
3216 break;
3219 if (i == ARRAY_SIZE (recip_options))
3221 error ("unknown option for -mrecip=%s", q);
3222 invert = false;
3223 mask = 0;
3224 ret = false;
3228 if (invert)
3229 rs6000_recip_control &= ~mask;
3230 else
3231 rs6000_recip_control |= mask;
3235 rs6000_init_hard_regno_mode_ok (global_init_p);
3237 /* Save the initial options in case the user does function specific options */
3238 if (global_init_p)
3239 target_option_default_node = target_option_current_node
3240 = build_target_option_node ();
3242 /* If not explicitly specified via option, decide whether to generate the
3243 extra blr's required to preserve the link stack on some cpus (eg, 476). */
3244 if (TARGET_LINK_STACK == -1)
3245 SET_TARGET_LINK_STACK (rs6000_cpu == PROCESSOR_PPC476 && flag_pic);
3247 return ret;
3250 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3251 define the target cpu type. */
3253 static void
3254 rs6000_option_override (void)
3256 (void) rs6000_option_override_internal (true);
3260 /* Implement targetm.vectorize.builtin_mask_for_load. */
3261 static tree
3262 rs6000_builtin_mask_for_load (void)
3264 if (TARGET_ALTIVEC || TARGET_VSX)
3265 return altivec_builtin_mask_for_load;
3266 else
3267 return 0;
3270 /* Implement LOOP_ALIGN. */
3272 rs6000_loop_align (rtx label)
3274 basic_block bb;
3275 int ninsns;
3277 /* Don't override loop alignment if -falign-loops was specified. */
3278 if (!can_override_loop_align)
3279 return align_loops_log;
3281 bb = BLOCK_FOR_INSN (label);
3282 ninsns = num_loop_insns(bb->loop_father);
3284 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3285 if (ninsns > 4 && ninsns <= 8
3286 && (rs6000_cpu == PROCESSOR_POWER4
3287 || rs6000_cpu == PROCESSOR_POWER5
3288 || rs6000_cpu == PROCESSOR_POWER6
3289 || rs6000_cpu == PROCESSOR_POWER7))
3290 return 5;
3291 else
3292 return align_loops_log;
3295 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3296 static int
3297 rs6000_loop_align_max_skip (rtx label)
3299 return (1 << rs6000_loop_align (label)) - 1;
3302 /* Implement targetm.vectorize.builtin_conversion.
3303 Returns a decl of a function that implements conversion of an integer vector
3304 into a floating-point vector, or vice-versa. DEST_TYPE is the
3305 destination type and SRC_TYPE the source type of the conversion.
3306 Return NULL_TREE if it is not available. */
3307 static tree
3308 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3310 enum tree_code code = (enum tree_code) tcode;
3312 switch (code)
3314 case FIX_TRUNC_EXPR:
3315 switch (TYPE_MODE (dest_type))
3317 case V2DImode:
3318 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3319 return NULL_TREE;
3321 return TYPE_UNSIGNED (dest_type)
3322 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3323 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3325 case V4SImode:
3326 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3327 return NULL_TREE;
3329 return TYPE_UNSIGNED (dest_type)
3330 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3331 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3333 default:
3334 return NULL_TREE;
3337 case FLOAT_EXPR:
3338 switch (TYPE_MODE (src_type))
3340 case V2DImode:
3341 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3342 return NULL_TREE;
3344 return TYPE_UNSIGNED (src_type)
3345 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3346 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3348 case V4SImode:
3349 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3350 return NULL_TREE;
3352 return TYPE_UNSIGNED (src_type)
3353 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3354 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3356 default:
3357 return NULL_TREE;
3360 default:
3361 return NULL_TREE;
3365 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3366 static tree
3367 rs6000_builtin_mul_widen_even (tree type)
3369 if (!TARGET_ALTIVEC)
3370 return NULL_TREE;
3372 switch (TYPE_MODE (type))
3374 case V8HImode:
3375 return TYPE_UNSIGNED (type)
3376 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3377 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3379 case V16QImode:
3380 return TYPE_UNSIGNED (type)
3381 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3382 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3383 default:
3384 return NULL_TREE;
3388 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3389 static tree
3390 rs6000_builtin_mul_widen_odd (tree type)
3392 if (!TARGET_ALTIVEC)
3393 return NULL_TREE;
3395 switch (TYPE_MODE (type))
3397 case V8HImode:
3398 return TYPE_UNSIGNED (type)
3399 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3400 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3402 case V16QImode:
3403 return TYPE_UNSIGNED (type)
3404 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3405 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3406 default:
3407 return NULL_TREE;
3412 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3413 after applying N number of iterations. This routine does not determine
3414 how may iterations are required to reach desired alignment. */
3416 static bool
3417 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3419 if (is_packed)
3420 return false;
3422 if (TARGET_32BIT)
3424 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3425 return true;
3427 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3428 return true;
3430 return false;
3432 else
3434 if (TARGET_MACHO)
3435 return false;
3437 /* Assuming that all other types are naturally aligned. CHECKME! */
3438 return true;
3442 /* Return true if the vector misalignment factor is supported by the
3443 target. */
3444 bool
3445 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3446 const_tree type,
3447 int misalignment,
3448 bool is_packed)
3450 if (TARGET_VSX)
3452 /* Return if movmisalign pattern is not supported for this mode. */
3453 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3454 return false;
3456 if (misalignment == -1)
3458 /* Misalignment factor is unknown at compile time but we know
3459 it's word aligned. */
3460 if (rs6000_vector_alignment_reachable (type, is_packed))
3462 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3464 if (element_size == 64 || element_size == 32)
3465 return true;
3468 return false;
3471 /* VSX supports word-aligned vector. */
3472 if (misalignment % 4 == 0)
3473 return true;
3475 return false;
3478 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3479 static int
3480 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3481 tree vectype, int misalign)
3483 unsigned elements;
3485 switch (type_of_cost)
3487 case scalar_stmt:
3488 case scalar_load:
3489 case scalar_store:
3490 case vector_stmt:
3491 case vector_load:
3492 case vector_store:
3493 case vec_to_scalar:
3494 case scalar_to_vec:
3495 case cond_branch_not_taken:
3496 case vec_perm:
3497 return 1;
3499 case cond_branch_taken:
3500 return 3;
3502 case unaligned_load:
3503 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3505 elements = TYPE_VECTOR_SUBPARTS (vectype);
3506 if (elements == 2)
3507 /* Double word aligned. */
3508 return 2;
3510 if (elements == 4)
3512 switch (misalign)
3514 case 8:
3515 /* Double word aligned. */
3516 return 2;
3518 case -1:
3519 /* Unknown misalignment. */
3520 case 4:
3521 case 12:
3522 /* Word aligned. */
3523 return 22;
3525 default:
3526 gcc_unreachable ();
3531 if (TARGET_ALTIVEC)
3532 /* Misaligned loads are not supported. */
3533 gcc_unreachable ();
3535 return 2;
3537 case unaligned_store:
3538 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3540 elements = TYPE_VECTOR_SUBPARTS (vectype);
3541 if (elements == 2)
3542 /* Double word aligned. */
3543 return 2;
3545 if (elements == 4)
3547 switch (misalign)
3549 case 8:
3550 /* Double word aligned. */
3551 return 2;
3553 case -1:
3554 /* Unknown misalignment. */
3555 case 4:
3556 case 12:
3557 /* Word aligned. */
3558 return 23;
3560 default:
3561 gcc_unreachable ();
3566 if (TARGET_ALTIVEC)
3567 /* Misaligned stores are not supported. */
3568 gcc_unreachable ();
3570 return 2;
3572 default:
3573 gcc_unreachable ();
3577 /* Implement targetm.vectorize.preferred_simd_mode. */
3579 static enum machine_mode
3580 rs6000_preferred_simd_mode (enum machine_mode mode)
3582 if (TARGET_VSX)
3583 switch (mode)
3585 case DFmode:
3586 return V2DFmode;
3587 default:;
3589 if (TARGET_ALTIVEC || TARGET_VSX)
3590 switch (mode)
3592 case SFmode:
3593 return V4SFmode;
3594 case DImode:
3595 return V2DImode;
3596 case SImode:
3597 return V4SImode;
3598 case HImode:
3599 return V8HImode;
3600 case QImode:
3601 return V16QImode;
3602 default:;
3604 if (TARGET_SPE)
3605 switch (mode)
3607 case SFmode:
3608 return V2SFmode;
3609 case SImode:
3610 return V2SImode;
3611 default:;
3613 if (TARGET_PAIRED_FLOAT
3614 && mode == SFmode)
3615 return V2SFmode;
3616 return word_mode;
3619 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3620 library with vectorized intrinsics. */
3622 static tree
3623 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3625 char name[32];
3626 const char *suffix = NULL;
3627 tree fntype, new_fndecl, bdecl = NULL_TREE;
3628 int n_args = 1;
3629 const char *bname;
3630 enum machine_mode el_mode, in_mode;
3631 int n, in_n;
3633 /* Libmass is suitable for unsafe math only as it does not correctly support
3634 parts of IEEE with the required precision such as denormals. Only support
3635 it if we have VSX to use the simd d2 or f4 functions.
3636 XXX: Add variable length support. */
3637 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3638 return NULL_TREE;
3640 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3641 n = TYPE_VECTOR_SUBPARTS (type_out);
3642 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3643 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3644 if (el_mode != in_mode
3645 || n != in_n)
3646 return NULL_TREE;
3648 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3650 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3651 switch (fn)
3653 case BUILT_IN_ATAN2:
3654 case BUILT_IN_HYPOT:
3655 case BUILT_IN_POW:
3656 n_args = 2;
3657 /* fall through */
3659 case BUILT_IN_ACOS:
3660 case BUILT_IN_ACOSH:
3661 case BUILT_IN_ASIN:
3662 case BUILT_IN_ASINH:
3663 case BUILT_IN_ATAN:
3664 case BUILT_IN_ATANH:
3665 case BUILT_IN_CBRT:
3666 case BUILT_IN_COS:
3667 case BUILT_IN_COSH:
3668 case BUILT_IN_ERF:
3669 case BUILT_IN_ERFC:
3670 case BUILT_IN_EXP2:
3671 case BUILT_IN_EXP:
3672 case BUILT_IN_EXPM1:
3673 case BUILT_IN_LGAMMA:
3674 case BUILT_IN_LOG10:
3675 case BUILT_IN_LOG1P:
3676 case BUILT_IN_LOG2:
3677 case BUILT_IN_LOG:
3678 case BUILT_IN_SIN:
3679 case BUILT_IN_SINH:
3680 case BUILT_IN_SQRT:
3681 case BUILT_IN_TAN:
3682 case BUILT_IN_TANH:
3683 bdecl = builtin_decl_implicit (fn);
3684 suffix = "d2"; /* pow -> powd2 */
3685 if (el_mode != DFmode
3686 || n != 2)
3687 return NULL_TREE;
3688 break;
3690 case BUILT_IN_ATAN2F:
3691 case BUILT_IN_HYPOTF:
3692 case BUILT_IN_POWF:
3693 n_args = 2;
3694 /* fall through */
3696 case BUILT_IN_ACOSF:
3697 case BUILT_IN_ACOSHF:
3698 case BUILT_IN_ASINF:
3699 case BUILT_IN_ASINHF:
3700 case BUILT_IN_ATANF:
3701 case BUILT_IN_ATANHF:
3702 case BUILT_IN_CBRTF:
3703 case BUILT_IN_COSF:
3704 case BUILT_IN_COSHF:
3705 case BUILT_IN_ERFF:
3706 case BUILT_IN_ERFCF:
3707 case BUILT_IN_EXP2F:
3708 case BUILT_IN_EXPF:
3709 case BUILT_IN_EXPM1F:
3710 case BUILT_IN_LGAMMAF:
3711 case BUILT_IN_LOG10F:
3712 case BUILT_IN_LOG1PF:
3713 case BUILT_IN_LOG2F:
3714 case BUILT_IN_LOGF:
3715 case BUILT_IN_SINF:
3716 case BUILT_IN_SINHF:
3717 case BUILT_IN_SQRTF:
3718 case BUILT_IN_TANF:
3719 case BUILT_IN_TANHF:
3720 bdecl = builtin_decl_implicit (fn);
3721 suffix = "4"; /* powf -> powf4 */
3722 if (el_mode != SFmode
3723 || n != 4)
3724 return NULL_TREE;
3725 break;
3727 default:
3728 return NULL_TREE;
3731 else
3732 return NULL_TREE;
3734 gcc_assert (suffix != NULL);
3735 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3736 strcpy (name, bname + sizeof ("__builtin_") - 1);
3737 strcat (name, suffix);
3739 if (n_args == 1)
3740 fntype = build_function_type_list (type_out, type_in, NULL);
3741 else if (n_args == 2)
3742 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3743 else
3744 gcc_unreachable ();
3746 /* Build a function declaration for the vectorized function. */
3747 new_fndecl = build_decl (BUILTINS_LOCATION,
3748 FUNCTION_DECL, get_identifier (name), fntype);
3749 TREE_PUBLIC (new_fndecl) = 1;
3750 DECL_EXTERNAL (new_fndecl) = 1;
3751 DECL_IS_NOVOPS (new_fndecl) = 1;
3752 TREE_READONLY (new_fndecl) = 1;
3754 return new_fndecl;
3757 /* Returns a function decl for a vectorized version of the builtin function
3758 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3759 if it is not available. */
3761 static tree
3762 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3763 tree type_in)
3765 enum machine_mode in_mode, out_mode;
3766 int in_n, out_n;
3768 if (TREE_CODE (type_out) != VECTOR_TYPE
3769 || TREE_CODE (type_in) != VECTOR_TYPE
3770 || !TARGET_VECTORIZE_BUILTINS)
3771 return NULL_TREE;
3773 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3774 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3775 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3776 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3778 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3780 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3781 switch (fn)
3783 case BUILT_IN_COPYSIGN:
3784 if (VECTOR_UNIT_VSX_P (V2DFmode)
3785 && out_mode == DFmode && out_n == 2
3786 && in_mode == DFmode && in_n == 2)
3787 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3788 break;
3789 case BUILT_IN_COPYSIGNF:
3790 if (out_mode != SFmode || out_n != 4
3791 || in_mode != SFmode || in_n != 4)
3792 break;
3793 if (VECTOR_UNIT_VSX_P (V4SFmode))
3794 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3795 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3796 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3797 break;
3798 case BUILT_IN_SQRT:
3799 if (VECTOR_UNIT_VSX_P (V2DFmode)
3800 && out_mode == DFmode && out_n == 2
3801 && in_mode == DFmode && in_n == 2)
3802 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3803 break;
3804 case BUILT_IN_SQRTF:
3805 if (VECTOR_UNIT_VSX_P (V4SFmode)
3806 && out_mode == SFmode && out_n == 4
3807 && in_mode == SFmode && in_n == 4)
3808 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3809 break;
3810 case BUILT_IN_CEIL:
3811 if (VECTOR_UNIT_VSX_P (V2DFmode)
3812 && out_mode == DFmode && out_n == 2
3813 && in_mode == DFmode && in_n == 2)
3814 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3815 break;
3816 case BUILT_IN_CEILF:
3817 if (out_mode != SFmode || out_n != 4
3818 || in_mode != SFmode || in_n != 4)
3819 break;
3820 if (VECTOR_UNIT_VSX_P (V4SFmode))
3821 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3822 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3823 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3824 break;
3825 case BUILT_IN_FLOOR:
3826 if (VECTOR_UNIT_VSX_P (V2DFmode)
3827 && out_mode == DFmode && out_n == 2
3828 && in_mode == DFmode && in_n == 2)
3829 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3830 break;
3831 case BUILT_IN_FLOORF:
3832 if (out_mode != SFmode || out_n != 4
3833 || in_mode != SFmode || in_n != 4)
3834 break;
3835 if (VECTOR_UNIT_VSX_P (V4SFmode))
3836 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3837 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3838 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3839 break;
3840 case BUILT_IN_FMA:
3841 if (VECTOR_UNIT_VSX_P (V2DFmode)
3842 && out_mode == DFmode && out_n == 2
3843 && in_mode == DFmode && in_n == 2)
3844 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
3845 break;
3846 case BUILT_IN_FMAF:
3847 if (VECTOR_UNIT_VSX_P (V4SFmode)
3848 && out_mode == SFmode && out_n == 4
3849 && in_mode == SFmode && in_n == 4)
3850 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
3851 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
3852 && out_mode == SFmode && out_n == 4
3853 && in_mode == SFmode && in_n == 4)
3854 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
3855 break;
3856 case BUILT_IN_TRUNC:
3857 if (VECTOR_UNIT_VSX_P (V2DFmode)
3858 && out_mode == DFmode && out_n == 2
3859 && in_mode == DFmode && in_n == 2)
3860 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3861 break;
3862 case BUILT_IN_TRUNCF:
3863 if (out_mode != SFmode || out_n != 4
3864 || in_mode != SFmode || in_n != 4)
3865 break;
3866 if (VECTOR_UNIT_VSX_P (V4SFmode))
3867 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3868 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3869 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3870 break;
3871 case BUILT_IN_NEARBYINT:
3872 if (VECTOR_UNIT_VSX_P (V2DFmode)
3873 && flag_unsafe_math_optimizations
3874 && out_mode == DFmode && out_n == 2
3875 && in_mode == DFmode && in_n == 2)
3876 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3877 break;
3878 case BUILT_IN_NEARBYINTF:
3879 if (VECTOR_UNIT_VSX_P (V4SFmode)
3880 && flag_unsafe_math_optimizations
3881 && out_mode == SFmode && out_n == 4
3882 && in_mode == SFmode && in_n == 4)
3883 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3884 break;
3885 case BUILT_IN_RINT:
3886 if (VECTOR_UNIT_VSX_P (V2DFmode)
3887 && !flag_trapping_math
3888 && out_mode == DFmode && out_n == 2
3889 && in_mode == DFmode && in_n == 2)
3890 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3891 break;
3892 case BUILT_IN_RINTF:
3893 if (VECTOR_UNIT_VSX_P (V4SFmode)
3894 && !flag_trapping_math
3895 && out_mode == SFmode && out_n == 4
3896 && in_mode == SFmode && in_n == 4)
3897 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3898 break;
3899 default:
3900 break;
3904 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3906 enum rs6000_builtins fn
3907 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3908 switch (fn)
3910 case RS6000_BUILTIN_RSQRTF:
3911 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3912 && out_mode == SFmode && out_n == 4
3913 && in_mode == SFmode && in_n == 4)
3914 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3915 break;
3916 case RS6000_BUILTIN_RSQRT:
3917 if (VECTOR_UNIT_VSX_P (V2DFmode)
3918 && out_mode == DFmode && out_n == 2
3919 && in_mode == DFmode && in_n == 2)
3920 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3921 break;
3922 case RS6000_BUILTIN_RECIPF:
3923 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3924 && out_mode == SFmode && out_n == 4
3925 && in_mode == SFmode && in_n == 4)
3926 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3927 break;
3928 case RS6000_BUILTIN_RECIP:
3929 if (VECTOR_UNIT_VSX_P (V2DFmode)
3930 && out_mode == DFmode && out_n == 2
3931 && in_mode == DFmode && in_n == 2)
3932 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3933 break;
3934 default:
3935 break;
3939 /* Generate calls to libmass if appropriate. */
3940 if (rs6000_veclib_handler)
3941 return rs6000_veclib_handler (fndecl, type_out, type_in);
3943 return NULL_TREE;
3946 /* Default CPU string for rs6000*_file_start functions. */
3947 static const char *rs6000_default_cpu;
3949 /* Do anything needed at the start of the asm file. */
3951 static void
3952 rs6000_file_start (void)
3954 char buffer[80];
3955 const char *start = buffer;
3956 FILE *file = asm_out_file;
3958 rs6000_default_cpu = TARGET_CPU_DEFAULT;
3960 default_file_start ();
3962 #ifdef TARGET_BI_ARCH
3963 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3964 rs6000_default_cpu = 0;
3965 #endif
3967 if (flag_verbose_asm)
3969 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3971 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
3973 fprintf (file, "%s --with-cpu=%s", start, rs6000_default_cpu);
3974 start = "";
3977 if (global_options_set.x_rs6000_cpu_index)
3979 fprintf (file, "%s -mcpu=%s", start,
3980 processor_target_table[rs6000_cpu_index].name);
3981 start = "";
3984 if (global_options_set.x_rs6000_tune_index)
3986 fprintf (file, "%s -mtune=%s", start,
3987 processor_target_table[rs6000_tune_index].name);
3988 start = "";
3991 if (PPC405_ERRATUM77)
3993 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3994 start = "";
3997 #ifdef USING_ELFOS_H
3998 switch (rs6000_sdata)
4000 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4001 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4002 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4003 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4006 if (rs6000_sdata && g_switch_value)
4008 fprintf (file, "%s -G %d", start,
4009 g_switch_value);
4010 start = "";
4012 #endif
4014 if (*start == '\0')
4015 putc ('\n', file);
4018 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4020 switch_to_section (toc_section);
4021 switch_to_section (text_section);
4026 /* Return nonzero if this function is known to have a null epilogue. */
4029 direct_return (void)
4031 if (reload_completed)
4033 rs6000_stack_t *info = rs6000_stack_info ();
4035 if (info->first_gp_reg_save == 32
4036 && info->first_fp_reg_save == 64
4037 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4038 && ! info->lr_save_p
4039 && ! info->cr_save_p
4040 && info->vrsave_mask == 0
4041 && ! info->push_p)
4042 return 1;
4045 return 0;
4048 /* Return the number of instructions it takes to form a constant in an
4049 integer register. */
4052 num_insns_constant_wide (HOST_WIDE_INT value)
4054 /* signed constant loadable with {cal|addi} */
4055 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4056 return 1;
4058 /* constant loadable with {cau|addis} */
4059 else if ((value & 0xffff) == 0
4060 && (value >> 31 == -1 || value >> 31 == 0))
4061 return 1;
4063 #if HOST_BITS_PER_WIDE_INT == 64
4064 else if (TARGET_POWERPC64)
4066 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4067 HOST_WIDE_INT high = value >> 31;
4069 if (high == 0 || high == -1)
4070 return 2;
4072 high >>= 1;
4074 if (low == 0)
4075 return num_insns_constant_wide (high) + 1;
4076 else if (high == 0)
4077 return num_insns_constant_wide (low) + 1;
4078 else
4079 return (num_insns_constant_wide (high)
4080 + num_insns_constant_wide (low) + 1);
4082 #endif
4084 else
4085 return 2;
4089 num_insns_constant (rtx op, enum machine_mode mode)
4091 HOST_WIDE_INT low, high;
4093 switch (GET_CODE (op))
4095 case CONST_INT:
4096 #if HOST_BITS_PER_WIDE_INT == 64
4097 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4098 && mask64_operand (op, mode))
4099 return 2;
4100 else
4101 #endif
4102 return num_insns_constant_wide (INTVAL (op));
4104 case CONST_DOUBLE:
4105 if (mode == SFmode || mode == SDmode)
4107 long l;
4108 REAL_VALUE_TYPE rv;
4110 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4111 if (DECIMAL_FLOAT_MODE_P (mode))
4112 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4113 else
4114 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4115 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4118 if (mode == VOIDmode || mode == DImode)
4120 high = CONST_DOUBLE_HIGH (op);
4121 low = CONST_DOUBLE_LOW (op);
4123 else
4125 long l[2];
4126 REAL_VALUE_TYPE rv;
4128 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4129 if (DECIMAL_FLOAT_MODE_P (mode))
4130 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4131 else
4132 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4133 high = l[WORDS_BIG_ENDIAN == 0];
4134 low = l[WORDS_BIG_ENDIAN != 0];
4137 if (TARGET_32BIT)
4138 return (num_insns_constant_wide (low)
4139 + num_insns_constant_wide (high));
4140 else
4142 if ((high == 0 && low >= 0)
4143 || (high == -1 && low < 0))
4144 return num_insns_constant_wide (low);
4146 else if (mask64_operand (op, mode))
4147 return 2;
4149 else if (low == 0)
4150 return num_insns_constant_wide (high) + 1;
4152 else
4153 return (num_insns_constant_wide (high)
4154 + num_insns_constant_wide (low) + 1);
4157 default:
4158 gcc_unreachable ();
4162 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4163 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4164 corresponding element of the vector, but for V4SFmode and V2SFmode,
4165 the corresponding "float" is interpreted as an SImode integer. */
4167 HOST_WIDE_INT
4168 const_vector_elt_as_int (rtx op, unsigned int elt)
4170 rtx tmp;
4172 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4173 gcc_assert (GET_MODE (op) != V2DImode
4174 && GET_MODE (op) != V2DFmode);
4176 tmp = CONST_VECTOR_ELT (op, elt);
4177 if (GET_MODE (op) == V4SFmode
4178 || GET_MODE (op) == V2SFmode)
4179 tmp = gen_lowpart (SImode, tmp);
4180 return INTVAL (tmp);
4183 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4184 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4185 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4186 all items are set to the same value and contain COPIES replicas of the
4187 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4188 operand and the others are set to the value of the operand's msb. */
4190 static bool
4191 vspltis_constant (rtx op, unsigned step, unsigned copies)
4193 enum machine_mode mode = GET_MODE (op);
4194 enum machine_mode inner = GET_MODE_INNER (mode);
4196 unsigned i;
4197 unsigned nunits;
4198 unsigned bitsize;
4199 unsigned mask;
4201 HOST_WIDE_INT val;
4202 HOST_WIDE_INT splat_val;
4203 HOST_WIDE_INT msb_val;
4205 if (mode == V2DImode || mode == V2DFmode)
4206 return false;
4208 nunits = GET_MODE_NUNITS (mode);
4209 bitsize = GET_MODE_BITSIZE (inner);
4210 mask = GET_MODE_MASK (inner);
4212 val = const_vector_elt_as_int (op, nunits - 1);
4213 splat_val = val;
4214 msb_val = val > 0 ? 0 : -1;
4216 /* Construct the value to be splatted, if possible. If not, return 0. */
4217 for (i = 2; i <= copies; i *= 2)
4219 HOST_WIDE_INT small_val;
4220 bitsize /= 2;
4221 small_val = splat_val >> bitsize;
4222 mask >>= bitsize;
4223 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4224 return false;
4225 splat_val = small_val;
4228 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4229 if (EASY_VECTOR_15 (splat_val))
4232 /* Also check if we can splat, and then add the result to itself. Do so if
4233 the value is positive, of if the splat instruction is using OP's mode;
4234 for splat_val < 0, the splat and the add should use the same mode. */
4235 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4236 && (splat_val >= 0 || (step == 1 && copies == 1)))
4239 /* Also check if are loading up the most significant bit which can be done by
4240 loading up -1 and shifting the value left by -1. */
4241 else if (EASY_VECTOR_MSB (splat_val, inner))
4244 else
4245 return false;
4247 /* Check if VAL is present in every STEP-th element, and the
4248 other elements are filled with its most significant bit. */
4249 for (i = 0; i < nunits - 1; ++i)
4251 HOST_WIDE_INT desired_val;
4252 if (((i + 1) & (step - 1)) == 0)
4253 desired_val = val;
4254 else
4255 desired_val = msb_val;
4257 if (desired_val != const_vector_elt_as_int (op, i))
4258 return false;
4261 return true;
4265 /* Return true if OP is of the given MODE and can be synthesized
4266 with a vspltisb, vspltish or vspltisw. */
4268 bool
4269 easy_altivec_constant (rtx op, enum machine_mode mode)
4271 unsigned step, copies;
4273 if (mode == VOIDmode)
4274 mode = GET_MODE (op);
4275 else if (mode != GET_MODE (op))
4276 return false;
4278 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4279 constants. */
4280 if (mode == V2DFmode)
4281 return zero_constant (op, mode);
4283 if (mode == V2DImode)
4285 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4286 easy. */
4287 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4288 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4289 return false;
4291 if (zero_constant (op, mode))
4292 return true;
4294 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4295 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4296 return true;
4298 return false;
4301 /* Start with a vspltisw. */
4302 step = GET_MODE_NUNITS (mode) / 4;
4303 copies = 1;
4305 if (vspltis_constant (op, step, copies))
4306 return true;
4308 /* Then try with a vspltish. */
4309 if (step == 1)
4310 copies <<= 1;
4311 else
4312 step >>= 1;
4314 if (vspltis_constant (op, step, copies))
4315 return true;
4317 /* And finally a vspltisb. */
4318 if (step == 1)
4319 copies <<= 1;
4320 else
4321 step >>= 1;
4323 if (vspltis_constant (op, step, copies))
4324 return true;
4326 return false;
4329 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4330 result is OP. Abort if it is not possible. */
4333 gen_easy_altivec_constant (rtx op)
4335 enum machine_mode mode = GET_MODE (op);
4336 int nunits = GET_MODE_NUNITS (mode);
4337 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4338 unsigned step = nunits / 4;
4339 unsigned copies = 1;
4341 /* Start with a vspltisw. */
4342 if (vspltis_constant (op, step, copies))
4343 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4345 /* Then try with a vspltish. */
4346 if (step == 1)
4347 copies <<= 1;
4348 else
4349 step >>= 1;
4351 if (vspltis_constant (op, step, copies))
4352 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4354 /* And finally a vspltisb. */
4355 if (step == 1)
4356 copies <<= 1;
4357 else
4358 step >>= 1;
4360 if (vspltis_constant (op, step, copies))
4361 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4363 gcc_unreachable ();
4366 const char *
4367 output_vec_const_move (rtx *operands)
4369 int cst, cst2;
4370 enum machine_mode mode;
4371 rtx dest, vec;
4373 dest = operands[0];
4374 vec = operands[1];
4375 mode = GET_MODE (dest);
4377 if (TARGET_VSX)
4379 if (zero_constant (vec, mode))
4380 return "xxlxor %x0,%x0,%x0";
4382 if (mode == V2DImode
4383 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
4384 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
4385 return "vspltisw %0,-1";
4388 if (TARGET_ALTIVEC)
4390 rtx splat_vec;
4391 if (zero_constant (vec, mode))
4392 return "vxor %0,%0,%0";
4394 splat_vec = gen_easy_altivec_constant (vec);
4395 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4396 operands[1] = XEXP (splat_vec, 0);
4397 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4398 return "#";
4400 switch (GET_MODE (splat_vec))
4402 case V4SImode:
4403 return "vspltisw %0,%1";
4405 case V8HImode:
4406 return "vspltish %0,%1";
4408 case V16QImode:
4409 return "vspltisb %0,%1";
4411 default:
4412 gcc_unreachable ();
4416 gcc_assert (TARGET_SPE);
4418 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4419 pattern of V1DI, V4HI, and V2SF.
4421 FIXME: We should probably return # and add post reload
4422 splitters for these, but this way is so easy ;-). */
4423 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4424 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4425 operands[1] = CONST_VECTOR_ELT (vec, 0);
4426 operands[2] = CONST_VECTOR_ELT (vec, 1);
4427 if (cst == cst2)
4428 return "li %0,%1\n\tevmergelo %0,%0,%0";
4429 else
4430 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4433 /* Initialize TARGET of vector PAIRED to VALS. */
4435 void
4436 paired_expand_vector_init (rtx target, rtx vals)
4438 enum machine_mode mode = GET_MODE (target);
4439 int n_elts = GET_MODE_NUNITS (mode);
4440 int n_var = 0;
4441 rtx x, new_rtx, tmp, constant_op, op1, op2;
4442 int i;
4444 for (i = 0; i < n_elts; ++i)
4446 x = XVECEXP (vals, 0, i);
4447 if (!(CONST_INT_P (x)
4448 || GET_CODE (x) == CONST_DOUBLE
4449 || GET_CODE (x) == CONST_FIXED))
4450 ++n_var;
4452 if (n_var == 0)
4454 /* Load from constant pool. */
4455 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4456 return;
4459 if (n_var == 2)
4461 /* The vector is initialized only with non-constants. */
4462 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4463 XVECEXP (vals, 0, 1));
4465 emit_move_insn (target, new_rtx);
4466 return;
4469 /* One field is non-constant and the other one is a constant. Load the
4470 constant from the constant pool and use ps_merge instruction to
4471 construct the whole vector. */
4472 op1 = XVECEXP (vals, 0, 0);
4473 op2 = XVECEXP (vals, 0, 1);
4475 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4477 tmp = gen_reg_rtx (GET_MODE (constant_op));
4478 emit_move_insn (tmp, constant_op);
4480 if (CONSTANT_P (op1))
4481 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4482 else
4483 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4485 emit_move_insn (target, new_rtx);
4488 void
4489 paired_expand_vector_move (rtx operands[])
4491 rtx op0 = operands[0], op1 = operands[1];
4493 emit_move_insn (op0, op1);
4496 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4497 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4498 operands for the relation operation COND. This is a recursive
4499 function. */
4501 static void
4502 paired_emit_vector_compare (enum rtx_code rcode,
4503 rtx dest, rtx op0, rtx op1,
4504 rtx cc_op0, rtx cc_op1)
4506 rtx tmp = gen_reg_rtx (V2SFmode);
4507 rtx tmp1, max, min;
4509 gcc_assert (TARGET_PAIRED_FLOAT);
4510 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4512 switch (rcode)
4514 case LT:
4515 case LTU:
4516 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4517 return;
4518 case GE:
4519 case GEU:
4520 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4521 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4522 return;
4523 case LE:
4524 case LEU:
4525 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4526 return;
4527 case GT:
4528 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4529 return;
4530 case EQ:
4531 tmp1 = gen_reg_rtx (V2SFmode);
4532 max = gen_reg_rtx (V2SFmode);
4533 min = gen_reg_rtx (V2SFmode);
4534 gen_reg_rtx (V2SFmode);
4536 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4537 emit_insn (gen_selv2sf4
4538 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4539 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4540 emit_insn (gen_selv2sf4
4541 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4542 emit_insn (gen_subv2sf3 (tmp1, min, max));
4543 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4544 return;
4545 case NE:
4546 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4547 return;
4548 case UNLE:
4549 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4550 return;
4551 case UNLT:
4552 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4553 return;
4554 case UNGE:
4555 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4556 return;
4557 case UNGT:
4558 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4559 return;
4560 default:
4561 gcc_unreachable ();
4564 return;
4567 /* Emit vector conditional expression.
4568 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4569 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4572 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4573 rtx cond, rtx cc_op0, rtx cc_op1)
4575 enum rtx_code rcode = GET_CODE (cond);
4577 if (!TARGET_PAIRED_FLOAT)
4578 return 0;
4580 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4582 return 1;
4585 /* Initialize vector TARGET to VALS. */
4587 void
4588 rs6000_expand_vector_init (rtx target, rtx vals)
4590 enum machine_mode mode = GET_MODE (target);
4591 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4592 int n_elts = GET_MODE_NUNITS (mode);
4593 int n_var = 0, one_var = -1;
4594 bool all_same = true, all_const_zero = true;
4595 rtx x, mem;
4596 int i;
4598 for (i = 0; i < n_elts; ++i)
4600 x = XVECEXP (vals, 0, i);
4601 if (!(CONST_INT_P (x)
4602 || GET_CODE (x) == CONST_DOUBLE
4603 || GET_CODE (x) == CONST_FIXED))
4604 ++n_var, one_var = i;
4605 else if (x != CONST0_RTX (inner_mode))
4606 all_const_zero = false;
4608 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4609 all_same = false;
4612 if (n_var == 0)
4614 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4615 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4616 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4618 /* Zero register. */
4619 emit_insn (gen_rtx_SET (VOIDmode, target,
4620 gen_rtx_XOR (mode, target, target)));
4621 return;
4623 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4625 /* Splat immediate. */
4626 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4627 return;
4629 else
4631 /* Load from constant pool. */
4632 emit_move_insn (target, const_vec);
4633 return;
4637 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4638 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4640 if (all_same)
4642 rtx element = XVECEXP (vals, 0, 0);
4643 if (mode == V2DFmode)
4644 emit_insn (gen_vsx_splat_v2df (target, element));
4645 else
4646 emit_insn (gen_vsx_splat_v2di (target, element));
4648 else
4650 if (mode == V2DFmode)
4652 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
4653 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
4654 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4656 else
4658 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
4659 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
4660 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4663 return;
4666 /* With single precision floating point on VSX, know that internally single
4667 precision is actually represented as a double, and either make 2 V2DF
4668 vectors, and convert these vectors to single precision, or do one
4669 conversion, and splat the result to the other elements. */
4670 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4672 if (all_same)
4674 rtx freg = gen_reg_rtx (V4SFmode);
4675 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4677 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4678 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4680 else
4682 rtx dbl_even = gen_reg_rtx (V2DFmode);
4683 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4684 rtx flt_even = gen_reg_rtx (V4SFmode);
4685 rtx flt_odd = gen_reg_rtx (V4SFmode);
4687 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4688 copy_to_reg (XVECEXP (vals, 0, 0)),
4689 copy_to_reg (XVECEXP (vals, 0, 1))));
4690 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4691 copy_to_reg (XVECEXP (vals, 0, 2)),
4692 copy_to_reg (XVECEXP (vals, 0, 3))));
4693 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4694 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4695 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4697 return;
4700 /* Store value to stack temp. Load vector element. Splat. However, splat
4701 of 64-bit items is not supported on Altivec. */
4702 if (all_same && GET_MODE_SIZE (inner_mode) <= 4)
4704 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4705 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4706 XVECEXP (vals, 0, 0));
4707 x = gen_rtx_UNSPEC (VOIDmode,
4708 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4709 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4710 gen_rtvec (2,
4711 gen_rtx_SET (VOIDmode,
4712 target, mem),
4713 x)));
4714 x = gen_rtx_VEC_SELECT (inner_mode, target,
4715 gen_rtx_PARALLEL (VOIDmode,
4716 gen_rtvec (1, const0_rtx)));
4717 emit_insn (gen_rtx_SET (VOIDmode, target,
4718 gen_rtx_VEC_DUPLICATE (mode, x)));
4719 return;
4722 /* One field is non-constant. Load constant then overwrite
4723 varying field. */
4724 if (n_var == 1)
4726 rtx copy = copy_rtx (vals);
4728 /* Load constant part of vector, substitute neighboring value for
4729 varying element. */
4730 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4731 rs6000_expand_vector_init (target, copy);
4733 /* Insert variable. */
4734 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4735 return;
4738 /* Construct the vector in memory one field at a time
4739 and load the whole vector. */
4740 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4741 for (i = 0; i < n_elts; i++)
4742 emit_move_insn (adjust_address_nv (mem, inner_mode,
4743 i * GET_MODE_SIZE (inner_mode)),
4744 XVECEXP (vals, 0, i));
4745 emit_move_insn (target, mem);
4748 /* Set field ELT of TARGET to VAL. */
4750 void
4751 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4753 enum machine_mode mode = GET_MODE (target);
4754 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4755 rtx reg = gen_reg_rtx (mode);
4756 rtx mask, mem, x;
4757 int width = GET_MODE_SIZE (inner_mode);
4758 int i;
4760 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4762 rtx (*set_func) (rtx, rtx, rtx, rtx)
4763 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4764 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4765 return;
4768 /* Load single variable value. */
4769 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4770 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4771 x = gen_rtx_UNSPEC (VOIDmode,
4772 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4773 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4774 gen_rtvec (2,
4775 gen_rtx_SET (VOIDmode,
4776 reg, mem),
4777 x)));
4779 /* Linear sequence. */
4780 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4781 for (i = 0; i < 16; ++i)
4782 XVECEXP (mask, 0, i) = GEN_INT (i);
4784 /* Set permute mask to insert element into target. */
4785 for (i = 0; i < width; ++i)
4786 XVECEXP (mask, 0, elt*width + i)
4787 = GEN_INT (i + 0x10);
4788 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4789 x = gen_rtx_UNSPEC (mode,
4790 gen_rtvec (3, target, reg,
4791 force_reg (V16QImode, x)),
4792 UNSPEC_VPERM);
4793 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4796 /* Extract field ELT from VEC into TARGET. */
4798 void
4799 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4801 enum machine_mode mode = GET_MODE (vec);
4802 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4803 rtx mem;
4805 if (VECTOR_MEM_VSX_P (mode))
4807 switch (mode)
4809 default:
4810 break;
4811 case V2DFmode:
4812 emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
4813 return;
4814 case V2DImode:
4815 emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt)));
4816 return;
4817 case V4SFmode:
4818 emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
4819 return;
4823 /* Allocate mode-sized buffer. */
4824 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4826 emit_move_insn (mem, vec);
4828 /* Add offset to field within buffer matching vector element. */
4829 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
4831 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4834 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4835 implement ANDing by the mask IN. */
4836 void
4837 build_mask64_2_operands (rtx in, rtx *out)
4839 #if HOST_BITS_PER_WIDE_INT >= 64
4840 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4841 int shift;
4843 gcc_assert (GET_CODE (in) == CONST_INT);
4845 c = INTVAL (in);
4846 if (c & 1)
4848 /* Assume c initially something like 0x00fff000000fffff. The idea
4849 is to rotate the word so that the middle ^^^^^^ group of zeros
4850 is at the MS end and can be cleared with an rldicl mask. We then
4851 rotate back and clear off the MS ^^ group of zeros with a
4852 second rldicl. */
4853 c = ~c; /* c == 0xff000ffffff00000 */
4854 lsb = c & -c; /* lsb == 0x0000000000100000 */
4855 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4856 c = ~c; /* c == 0x00fff000000fffff */
4857 c &= -lsb; /* c == 0x00fff00000000000 */
4858 lsb = c & -c; /* lsb == 0x0000100000000000 */
4859 c = ~c; /* c == 0xff000fffffffffff */
4860 c &= -lsb; /* c == 0xff00000000000000 */
4861 shift = 0;
4862 while ((lsb >>= 1) != 0)
4863 shift++; /* shift == 44 on exit from loop */
4864 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4865 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4866 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4868 else
4870 /* Assume c initially something like 0xff000f0000000000. The idea
4871 is to rotate the word so that the ^^^ middle group of zeros
4872 is at the LS end and can be cleared with an rldicr mask. We then
4873 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4874 a second rldicr. */
4875 lsb = c & -c; /* lsb == 0x0000010000000000 */
4876 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4877 c = ~c; /* c == 0x00fff0ffffffffff */
4878 c &= -lsb; /* c == 0x00fff00000000000 */
4879 lsb = c & -c; /* lsb == 0x0000100000000000 */
4880 c = ~c; /* c == 0xff000fffffffffff */
4881 c &= -lsb; /* c == 0xff00000000000000 */
4882 shift = 0;
4883 while ((lsb >>= 1) != 0)
4884 shift++; /* shift == 44 on exit from loop */
4885 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4886 m1 >>= shift; /* m1 == 0x0000000000000fff */
4887 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4890 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4891 masks will be all 1's. We are guaranteed more than one transition. */
4892 out[0] = GEN_INT (64 - shift);
4893 out[1] = GEN_INT (m1);
4894 out[2] = GEN_INT (shift);
4895 out[3] = GEN_INT (m2);
4896 #else
4897 (void)in;
4898 (void)out;
4899 gcc_unreachable ();
4900 #endif
4903 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4905 bool
4906 invalid_e500_subreg (rtx op, enum machine_mode mode)
4908 if (TARGET_E500_DOUBLE)
4910 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4911 subreg:TI and reg:TF. Decimal float modes are like integer
4912 modes (only low part of each register used) for this
4913 purpose. */
4914 if (GET_CODE (op) == SUBREG
4915 && (mode == SImode || mode == DImode || mode == TImode
4916 || mode == DDmode || mode == TDmode)
4917 && REG_P (SUBREG_REG (op))
4918 && (GET_MODE (SUBREG_REG (op)) == DFmode
4919 || GET_MODE (SUBREG_REG (op)) == TFmode))
4920 return true;
4922 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4923 reg:TI. */
4924 if (GET_CODE (op) == SUBREG
4925 && (mode == DFmode || mode == TFmode)
4926 && REG_P (SUBREG_REG (op))
4927 && (GET_MODE (SUBREG_REG (op)) == DImode
4928 || GET_MODE (SUBREG_REG (op)) == TImode
4929 || GET_MODE (SUBREG_REG (op)) == DDmode
4930 || GET_MODE (SUBREG_REG (op)) == TDmode))
4931 return true;
4934 if (TARGET_SPE
4935 && GET_CODE (op) == SUBREG
4936 && mode == SImode
4937 && REG_P (SUBREG_REG (op))
4938 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4939 return true;
4941 return false;
4944 /* AIX increases natural record alignment to doubleword if the first
4945 field is an FP double while the FP fields remain word aligned. */
4947 unsigned int
4948 rs6000_special_round_type_align (tree type, unsigned int computed,
4949 unsigned int specified)
4951 unsigned int align = MAX (computed, specified);
4952 tree field = TYPE_FIELDS (type);
4954 /* Skip all non field decls */
4955 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4956 field = DECL_CHAIN (field);
4958 if (field != NULL && field != type)
4960 type = TREE_TYPE (field);
4961 while (TREE_CODE (type) == ARRAY_TYPE)
4962 type = TREE_TYPE (type);
4964 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4965 align = MAX (align, 64);
4968 return align;
4971 /* Darwin increases record alignment to the natural alignment of
4972 the first field. */
4974 unsigned int
4975 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4976 unsigned int specified)
4978 unsigned int align = MAX (computed, specified);
4980 if (TYPE_PACKED (type))
4981 return align;
4983 /* Find the first field, looking down into aggregates. */
4984 do {
4985 tree field = TYPE_FIELDS (type);
4986 /* Skip all non field decls */
4987 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4988 field = DECL_CHAIN (field);
4989 if (! field)
4990 break;
4991 /* A packed field does not contribute any extra alignment. */
4992 if (DECL_PACKED (field))
4993 return align;
4994 type = TREE_TYPE (field);
4995 while (TREE_CODE (type) == ARRAY_TYPE)
4996 type = TREE_TYPE (type);
4997 } while (AGGREGATE_TYPE_P (type));
4999 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5000 align = MAX (align, TYPE_ALIGN (type));
5002 return align;
5005 /* Return 1 for an operand in small memory on V.4/eabi. */
5008 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5009 enum machine_mode mode ATTRIBUTE_UNUSED)
5011 #if TARGET_ELF
5012 rtx sym_ref;
5014 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5015 return 0;
5017 if (DEFAULT_ABI != ABI_V4)
5018 return 0;
5020 /* Vector and float memory instructions have a limited offset on the
5021 SPE, so using a vector or float variable directly as an operand is
5022 not useful. */
5023 if (TARGET_SPE
5024 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5025 return 0;
5027 if (GET_CODE (op) == SYMBOL_REF)
5028 sym_ref = op;
5030 else if (GET_CODE (op) != CONST
5031 || GET_CODE (XEXP (op, 0)) != PLUS
5032 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5033 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5034 return 0;
5036 else
5038 rtx sum = XEXP (op, 0);
5039 HOST_WIDE_INT summand;
5041 /* We have to be careful here, because it is the referenced address
5042 that must be 32k from _SDA_BASE_, not just the symbol. */
5043 summand = INTVAL (XEXP (sum, 1));
5044 if (summand < 0 || summand > g_switch_value)
5045 return 0;
5047 sym_ref = XEXP (sum, 0);
5050 return SYMBOL_REF_SMALL_P (sym_ref);
5051 #else
5052 return 0;
5053 #endif
5056 /* Return true if either operand is a general purpose register. */
5058 bool
5059 gpr_or_gpr_p (rtx op0, rtx op1)
5061 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5062 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5066 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5068 static bool
5069 reg_offset_addressing_ok_p (enum machine_mode mode)
5071 switch (mode)
5073 case V16QImode:
5074 case V8HImode:
5075 case V4SFmode:
5076 case V4SImode:
5077 case V2DFmode:
5078 case V2DImode:
5079 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5080 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5081 return false;
5082 break;
5084 case V4HImode:
5085 case V2SImode:
5086 case V1DImode:
5087 case V2SFmode:
5088 /* Paired vector modes. Only reg+reg addressing is valid. */
5089 if (TARGET_PAIRED_FLOAT)
5090 return false;
5091 break;
5093 default:
5094 break;
5097 return true;
5100 static bool
5101 virtual_stack_registers_memory_p (rtx op)
5103 int regnum;
5105 if (GET_CODE (op) == REG)
5106 regnum = REGNO (op);
5108 else if (GET_CODE (op) == PLUS
5109 && GET_CODE (XEXP (op, 0)) == REG
5110 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5111 regnum = REGNO (XEXP (op, 0));
5113 else
5114 return false;
5116 return (regnum >= FIRST_VIRTUAL_REGISTER
5117 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5120 /* Return true if memory accesses to OP are known to never straddle
5121 a 32k boundary. */
5123 static bool
5124 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5125 enum machine_mode mode)
5127 tree decl, type;
5128 unsigned HOST_WIDE_INT dsize, dalign;
5130 if (GET_CODE (op) != SYMBOL_REF)
5131 return false;
5133 decl = SYMBOL_REF_DECL (op);
5134 if (!decl)
5136 if (GET_MODE_SIZE (mode) == 0)
5137 return false;
5139 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5140 replacing memory addresses with an anchor plus offset. We
5141 could find the decl by rummaging around in the block->objects
5142 VEC for the given offset but that seems like too much work. */
5143 dalign = 1;
5144 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5145 && SYMBOL_REF_ANCHOR_P (op)
5146 && SYMBOL_REF_BLOCK (op) != NULL)
5148 struct object_block *block = SYMBOL_REF_BLOCK (op);
5149 HOST_WIDE_INT lsb, mask;
5151 /* Given the alignment of the block.. */
5152 dalign = block->alignment;
5153 mask = dalign / BITS_PER_UNIT - 1;
5155 /* ..and the combined offset of the anchor and any offset
5156 to this block object.. */
5157 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5158 lsb = offset & -offset;
5160 /* ..find how many bits of the alignment we know for the
5161 object. */
5162 mask &= lsb - 1;
5163 dalign = mask + 1;
5165 return dalign >= GET_MODE_SIZE (mode);
5168 if (DECL_P (decl))
5170 if (TREE_CODE (decl) == FUNCTION_DECL)
5171 return true;
5173 if (!DECL_SIZE_UNIT (decl))
5174 return false;
5176 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5177 return false;
5179 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5180 if (dsize > 32768)
5181 return false;
5183 dalign = DECL_ALIGN_UNIT (decl);
5184 return dalign >= dsize;
5187 type = TREE_TYPE (decl);
5189 if (TREE_CODE (decl) == STRING_CST)
5190 dsize = TREE_STRING_LENGTH (decl);
5191 else if (TYPE_SIZE_UNIT (type)
5192 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5193 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5194 else
5195 return false;
5196 if (dsize > 32768)
5197 return false;
5199 dalign = TYPE_ALIGN (type);
5200 if (CONSTANT_CLASS_P (decl))
5201 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5202 else
5203 dalign = DATA_ALIGNMENT (decl, dalign);
5204 dalign /= BITS_PER_UNIT;
5205 return dalign >= dsize;
5208 static bool
5209 constant_pool_expr_p (rtx op)
5211 rtx base, offset;
5213 split_const (op, &base, &offset);
5214 return (GET_CODE (base) == SYMBOL_REF
5215 && CONSTANT_POOL_ADDRESS_P (base)
5216 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5219 static rtx tocrel_base, tocrel_offset;
5221 bool
5222 toc_relative_expr_p (rtx op)
5224 if (GET_CODE (op) != CONST)
5225 return false;
5227 split_const (op, &tocrel_base, &tocrel_offset);
5228 return (GET_CODE (tocrel_base) == UNSPEC
5229 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5232 /* Return true if X is a constant pool address, and also for cmodel=medium
5233 if X is a toc-relative address known to be offsettable within MODE. */
5235 bool
5236 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5237 bool strict)
5239 return (TARGET_TOC
5240 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5241 && GET_CODE (XEXP (x, 0)) == REG
5242 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5243 || ((TARGET_MINIMAL_TOC
5244 || TARGET_CMODEL != CMODEL_SMALL)
5245 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5246 && toc_relative_expr_p (XEXP (x, 1))
5247 && (TARGET_CMODEL != CMODEL_MEDIUM
5248 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5249 || mode == QImode
5250 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5251 INTVAL (tocrel_offset), mode)));
5254 static bool
5255 legitimate_small_data_p (enum machine_mode mode, rtx x)
5257 return (DEFAULT_ABI == ABI_V4
5258 && !flag_pic && !TARGET_TOC
5259 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5260 && small_data_operand (x, mode));
5263 /* SPE offset addressing is limited to 5-bits worth of double words. */
5264 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5266 bool
5267 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5269 unsigned HOST_WIDE_INT offset, extra;
5271 if (GET_CODE (x) != PLUS)
5272 return false;
5273 if (GET_CODE (XEXP (x, 0)) != REG)
5274 return false;
5275 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5276 return false;
5277 if (!reg_offset_addressing_ok_p (mode))
5278 return virtual_stack_registers_memory_p (x);
5279 if (legitimate_constant_pool_address_p (x, mode, strict))
5280 return true;
5281 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5282 return false;
5284 offset = INTVAL (XEXP (x, 1));
5285 extra = 0;
5286 switch (mode)
5288 case V4HImode:
5289 case V2SImode:
5290 case V1DImode:
5291 case V2SFmode:
5292 /* SPE vector modes. */
5293 return SPE_CONST_OFFSET_OK (offset);
5295 case DFmode:
5296 if (TARGET_E500_DOUBLE)
5297 return SPE_CONST_OFFSET_OK (offset);
5299 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5300 addressing. */
5301 if (VECTOR_MEM_VSX_P (DFmode))
5302 return false;
5304 case DDmode:
5305 case DImode:
5306 /* On e500v2, we may have:
5308 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5310 Which gets addressed with evldd instructions. */
5311 if (TARGET_E500_DOUBLE)
5312 return SPE_CONST_OFFSET_OK (offset);
5314 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5315 extra = 4;
5316 else if (offset & 3)
5317 return false;
5318 break;
5320 case TFmode:
5321 if (TARGET_E500_DOUBLE)
5322 return (SPE_CONST_OFFSET_OK (offset)
5323 && SPE_CONST_OFFSET_OK (offset + 8));
5325 case TDmode:
5326 case TImode:
5327 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5328 extra = 12;
5329 else if (offset & 3)
5330 return false;
5331 else
5332 extra = 8;
5333 break;
5335 default:
5336 break;
5339 offset += 0x8000;
5340 return offset < 0x10000 - extra;
5343 bool
5344 legitimate_indexed_address_p (rtx x, int strict)
5346 rtx op0, op1;
5348 if (GET_CODE (x) != PLUS)
5349 return false;
5351 op0 = XEXP (x, 0);
5352 op1 = XEXP (x, 1);
5354 /* Recognize the rtl generated by reload which we know will later be
5355 replaced with proper base and index regs. */
5356 if (!strict
5357 && reload_in_progress
5358 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5359 && REG_P (op1))
5360 return true;
5362 return (REG_P (op0) && REG_P (op1)
5363 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5364 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5365 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5366 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5369 bool
5370 avoiding_indexed_address_p (enum machine_mode mode)
5372 /* Avoid indexed addressing for modes that have non-indexed
5373 load/store instruction forms. */
5374 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5377 inline bool
5378 legitimate_indirect_address_p (rtx x, int strict)
5380 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5383 bool
5384 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5386 if (!TARGET_MACHO || !flag_pic
5387 || mode != SImode || GET_CODE (x) != MEM)
5388 return false;
5389 x = XEXP (x, 0);
5391 if (GET_CODE (x) != LO_SUM)
5392 return false;
5393 if (GET_CODE (XEXP (x, 0)) != REG)
5394 return false;
5395 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5396 return false;
5397 x = XEXP (x, 1);
5399 return CONSTANT_P (x);
5402 static bool
5403 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5405 if (GET_CODE (x) != LO_SUM)
5406 return false;
5407 if (GET_CODE (XEXP (x, 0)) != REG)
5408 return false;
5409 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5410 return false;
5411 /* Restrict addressing for DI because of our SUBREG hackery. */
5412 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5413 || mode == DDmode || mode == TDmode
5414 || mode == DImode))
5415 return false;
5416 x = XEXP (x, 1);
5418 if (TARGET_ELF || TARGET_MACHO)
5420 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5421 return false;
5422 if (TARGET_TOC)
5423 return false;
5424 if (GET_MODE_NUNITS (mode) != 1)
5425 return false;
5426 if (GET_MODE_BITSIZE (mode) > 64
5427 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5428 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5429 && (mode == DFmode || mode == DDmode))))
5430 return false;
5432 return CONSTANT_P (x);
5435 return false;
5439 /* Try machine-dependent ways of modifying an illegitimate address
5440 to be legitimate. If we find one, return the new, valid address.
5441 This is used from only one place: `memory_address' in explow.c.
5443 OLDX is the address as it was before break_out_memory_refs was
5444 called. In some cases it is useful to look at this to decide what
5445 needs to be done.
5447 It is always safe for this function to do nothing. It exists to
5448 recognize opportunities to optimize the output.
5450 On RS/6000, first check for the sum of a register with a constant
5451 integer that is out of range. If so, generate code to add the
5452 constant with the low-order 16 bits masked to the register and force
5453 this result into another register (this can be done with `cau').
5454 Then generate an address of REG+(CONST&0xffff), allowing for the
5455 possibility of bit 16 being a one.
5457 Then check for the sum of a register and something not constant, try to
5458 load the other things into a register and return the sum. */
5460 static rtx
5461 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5462 enum machine_mode mode)
5464 unsigned int extra = 0;
5466 if (!reg_offset_addressing_ok_p (mode))
5468 if (virtual_stack_registers_memory_p (x))
5469 return x;
5471 /* In theory we should not be seeing addresses of the form reg+0,
5472 but just in case it is generated, optimize it away. */
5473 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5474 return force_reg (Pmode, XEXP (x, 0));
5476 /* Make sure both operands are registers. */
5477 else if (GET_CODE (x) == PLUS)
5478 return gen_rtx_PLUS (Pmode,
5479 force_reg (Pmode, XEXP (x, 0)),
5480 force_reg (Pmode, XEXP (x, 1)));
5481 else
5482 return force_reg (Pmode, x);
5484 if (GET_CODE (x) == SYMBOL_REF)
5486 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5487 if (model != 0)
5488 return rs6000_legitimize_tls_address (x, model);
5491 switch (mode)
5493 case DFmode:
5494 case DDmode:
5495 extra = 4;
5496 break;
5497 case DImode:
5498 if (!TARGET_POWERPC64)
5499 extra = 4;
5500 break;
5501 case TFmode:
5502 case TDmode:
5503 extra = 12;
5504 break;
5505 case TImode:
5506 extra = TARGET_POWERPC64 ? 8 : 12;
5507 break;
5508 default:
5509 break;
5512 if (GET_CODE (x) == PLUS
5513 && GET_CODE (XEXP (x, 0)) == REG
5514 && GET_CODE (XEXP (x, 1)) == CONST_INT
5515 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5516 >= 0x10000 - extra)
5517 && !((TARGET_POWERPC64
5518 && (mode == DImode || mode == TImode)
5519 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5520 || SPE_VECTOR_MODE (mode)
5521 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5522 || mode == DImode || mode == DDmode
5523 || mode == TDmode))))
5525 HOST_WIDE_INT high_int, low_int;
5526 rtx sum;
5527 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5528 if (low_int >= 0x8000 - extra)
5529 low_int = 0;
5530 high_int = INTVAL (XEXP (x, 1)) - low_int;
5531 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5532 GEN_INT (high_int)), 0);
5533 return plus_constant (sum, low_int);
5535 else if (GET_CODE (x) == PLUS
5536 && GET_CODE (XEXP (x, 0)) == REG
5537 && GET_CODE (XEXP (x, 1)) != CONST_INT
5538 && GET_MODE_NUNITS (mode) == 1
5539 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5540 || TARGET_POWERPC64
5541 || ((mode != DImode && mode != DFmode && mode != DDmode)
5542 || (TARGET_E500_DOUBLE && mode != DDmode)))
5543 && (TARGET_POWERPC64 || mode != DImode)
5544 && !avoiding_indexed_address_p (mode)
5545 && mode != TImode
5546 && mode != TFmode
5547 && mode != TDmode)
5549 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5550 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5552 else if (SPE_VECTOR_MODE (mode)
5553 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5554 || mode == DDmode || mode == TDmode
5555 || mode == DImode)))
5557 if (mode == DImode)
5558 return x;
5559 /* We accept [reg + reg] and [reg + OFFSET]. */
5561 if (GET_CODE (x) == PLUS)
5563 rtx op1 = XEXP (x, 0);
5564 rtx op2 = XEXP (x, 1);
5565 rtx y;
5567 op1 = force_reg (Pmode, op1);
5569 if (GET_CODE (op2) != REG
5570 && (GET_CODE (op2) != CONST_INT
5571 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5572 || (GET_MODE_SIZE (mode) > 8
5573 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5574 op2 = force_reg (Pmode, op2);
5576 /* We can't always do [reg + reg] for these, because [reg +
5577 reg + offset] is not a legitimate addressing mode. */
5578 y = gen_rtx_PLUS (Pmode, op1, op2);
5580 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5581 return force_reg (Pmode, y);
5582 else
5583 return y;
5586 return force_reg (Pmode, x);
5588 else if (TARGET_ELF
5589 && TARGET_32BIT
5590 && TARGET_NO_TOC
5591 && ! flag_pic
5592 && GET_CODE (x) != CONST_INT
5593 && GET_CODE (x) != CONST_DOUBLE
5594 && CONSTANT_P (x)
5595 && GET_MODE_NUNITS (mode) == 1
5596 && (GET_MODE_BITSIZE (mode) <= 32
5597 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5598 && (mode == DFmode || mode == DDmode))))
5600 rtx reg = gen_reg_rtx (Pmode);
5601 emit_insn (gen_elf_high (reg, x));
5602 return gen_rtx_LO_SUM (Pmode, reg, x);
5604 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5605 && ! flag_pic
5606 #if TARGET_MACHO
5607 && ! MACHO_DYNAMIC_NO_PIC_P
5608 #endif
5609 && GET_CODE (x) != CONST_INT
5610 && GET_CODE (x) != CONST_DOUBLE
5611 && CONSTANT_P (x)
5612 && GET_MODE_NUNITS (mode) == 1
5613 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5614 || (mode != DFmode && mode != DDmode))
5615 && mode != DImode
5616 && mode != TImode)
5618 rtx reg = gen_reg_rtx (Pmode);
5619 emit_insn (gen_macho_high (reg, x));
5620 return gen_rtx_LO_SUM (Pmode, reg, x);
5622 else if (TARGET_TOC
5623 && GET_CODE (x) == SYMBOL_REF
5624 && constant_pool_expr_p (x)
5625 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5627 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5628 return create_TOC_reference (x, reg);
5630 else
5631 return x;
5634 /* Debug version of rs6000_legitimize_address. */
5635 static rtx
5636 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5638 rtx ret;
5639 rtx insns;
5641 start_sequence ();
5642 ret = rs6000_legitimize_address (x, oldx, mode);
5643 insns = get_insns ();
5644 end_sequence ();
5646 if (ret != x)
5648 fprintf (stderr,
5649 "\nrs6000_legitimize_address: mode %s, old code %s, "
5650 "new code %s, modified\n",
5651 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5652 GET_RTX_NAME (GET_CODE (ret)));
5654 fprintf (stderr, "Original address:\n");
5655 debug_rtx (x);
5657 fprintf (stderr, "oldx:\n");
5658 debug_rtx (oldx);
5660 fprintf (stderr, "New address:\n");
5661 debug_rtx (ret);
5663 if (insns)
5665 fprintf (stderr, "Insns added:\n");
5666 debug_rtx_list (insns, 20);
5669 else
5671 fprintf (stderr,
5672 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5673 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5675 debug_rtx (x);
5678 if (insns)
5679 emit_insn (insns);
5681 return ret;
5684 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5685 We need to emit DTP-relative relocations. */
5687 static void
5688 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5690 switch (size)
5692 case 4:
5693 fputs ("\t.long\t", file);
5694 break;
5695 case 8:
5696 fputs (DOUBLE_INT_ASM_OP, file);
5697 break;
5698 default:
5699 gcc_unreachable ();
5701 output_addr_const (file, x);
5702 fputs ("@dtprel+0x8000", file);
5705 /* In the name of slightly smaller debug output, and to cater to
5706 general assembler lossage, recognize various UNSPEC sequences
5707 and turn them back into a direct symbol reference. */
5709 static rtx
5710 rs6000_delegitimize_address (rtx orig_x)
5712 rtx x, y;
5714 orig_x = delegitimize_mem_from_attrs (orig_x);
5715 x = orig_x;
5716 if (MEM_P (x))
5717 x = XEXP (x, 0);
5719 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
5720 && GET_CODE (XEXP (x, 1)) == CONST)
5722 rtx offset = NULL_RTX;
5724 y = XEXP (XEXP (x, 1), 0);
5725 if (GET_CODE (y) == PLUS
5726 && GET_MODE (y) == Pmode
5727 && CONST_INT_P (XEXP (y, 1)))
5729 offset = XEXP (y, 1);
5730 y = XEXP (y, 0);
5732 if (GET_CODE (y) == UNSPEC
5733 && XINT (y, 1) == UNSPEC_TOCREL
5734 && ((GET_CODE (XEXP (x, 0)) == REG
5735 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5736 || TARGET_MINIMAL_TOC
5737 || TARGET_CMODEL != CMODEL_SMALL))
5738 || (TARGET_CMODEL != CMODEL_SMALL
5739 && GET_CODE (XEXP (x, 0)) == CONST
5740 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
5741 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
5742 && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER
5743 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH
5744 && rtx_equal_p (XEXP (x, 1),
5745 XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)))))
5747 y = XVECEXP (y, 0, 0);
5748 if (offset != NULL_RTX)
5749 y = gen_rtx_PLUS (Pmode, y, offset);
5750 if (!MEM_P (orig_x))
5751 return y;
5752 else
5753 return replace_equiv_address_nv (orig_x, y);
5757 if (TARGET_MACHO
5758 && GET_CODE (orig_x) == LO_SUM
5759 && GET_CODE (XEXP (orig_x, 1)) == CONST)
5761 y = XEXP (XEXP (orig_x, 1), 0);
5762 if (GET_CODE (y) == UNSPEC
5763 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5764 return XVECEXP (y, 0, 0);
5767 return orig_x;
5770 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5772 static GTY(()) rtx rs6000_tls_symbol;
5773 static rtx
5774 rs6000_tls_get_addr (void)
5776 if (!rs6000_tls_symbol)
5777 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5779 return rs6000_tls_symbol;
5782 /* Construct the SYMBOL_REF for TLS GOT references. */
5784 static GTY(()) rtx rs6000_got_symbol;
5785 static rtx
5786 rs6000_got_sym (void)
5788 if (!rs6000_got_symbol)
5790 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5791 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5792 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5795 return rs6000_got_symbol;
5798 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5799 this (thread-local) address. */
5801 static rtx
5802 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5804 rtx dest, insn;
5806 dest = gen_reg_rtx (Pmode);
5807 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5809 rtx tlsreg;
5811 if (TARGET_64BIT)
5813 tlsreg = gen_rtx_REG (Pmode, 13);
5814 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5816 else
5818 tlsreg = gen_rtx_REG (Pmode, 2);
5819 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5821 emit_insn (insn);
5823 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5825 rtx tlsreg, tmp;
5827 tmp = gen_reg_rtx (Pmode);
5828 if (TARGET_64BIT)
5830 tlsreg = gen_rtx_REG (Pmode, 13);
5831 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5833 else
5835 tlsreg = gen_rtx_REG (Pmode, 2);
5836 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5838 emit_insn (insn);
5839 if (TARGET_64BIT)
5840 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5841 else
5842 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5843 emit_insn (insn);
5845 else
5847 rtx r3, got, tga, tmp1, tmp2, call_insn;
5849 /* We currently use relocations like @got@tlsgd for tls, which
5850 means the linker will handle allocation of tls entries, placing
5851 them in the .got section. So use a pointer to the .got section,
5852 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5853 or to secondary GOT sections used by 32-bit -fPIC. */
5854 if (TARGET_64BIT)
5855 got = gen_rtx_REG (Pmode, 2);
5856 else
5858 if (flag_pic == 1)
5859 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5860 else
5862 rtx gsym = rs6000_got_sym ();
5863 got = gen_reg_rtx (Pmode);
5864 if (flag_pic == 0)
5865 rs6000_emit_move (got, gsym, Pmode);
5866 else
5868 rtx mem, lab, last;
5870 tmp1 = gen_reg_rtx (Pmode);
5871 tmp2 = gen_reg_rtx (Pmode);
5872 mem = gen_const_mem (Pmode, tmp1);
5873 lab = gen_label_rtx ();
5874 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5875 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5876 if (TARGET_LINK_STACK)
5877 emit_insn (gen_addsi3 (tmp1, tmp1, GEN_INT (4)));
5878 emit_move_insn (tmp2, mem);
5879 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5880 set_unique_reg_note (last, REG_EQUAL, gsym);
5885 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5887 tga = rs6000_tls_get_addr ();
5888 emit_library_call_value (tga, dest, LCT_CONST, Pmode,
5889 1, const0_rtx, Pmode);
5891 r3 = gen_rtx_REG (Pmode, 3);
5892 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5893 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5894 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5895 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5896 else if (DEFAULT_ABI == ABI_V4)
5897 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5898 else
5899 gcc_unreachable ();
5900 call_insn = last_call_insn ();
5901 PATTERN (call_insn) = insn;
5902 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5903 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5904 pic_offset_table_rtx);
5906 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5908 tga = rs6000_tls_get_addr ();
5909 tmp1 = gen_reg_rtx (Pmode);
5910 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
5911 1, const0_rtx, Pmode);
5913 r3 = gen_rtx_REG (Pmode, 3);
5914 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5915 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5916 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5917 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5918 else if (DEFAULT_ABI == ABI_V4)
5919 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5920 else
5921 gcc_unreachable ();
5922 call_insn = last_call_insn ();
5923 PATTERN (call_insn) = insn;
5924 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5925 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5926 pic_offset_table_rtx);
5928 if (rs6000_tls_size == 16)
5930 if (TARGET_64BIT)
5931 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5932 else
5933 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5935 else if (rs6000_tls_size == 32)
5937 tmp2 = gen_reg_rtx (Pmode);
5938 if (TARGET_64BIT)
5939 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5940 else
5941 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5942 emit_insn (insn);
5943 if (TARGET_64BIT)
5944 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5945 else
5946 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5948 else
5950 tmp2 = gen_reg_rtx (Pmode);
5951 if (TARGET_64BIT)
5952 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5953 else
5954 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5955 emit_insn (insn);
5956 insn = gen_rtx_SET (Pmode, dest,
5957 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5959 emit_insn (insn);
5961 else
5963 /* IE, or 64-bit offset LE. */
5964 tmp2 = gen_reg_rtx (Pmode);
5965 if (TARGET_64BIT)
5966 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5967 else
5968 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5969 emit_insn (insn);
5970 if (TARGET_64BIT)
5971 insn = gen_tls_tls_64 (dest, tmp2, addr);
5972 else
5973 insn = gen_tls_tls_32 (dest, tmp2, addr);
5974 emit_insn (insn);
5978 return dest;
5981 /* Return 1 if X contains a thread-local symbol. */
5983 static bool
5984 rs6000_tls_referenced_p (rtx x)
5986 if (! TARGET_HAVE_TLS)
5987 return false;
5989 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5992 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
5994 static bool
5995 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
5997 if (GET_CODE (x) == CONST
5998 && GET_CODE (XEXP (x, 0)) == PLUS
5999 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
6000 return true;
6002 return rs6000_tls_referenced_p (x);
6005 /* Return 1 if *X is a thread-local symbol. This is the same as
6006 rs6000_tls_symbol_ref except for the type of the unused argument. */
6008 static int
6009 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6011 return RS6000_SYMBOL_REF_TLS_P (*x);
6014 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6015 replace the input X, or the original X if no replacement is called for.
6016 The output parameter *WIN is 1 if the calling macro should goto WIN,
6017 0 if it should not.
6019 For RS/6000, we wish to handle large displacements off a base
6020 register by splitting the addend across an addiu/addis and the mem insn.
6021 This cuts number of extra insns needed from 3 to 1.
6023 On Darwin, we use this to generate code for floating point constants.
6024 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6025 The Darwin code is inside #if TARGET_MACHO because only then are the
6026 machopic_* functions defined. */
6027 static rtx
6028 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6029 int opnum, int type,
6030 int ind_levels ATTRIBUTE_UNUSED, int *win)
6032 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6034 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6035 DFmode/DImode MEM. */
6036 if (reg_offset_p
6037 && opnum == 1
6038 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6039 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6040 reg_offset_p = false;
6042 /* We must recognize output that we have already generated ourselves. */
6043 if (GET_CODE (x) == PLUS
6044 && GET_CODE (XEXP (x, 0)) == PLUS
6045 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6046 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6047 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6049 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6050 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6051 opnum, (enum reload_type)type);
6052 *win = 1;
6053 return x;
6056 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6057 if (GET_CODE (x) == LO_SUM
6058 && GET_CODE (XEXP (x, 0)) == HIGH)
6060 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6061 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6062 opnum, (enum reload_type)type);
6063 *win = 1;
6064 return x;
6067 #if TARGET_MACHO
6068 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6069 && GET_CODE (x) == LO_SUM
6070 && GET_CODE (XEXP (x, 0)) == PLUS
6071 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6072 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6073 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6074 && machopic_operand_p (XEXP (x, 1)))
6076 /* Result of previous invocation of this function on Darwin
6077 floating point constant. */
6078 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6079 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6080 opnum, (enum reload_type)type);
6081 *win = 1;
6082 return x;
6084 #endif
6086 if (TARGET_CMODEL != CMODEL_SMALL
6087 && GET_CODE (x) == LO_SUM
6088 && GET_CODE (XEXP (x, 0)) == PLUS
6089 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6090 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6091 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST
6092 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH
6093 && GET_CODE (XEXP (x, 1)) == CONST
6094 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6095 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6096 && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1)))
6098 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6099 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6100 opnum, (enum reload_type) type);
6101 *win = 1;
6102 return x;
6105 /* Force ld/std non-word aligned offset into base register by wrapping
6106 in offset 0. */
6107 if (GET_CODE (x) == PLUS
6108 && GET_CODE (XEXP (x, 0)) == REG
6109 && REGNO (XEXP (x, 0)) < 32
6110 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6111 && GET_CODE (XEXP (x, 1)) == CONST_INT
6112 && reg_offset_p
6113 && (INTVAL (XEXP (x, 1)) & 3) != 0
6114 && VECTOR_MEM_NONE_P (mode)
6115 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6116 && TARGET_POWERPC64)
6118 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6119 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6120 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6121 opnum, (enum reload_type) type);
6122 *win = 1;
6123 return x;
6126 if (GET_CODE (x) == PLUS
6127 && GET_CODE (XEXP (x, 0)) == REG
6128 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6129 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6130 && GET_CODE (XEXP (x, 1)) == CONST_INT
6131 && reg_offset_p
6132 && !SPE_VECTOR_MODE (mode)
6133 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6134 || mode == DDmode || mode == TDmode
6135 || mode == DImode))
6136 && VECTOR_MEM_NONE_P (mode))
6138 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6139 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6140 HOST_WIDE_INT high
6141 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6143 /* Check for 32-bit overflow. */
6144 if (high + low != val)
6146 *win = 0;
6147 return x;
6150 /* Reload the high part into a base reg; leave the low part
6151 in the mem directly. */
6153 x = gen_rtx_PLUS (GET_MODE (x),
6154 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6155 GEN_INT (high)),
6156 GEN_INT (low));
6158 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6159 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6160 opnum, (enum reload_type)type);
6161 *win = 1;
6162 return x;
6165 if (GET_CODE (x) == SYMBOL_REF
6166 && reg_offset_p
6167 && VECTOR_MEM_NONE_P (mode)
6168 && !SPE_VECTOR_MODE (mode)
6169 #if TARGET_MACHO
6170 && DEFAULT_ABI == ABI_DARWIN
6171 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6172 && machopic_symbol_defined_p (x)
6173 #else
6174 && DEFAULT_ABI == ABI_V4
6175 && !flag_pic
6176 #endif
6177 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6178 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6179 without fprs. */
6180 && mode != TFmode
6181 && mode != TDmode
6182 && (mode != DImode || TARGET_POWERPC64)
6183 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6184 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6186 #if TARGET_MACHO
6187 if (flag_pic)
6189 rtx offset = machopic_gen_offset (x);
6190 x = gen_rtx_LO_SUM (GET_MODE (x),
6191 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6192 gen_rtx_HIGH (Pmode, offset)), offset);
6194 else
6195 #endif
6196 x = gen_rtx_LO_SUM (GET_MODE (x),
6197 gen_rtx_HIGH (Pmode, x), x);
6199 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6200 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6201 opnum, (enum reload_type)type);
6202 *win = 1;
6203 return x;
6206 /* Reload an offset address wrapped by an AND that represents the
6207 masking of the lower bits. Strip the outer AND and let reload
6208 convert the offset address into an indirect address. For VSX,
6209 force reload to create the address with an AND in a separate
6210 register, because we can't guarantee an altivec register will
6211 be used. */
6212 if (VECTOR_MEM_ALTIVEC_P (mode)
6213 && GET_CODE (x) == AND
6214 && GET_CODE (XEXP (x, 0)) == PLUS
6215 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6216 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6217 && GET_CODE (XEXP (x, 1)) == CONST_INT
6218 && INTVAL (XEXP (x, 1)) == -16)
6220 x = XEXP (x, 0);
6221 *win = 1;
6222 return x;
6225 if (TARGET_TOC
6226 && reg_offset_p
6227 && GET_CODE (x) == SYMBOL_REF
6228 && constant_pool_expr_p (x)
6229 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6231 x = create_TOC_reference (x, NULL_RTX);
6232 if (TARGET_CMODEL != CMODEL_SMALL)
6233 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6234 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6235 opnum, (enum reload_type) type);
6236 *win = 1;
6237 return x;
6239 *win = 0;
6240 return x;
6243 /* Debug version of rs6000_legitimize_reload_address. */
6244 static rtx
6245 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6246 int opnum, int type,
6247 int ind_levels, int *win)
6249 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6250 ind_levels, win);
6251 fprintf (stderr,
6252 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6253 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6254 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6255 debug_rtx (x);
6257 if (x == ret)
6258 fprintf (stderr, "Same address returned\n");
6259 else if (!ret)
6260 fprintf (stderr, "NULL returned\n");
6261 else
6263 fprintf (stderr, "New address:\n");
6264 debug_rtx (ret);
6267 return ret;
6270 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6271 that is a valid memory address for an instruction.
6272 The MODE argument is the machine mode for the MEM expression
6273 that wants to use this address.
6275 On the RS/6000, there are four valid address: a SYMBOL_REF that
6276 refers to a constant pool entry of an address (or the sum of it
6277 plus a constant), a short (16-bit signed) constant plus a register,
6278 the sum of two registers, or a register indirect, possibly with an
6279 auto-increment. For DFmode, DDmode and DImode with a constant plus
6280 register, we must ensure that both words are addressable or PowerPC64
6281 with offset word aligned.
6283 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6284 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6285 because adjacent memory cells are accessed by adding word-sized offsets
6286 during assembly output. */
6287 bool
6288 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6290 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6292 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6293 if (VECTOR_MEM_ALTIVEC_P (mode)
6294 && GET_CODE (x) == AND
6295 && GET_CODE (XEXP (x, 1)) == CONST_INT
6296 && INTVAL (XEXP (x, 1)) == -16)
6297 x = XEXP (x, 0);
6299 if (RS6000_SYMBOL_REF_TLS_P (x))
6300 return 0;
6301 if (legitimate_indirect_address_p (x, reg_ok_strict))
6302 return 1;
6303 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6304 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6305 && !SPE_VECTOR_MODE (mode)
6306 && mode != TFmode
6307 && mode != TDmode
6308 /* Restrict addressing for DI because of our SUBREG hackery. */
6309 && !(TARGET_E500_DOUBLE
6310 && (mode == DFmode || mode == DDmode || mode == DImode))
6311 && TARGET_UPDATE
6312 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6313 return 1;
6314 if (virtual_stack_registers_memory_p (x))
6315 return 1;
6316 if (reg_offset_p && legitimate_small_data_p (mode, x))
6317 return 1;
6318 if (reg_offset_p
6319 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6320 return 1;
6321 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6322 if (! reg_ok_strict
6323 && reg_offset_p
6324 && GET_CODE (x) == PLUS
6325 && GET_CODE (XEXP (x, 0)) == REG
6326 && (XEXP (x, 0) == virtual_stack_vars_rtx
6327 || XEXP (x, 0) == arg_pointer_rtx)
6328 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6329 return 1;
6330 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6331 return 1;
6332 if (mode != TImode
6333 && mode != TFmode
6334 && mode != TDmode
6335 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6336 || TARGET_POWERPC64
6337 || (mode != DFmode && mode != DDmode)
6338 || (TARGET_E500_DOUBLE && mode != DDmode))
6339 && (TARGET_POWERPC64 || mode != DImode)
6340 && !avoiding_indexed_address_p (mode)
6341 && legitimate_indexed_address_p (x, reg_ok_strict))
6342 return 1;
6343 if (GET_CODE (x) == PRE_MODIFY
6344 && mode != TImode
6345 && mode != TFmode
6346 && mode != TDmode
6347 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6348 || TARGET_POWERPC64
6349 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6350 && (TARGET_POWERPC64 || mode != DImode)
6351 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6352 && !SPE_VECTOR_MODE (mode)
6353 /* Restrict addressing for DI because of our SUBREG hackery. */
6354 && !(TARGET_E500_DOUBLE
6355 && (mode == DFmode || mode == DDmode || mode == DImode))
6356 && TARGET_UPDATE
6357 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6358 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6359 || (!avoiding_indexed_address_p (mode)
6360 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6361 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6362 return 1;
6363 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6364 return 1;
6365 return 0;
6368 /* Debug version of rs6000_legitimate_address_p. */
6369 static bool
6370 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6371 bool reg_ok_strict)
6373 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6374 fprintf (stderr,
6375 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6376 "strict = %d, code = %s\n",
6377 ret ? "true" : "false",
6378 GET_MODE_NAME (mode),
6379 reg_ok_strict,
6380 GET_RTX_NAME (GET_CODE (x)));
6381 debug_rtx (x);
6383 return ret;
6386 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6388 static bool
6389 rs6000_mode_dependent_address_p (const_rtx addr)
6391 return rs6000_mode_dependent_address_ptr (addr);
6394 /* Go to LABEL if ADDR (a legitimate address expression)
6395 has an effect that depends on the machine mode it is used for.
6397 On the RS/6000 this is true of all integral offsets (since AltiVec
6398 and VSX modes don't allow them) or is a pre-increment or decrement.
6400 ??? Except that due to conceptual problems in offsettable_address_p
6401 we can't really report the problems of integral offsets. So leave
6402 this assuming that the adjustable offset must be valid for the
6403 sub-words of a TFmode operand, which is what we had before. */
6405 static bool
6406 rs6000_mode_dependent_address (const_rtx addr)
6408 switch (GET_CODE (addr))
6410 case PLUS:
6411 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6412 is considered a legitimate address before reload, so there
6413 are no offset restrictions in that case. Note that this
6414 condition is safe in strict mode because any address involving
6415 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6416 been rejected as illegitimate. */
6417 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6418 && XEXP (addr, 0) != arg_pointer_rtx
6419 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6421 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6422 return val + 12 + 0x8000 >= 0x10000;
6424 break;
6426 case LO_SUM:
6427 /* Anything in the constant pool is sufficiently aligned that
6428 all bytes have the same high part address. */
6429 return !legitimate_constant_pool_address_p (addr, QImode, false);
6431 /* Auto-increment cases are now treated generically in recog.c. */
6432 case PRE_MODIFY:
6433 return TARGET_UPDATE;
6435 /* AND is only allowed in Altivec loads. */
6436 case AND:
6437 return true;
6439 default:
6440 break;
6443 return false;
6446 /* Debug version of rs6000_mode_dependent_address. */
6447 static bool
6448 rs6000_debug_mode_dependent_address (const_rtx addr)
6450 bool ret = rs6000_mode_dependent_address (addr);
6452 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6453 ret ? "true" : "false");
6454 debug_rtx (addr);
6456 return ret;
6459 /* Implement FIND_BASE_TERM. */
6462 rs6000_find_base_term (rtx op)
6464 rtx base, offset;
6466 split_const (op, &base, &offset);
6467 if (GET_CODE (base) == UNSPEC)
6468 switch (XINT (base, 1))
6470 case UNSPEC_TOCREL:
6471 case UNSPEC_MACHOPIC_OFFSET:
6472 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6473 for aliasing purposes. */
6474 return XVECEXP (base, 0, 0);
6477 return op;
6480 /* More elaborate version of recog's offsettable_memref_p predicate
6481 that works around the ??? note of rs6000_mode_dependent_address.
6482 In particular it accepts
6484 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6486 in 32-bit mode, that the recog predicate rejects. */
6488 bool
6489 rs6000_offsettable_memref_p (rtx op)
6491 if (!MEM_P (op))
6492 return false;
6494 /* First mimic offsettable_memref_p. */
6495 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6496 return true;
6498 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6499 the latter predicate knows nothing about the mode of the memory
6500 reference and, therefore, assumes that it is the largest supported
6501 mode (TFmode). As a consequence, legitimate offsettable memory
6502 references are rejected. rs6000_legitimate_offset_address_p contains
6503 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6504 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6507 /* Change register usage conditional on target flags. */
6508 static void
6509 rs6000_conditional_register_usage (void)
6511 int i;
6513 if (TARGET_DEBUG_TARGET)
6514 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6516 /* Set MQ register fixed (already call_used) if not POWER
6517 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6518 be allocated. */
6519 if (! TARGET_POWER)
6520 fixed_regs[64] = 1;
6522 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6523 if (TARGET_64BIT)
6524 fixed_regs[13] = call_used_regs[13]
6525 = call_really_used_regs[13] = 1;
6527 /* Conditionally disable FPRs. */
6528 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6529 for (i = 32; i < 64; i++)
6530 fixed_regs[i] = call_used_regs[i]
6531 = call_really_used_regs[i] = 1;
6533 /* The TOC register is not killed across calls in a way that is
6534 visible to the compiler. */
6535 if (DEFAULT_ABI == ABI_AIX)
6536 call_really_used_regs[2] = 0;
6538 if (DEFAULT_ABI == ABI_V4
6539 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6540 && flag_pic == 2)
6541 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6543 if (DEFAULT_ABI == ABI_V4
6544 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6545 && flag_pic == 1)
6546 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6547 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6548 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6550 if (DEFAULT_ABI == ABI_DARWIN
6551 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6552 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6553 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6554 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6556 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6557 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6558 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6560 if (TARGET_SPE)
6562 global_regs[SPEFSCR_REGNO] = 1;
6563 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6564 registers in prologues and epilogues. We no longer use r14
6565 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6566 pool for link-compatibility with older versions of GCC. Once
6567 "old" code has died out, we can return r14 to the allocation
6568 pool. */
6569 fixed_regs[14]
6570 = call_used_regs[14]
6571 = call_really_used_regs[14] = 1;
6574 if (!TARGET_ALTIVEC && !TARGET_VSX)
6576 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6577 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6578 call_really_used_regs[VRSAVE_REGNO] = 1;
6581 if (TARGET_ALTIVEC || TARGET_VSX)
6582 global_regs[VSCR_REGNO] = 1;
6584 if (TARGET_ALTIVEC_ABI)
6586 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6587 call_used_regs[i] = call_really_used_regs[i] = 1;
6589 /* AIX reserves VR20:31 in non-extended ABI mode. */
6590 if (TARGET_XCOFF)
6591 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6592 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6596 /* Try to output insns to set TARGET equal to the constant C if it can
6597 be done in less than N insns. Do all computations in MODE.
6598 Returns the place where the output has been placed if it can be
6599 done and the insns have been emitted. If it would take more than N
6600 insns, zero is returned and no insns and emitted. */
6603 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6604 rtx source, int n ATTRIBUTE_UNUSED)
6606 rtx result, insn, set;
6607 HOST_WIDE_INT c0, c1;
6609 switch (mode)
6611 case QImode:
6612 case HImode:
6613 if (dest == NULL)
6614 dest = gen_reg_rtx (mode);
6615 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6616 return dest;
6618 case SImode:
6619 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6621 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6622 GEN_INT (INTVAL (source)
6623 & (~ (HOST_WIDE_INT) 0xffff))));
6624 emit_insn (gen_rtx_SET (VOIDmode, dest,
6625 gen_rtx_IOR (SImode, copy_rtx (result),
6626 GEN_INT (INTVAL (source) & 0xffff))));
6627 result = dest;
6628 break;
6630 case DImode:
6631 switch (GET_CODE (source))
6633 case CONST_INT:
6634 c0 = INTVAL (source);
6635 c1 = -(c0 < 0);
6636 break;
6638 case CONST_DOUBLE:
6639 #if HOST_BITS_PER_WIDE_INT >= 64
6640 c0 = CONST_DOUBLE_LOW (source);
6641 c1 = -(c0 < 0);
6642 #else
6643 c0 = CONST_DOUBLE_LOW (source);
6644 c1 = CONST_DOUBLE_HIGH (source);
6645 #endif
6646 break;
6648 default:
6649 gcc_unreachable ();
6652 result = rs6000_emit_set_long_const (dest, c0, c1);
6653 break;
6655 default:
6656 gcc_unreachable ();
6659 insn = get_last_insn ();
6660 set = single_set (insn);
6661 if (! CONSTANT_P (SET_SRC (set)))
6662 set_unique_reg_note (insn, REG_EQUAL, source);
6664 return result;
6667 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6668 fall back to a straight forward decomposition. We do this to avoid
6669 exponential run times encountered when looking for longer sequences
6670 with rs6000_emit_set_const. */
6671 static rtx
6672 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6674 if (!TARGET_POWERPC64)
6676 rtx operand1, operand2;
6678 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6679 DImode);
6680 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6681 DImode);
6682 emit_move_insn (operand1, GEN_INT (c1));
6683 emit_move_insn (operand2, GEN_INT (c2));
6685 else
6687 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6689 ud1 = c1 & 0xffff;
6690 ud2 = (c1 & 0xffff0000) >> 16;
6691 #if HOST_BITS_PER_WIDE_INT >= 64
6692 c2 = c1 >> 32;
6693 #endif
6694 ud3 = c2 & 0xffff;
6695 ud4 = (c2 & 0xffff0000) >> 16;
6697 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6698 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6700 if (ud1 & 0x8000)
6701 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6702 else
6703 emit_move_insn (dest, GEN_INT (ud1));
6706 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6707 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6709 if (ud2 & 0x8000)
6710 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6711 - 0x80000000));
6712 else
6713 emit_move_insn (dest, GEN_INT (ud2 << 16));
6714 if (ud1 != 0)
6715 emit_move_insn (copy_rtx (dest),
6716 gen_rtx_IOR (DImode, copy_rtx (dest),
6717 GEN_INT (ud1)));
6719 else if (ud3 == 0 && ud4 == 0)
6721 gcc_assert (ud2 & 0x8000);
6722 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6723 - 0x80000000));
6724 if (ud1 != 0)
6725 emit_move_insn (copy_rtx (dest),
6726 gen_rtx_IOR (DImode, copy_rtx (dest),
6727 GEN_INT (ud1)));
6728 emit_move_insn (copy_rtx (dest),
6729 gen_rtx_ZERO_EXTEND (DImode,
6730 gen_lowpart (SImode,
6731 copy_rtx (dest))));
6733 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6734 || (ud4 == 0 && ! (ud3 & 0x8000)))
6736 if (ud3 & 0x8000)
6737 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6738 - 0x80000000));
6739 else
6740 emit_move_insn (dest, GEN_INT (ud3 << 16));
6742 if (ud2 != 0)
6743 emit_move_insn (copy_rtx (dest),
6744 gen_rtx_IOR (DImode, copy_rtx (dest),
6745 GEN_INT (ud2)));
6746 emit_move_insn (copy_rtx (dest),
6747 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6748 GEN_INT (16)));
6749 if (ud1 != 0)
6750 emit_move_insn (copy_rtx (dest),
6751 gen_rtx_IOR (DImode, copy_rtx (dest),
6752 GEN_INT (ud1)));
6754 else
6756 if (ud4 & 0x8000)
6757 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6758 - 0x80000000));
6759 else
6760 emit_move_insn (dest, GEN_INT (ud4 << 16));
6762 if (ud3 != 0)
6763 emit_move_insn (copy_rtx (dest),
6764 gen_rtx_IOR (DImode, copy_rtx (dest),
6765 GEN_INT (ud3)));
6767 emit_move_insn (copy_rtx (dest),
6768 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6769 GEN_INT (32)));
6770 if (ud2 != 0)
6771 emit_move_insn (copy_rtx (dest),
6772 gen_rtx_IOR (DImode, copy_rtx (dest),
6773 GEN_INT (ud2 << 16)));
6774 if (ud1 != 0)
6775 emit_move_insn (copy_rtx (dest),
6776 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6779 return dest;
6782 /* Helper for the following. Get rid of [r+r] memory refs
6783 in cases where it won't work (TImode, TFmode, TDmode). */
6785 static void
6786 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6788 if (reload_in_progress)
6789 return;
6791 if (GET_CODE (operands[0]) == MEM
6792 && GET_CODE (XEXP (operands[0], 0)) != REG
6793 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
6794 GET_MODE (operands[0]), false))
6795 operands[0]
6796 = replace_equiv_address (operands[0],
6797 copy_addr_to_reg (XEXP (operands[0], 0)));
6799 if (GET_CODE (operands[1]) == MEM
6800 && GET_CODE (XEXP (operands[1], 0)) != REG
6801 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
6802 GET_MODE (operands[1]), false))
6803 operands[1]
6804 = replace_equiv_address (operands[1],
6805 copy_addr_to_reg (XEXP (operands[1], 0)));
6808 /* Emit a move from SOURCE to DEST in mode MODE. */
6809 void
6810 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6812 rtx operands[2];
6813 operands[0] = dest;
6814 operands[1] = source;
6816 if (TARGET_DEBUG_ADDR)
6818 fprintf (stderr,
6819 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6820 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6821 GET_MODE_NAME (mode),
6822 reload_in_progress,
6823 reload_completed,
6824 can_create_pseudo_p ());
6825 debug_rtx (dest);
6826 fprintf (stderr, "source:\n");
6827 debug_rtx (source);
6830 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6831 if (GET_CODE (operands[1]) == CONST_DOUBLE
6832 && ! FLOAT_MODE_P (mode)
6833 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6835 /* FIXME. This should never happen. */
6836 /* Since it seems that it does, do the safe thing and convert
6837 to a CONST_INT. */
6838 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6840 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6841 || FLOAT_MODE_P (mode)
6842 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6843 || CONST_DOUBLE_LOW (operands[1]) < 0)
6844 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6845 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6847 /* Check if GCC is setting up a block move that will end up using FP
6848 registers as temporaries. We must make sure this is acceptable. */
6849 if (GET_CODE (operands[0]) == MEM
6850 && GET_CODE (operands[1]) == MEM
6851 && mode == DImode
6852 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6853 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6854 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6855 ? 32 : MEM_ALIGN (operands[0])))
6856 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6857 ? 32
6858 : MEM_ALIGN (operands[1]))))
6859 && ! MEM_VOLATILE_P (operands [0])
6860 && ! MEM_VOLATILE_P (operands [1]))
6862 emit_move_insn (adjust_address (operands[0], SImode, 0),
6863 adjust_address (operands[1], SImode, 0));
6864 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6865 adjust_address (copy_rtx (operands[1]), SImode, 4));
6866 return;
6869 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6870 && !gpc_reg_operand (operands[1], mode))
6871 operands[1] = force_reg (mode, operands[1]);
6873 if (mode == SFmode && ! TARGET_POWERPC
6874 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6875 && GET_CODE (operands[0]) == MEM)
6877 int regnum;
6879 if (reload_in_progress || reload_completed)
6880 regnum = true_regnum (operands[1]);
6881 else if (GET_CODE (operands[1]) == REG)
6882 regnum = REGNO (operands[1]);
6883 else
6884 regnum = -1;
6886 /* If operands[1] is a register, on POWER it may have
6887 double-precision data in it, so truncate it to single
6888 precision. */
6889 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6891 rtx newreg;
6892 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6893 : gen_reg_rtx (mode));
6894 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6895 operands[1] = newreg;
6899 /* Recognize the case where operand[1] is a reference to thread-local
6900 data and load its address to a register. */
6901 if (rs6000_tls_referenced_p (operands[1]))
6903 enum tls_model model;
6904 rtx tmp = operands[1];
6905 rtx addend = NULL;
6907 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6909 addend = XEXP (XEXP (tmp, 0), 1);
6910 tmp = XEXP (XEXP (tmp, 0), 0);
6913 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6914 model = SYMBOL_REF_TLS_MODEL (tmp);
6915 gcc_assert (model != 0);
6917 tmp = rs6000_legitimize_tls_address (tmp, model);
6918 if (addend)
6920 tmp = gen_rtx_PLUS (mode, tmp, addend);
6921 tmp = force_operand (tmp, operands[0]);
6923 operands[1] = tmp;
6926 /* Handle the case where reload calls us with an invalid address. */
6927 if (reload_in_progress && mode == Pmode
6928 && (! general_operand (operands[1], mode)
6929 || ! nonimmediate_operand (operands[0], mode)))
6930 goto emit_set;
6932 /* 128-bit constant floating-point values on Darwin should really be
6933 loaded as two parts. */
6934 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6935 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6937 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6938 know how to get a DFmode SUBREG of a TFmode. */
6939 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6940 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6941 simplify_gen_subreg (imode, operands[1], mode, 0),
6942 imode);
6943 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6944 GET_MODE_SIZE (imode)),
6945 simplify_gen_subreg (imode, operands[1], mode,
6946 GET_MODE_SIZE (imode)),
6947 imode);
6948 return;
6951 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6952 cfun->machine->sdmode_stack_slot =
6953 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6955 if (reload_in_progress
6956 && mode == SDmode
6957 && MEM_P (operands[0])
6958 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6959 && REG_P (operands[1]))
6961 if (FP_REGNO_P (REGNO (operands[1])))
6963 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6964 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6965 emit_insn (gen_movsd_store (mem, operands[1]));
6967 else if (INT_REGNO_P (REGNO (operands[1])))
6969 rtx mem = adjust_address_nv (operands[0], mode, 4);
6970 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6971 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6973 else
6974 gcc_unreachable();
6975 return;
6977 if (reload_in_progress
6978 && mode == SDmode
6979 && REG_P (operands[0])
6980 && MEM_P (operands[1])
6981 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6983 if (FP_REGNO_P (REGNO (operands[0])))
6985 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6986 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6987 emit_insn (gen_movsd_load (operands[0], mem));
6989 else if (INT_REGNO_P (REGNO (operands[0])))
6991 rtx mem = adjust_address_nv (operands[1], mode, 4);
6992 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6993 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6995 else
6996 gcc_unreachable();
6997 return;
7000 /* FIXME: In the long term, this switch statement should go away
7001 and be replaced by a sequence of tests based on things like
7002 mode == Pmode. */
7003 switch (mode)
7005 case HImode:
7006 case QImode:
7007 if (CONSTANT_P (operands[1])
7008 && GET_CODE (operands[1]) != CONST_INT)
7009 operands[1] = force_const_mem (mode, operands[1]);
7010 break;
7012 case TFmode:
7013 case TDmode:
7014 rs6000_eliminate_indexed_memrefs (operands);
7015 /* fall through */
7017 case DFmode:
7018 case DDmode:
7019 case SFmode:
7020 case SDmode:
7021 if (CONSTANT_P (operands[1])
7022 && ! easy_fp_constant (operands[1], mode))
7023 operands[1] = force_const_mem (mode, operands[1]);
7024 break;
7026 case V16QImode:
7027 case V8HImode:
7028 case V4SFmode:
7029 case V4SImode:
7030 case V4HImode:
7031 case V2SFmode:
7032 case V2SImode:
7033 case V1DImode:
7034 case V2DFmode:
7035 case V2DImode:
7036 if (CONSTANT_P (operands[1])
7037 && !easy_vector_constant (operands[1], mode))
7038 operands[1] = force_const_mem (mode, operands[1]);
7039 break;
7041 case SImode:
7042 case DImode:
7043 /* Use default pattern for address of ELF small data */
7044 if (TARGET_ELF
7045 && mode == Pmode
7046 && DEFAULT_ABI == ABI_V4
7047 && (GET_CODE (operands[1]) == SYMBOL_REF
7048 || GET_CODE (operands[1]) == CONST)
7049 && small_data_operand (operands[1], mode))
7051 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7052 return;
7055 if (DEFAULT_ABI == ABI_V4
7056 && mode == Pmode && mode == SImode
7057 && flag_pic == 1 && got_operand (operands[1], mode))
7059 emit_insn (gen_movsi_got (operands[0], operands[1]));
7060 return;
7063 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7064 && TARGET_NO_TOC
7065 && ! flag_pic
7066 && mode == Pmode
7067 && CONSTANT_P (operands[1])
7068 && GET_CODE (operands[1]) != HIGH
7069 && GET_CODE (operands[1]) != CONST_INT)
7071 rtx target = (!can_create_pseudo_p ()
7072 ? operands[0]
7073 : gen_reg_rtx (mode));
7075 /* If this is a function address on -mcall-aixdesc,
7076 convert it to the address of the descriptor. */
7077 if (DEFAULT_ABI == ABI_AIX
7078 && GET_CODE (operands[1]) == SYMBOL_REF
7079 && XSTR (operands[1], 0)[0] == '.')
7081 const char *name = XSTR (operands[1], 0);
7082 rtx new_ref;
7083 while (*name == '.')
7084 name++;
7085 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7086 CONSTANT_POOL_ADDRESS_P (new_ref)
7087 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7088 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7089 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7090 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7091 operands[1] = new_ref;
7094 if (DEFAULT_ABI == ABI_DARWIN)
7096 #if TARGET_MACHO
7097 if (MACHO_DYNAMIC_NO_PIC_P)
7099 /* Take care of any required data indirection. */
7100 operands[1] = rs6000_machopic_legitimize_pic_address (
7101 operands[1], mode, operands[0]);
7102 if (operands[0] != operands[1])
7103 emit_insn (gen_rtx_SET (VOIDmode,
7104 operands[0], operands[1]));
7105 return;
7107 #endif
7108 emit_insn (gen_macho_high (target, operands[1]));
7109 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7110 return;
7113 emit_insn (gen_elf_high (target, operands[1]));
7114 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7115 return;
7118 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7119 and we have put it in the TOC, we just need to make a TOC-relative
7120 reference to it. */
7121 if ((TARGET_TOC
7122 && GET_CODE (operands[1]) == SYMBOL_REF
7123 && constant_pool_expr_p (operands[1])
7124 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7125 get_pool_mode (operands[1])))
7126 || (TARGET_CMODEL == CMODEL_MEDIUM
7127 && GET_CODE (operands[1]) == SYMBOL_REF
7128 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7129 && SYMBOL_REF_LOCAL_P (operands[1])))
7131 rtx reg = NULL_RTX;
7132 if (TARGET_CMODEL != CMODEL_SMALL)
7134 if (can_create_pseudo_p ())
7135 reg = gen_reg_rtx (Pmode);
7136 else
7137 reg = operands[0];
7139 operands[1] = create_TOC_reference (operands[1], reg);
7141 else if (mode == Pmode
7142 && CONSTANT_P (operands[1])
7143 && GET_CODE (operands[1]) != HIGH
7144 && !(TARGET_CMODEL != CMODEL_SMALL
7145 && GET_CODE (operands[1]) == CONST
7146 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7147 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH)
7148 && ((GET_CODE (operands[1]) != CONST_INT
7149 && ! easy_fp_constant (operands[1], mode))
7150 || (GET_CODE (operands[1]) == CONST_INT
7151 && (num_insns_constant (operands[1], mode)
7152 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7153 || (GET_CODE (operands[0]) == REG
7154 && FP_REGNO_P (REGNO (operands[0]))))
7155 && ! legitimate_constant_pool_address_p (operands[1], mode,
7156 false)
7157 && ! toc_relative_expr_p (operands[1])
7158 && (TARGET_CMODEL == CMODEL_SMALL
7159 || can_create_pseudo_p ()
7160 || (REG_P (operands[0])
7161 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7164 #if TARGET_MACHO
7165 /* Darwin uses a special PIC legitimizer. */
7166 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7168 operands[1] =
7169 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7170 operands[0]);
7171 if (operands[0] != operands[1])
7172 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7173 return;
7175 #endif
7177 /* If we are to limit the number of things we put in the TOC and
7178 this is a symbol plus a constant we can add in one insn,
7179 just put the symbol in the TOC and add the constant. Don't do
7180 this if reload is in progress. */
7181 if (GET_CODE (operands[1]) == CONST
7182 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7183 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7184 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7185 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7186 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7187 && ! side_effects_p (operands[0]))
7189 rtx sym =
7190 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7191 rtx other = XEXP (XEXP (operands[1], 0), 1);
7193 sym = force_reg (mode, sym);
7194 emit_insn (gen_add3_insn (operands[0], sym, other));
7195 return;
7198 operands[1] = force_const_mem (mode, operands[1]);
7200 if (TARGET_TOC
7201 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7202 && constant_pool_expr_p (XEXP (operands[1], 0))
7203 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7204 get_pool_constant (XEXP (operands[1], 0)),
7205 get_pool_mode (XEXP (operands[1], 0))))
7207 rtx tocref;
7208 rtx reg = NULL_RTX;
7209 if (TARGET_CMODEL != CMODEL_SMALL)
7211 if (can_create_pseudo_p ())
7212 reg = gen_reg_rtx (Pmode);
7213 else
7214 reg = operands[0];
7216 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7217 operands[1] = gen_const_mem (mode, tocref);
7218 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7221 break;
7223 case TImode:
7224 rs6000_eliminate_indexed_memrefs (operands);
7226 if (TARGET_POWER)
7228 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7229 gen_rtvec (2,
7230 gen_rtx_SET (VOIDmode,
7231 operands[0], operands[1]),
7232 gen_rtx_CLOBBER (VOIDmode,
7233 gen_rtx_SCRATCH (SImode)))));
7234 return;
7236 break;
7238 default:
7239 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7242 /* Above, we may have called force_const_mem which may have returned
7243 an invalid address. If we can, fix this up; otherwise, reload will
7244 have to deal with it. */
7245 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7246 operands[1] = validize_mem (operands[1]);
7248 emit_set:
7249 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7252 /* Nonzero if we can use a floating-point register to pass this arg. */
7253 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7254 (SCALAR_FLOAT_MODE_P (MODE) \
7255 && (CUM)->fregno <= FP_ARG_MAX_REG \
7256 && TARGET_HARD_FLOAT && TARGET_FPRS)
7258 /* Nonzero if we can use an AltiVec register to pass this arg. */
7259 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7260 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7261 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7262 && TARGET_ALTIVEC_ABI \
7263 && (NAMED))
7265 /* Return a nonzero value to say to return the function value in
7266 memory, just as large structures are always returned. TYPE will be
7267 the data type of the value, and FNTYPE will be the type of the
7268 function doing the returning, or @code{NULL} for libcalls.
7270 The AIX ABI for the RS/6000 specifies that all structures are
7271 returned in memory. The Darwin ABI does the same.
7273 For the Darwin 64 Bit ABI, a function result can be returned in
7274 registers or in memory, depending on the size of the return data
7275 type. If it is returned in registers, the value occupies the same
7276 registers as it would if it were the first and only function
7277 argument. Otherwise, the function places its result in memory at
7278 the location pointed to by GPR3.
7280 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7281 but a draft put them in memory, and GCC used to implement the draft
7282 instead of the final standard. Therefore, aix_struct_return
7283 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7284 compatibility can change DRAFT_V4_STRUCT_RET to override the
7285 default, and -m switches get the final word. See
7286 rs6000_option_override_internal for more details.
7288 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7289 long double support is enabled. These values are returned in memory.
7291 int_size_in_bytes returns -1 for variable size objects, which go in
7292 memory always. The cast to unsigned makes -1 > 8. */
7294 static bool
7295 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7297 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7298 if (TARGET_MACHO
7299 && rs6000_darwin64_abi
7300 && TREE_CODE (type) == RECORD_TYPE
7301 && int_size_in_bytes (type) > 0)
7303 CUMULATIVE_ARGS valcum;
7304 rtx valret;
7306 valcum.words = 0;
7307 valcum.fregno = FP_ARG_MIN_REG;
7308 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7309 /* Do a trial code generation as if this were going to be passed
7310 as an argument; if any part goes in memory, we return NULL. */
7311 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7312 if (valret)
7313 return false;
7314 /* Otherwise fall through to more conventional ABI rules. */
7317 if (AGGREGATE_TYPE_P (type)
7318 && (aix_struct_return
7319 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7320 return true;
7322 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7323 modes only exist for GCC vector types if -maltivec. */
7324 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7325 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7326 return false;
7328 /* Return synthetic vectors in memory. */
7329 if (TREE_CODE (type) == VECTOR_TYPE
7330 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7332 static bool warned_for_return_big_vectors = false;
7333 if (!warned_for_return_big_vectors)
7335 warning (0, "GCC vector returned by reference: "
7336 "non-standard ABI extension with no compatibility guarantee");
7337 warned_for_return_big_vectors = true;
7339 return true;
7342 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7343 return true;
7345 return false;
7348 #ifdef HAVE_AS_GNU_ATTRIBUTE
7349 /* Return TRUE if a call to function FNDECL may be one that
7350 potentially affects the function calling ABI of the object file. */
7352 static bool
7353 call_ABI_of_interest (tree fndecl)
7355 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7357 struct cgraph_node *c_node;
7359 /* Libcalls are always interesting. */
7360 if (fndecl == NULL_TREE)
7361 return true;
7363 /* Any call to an external function is interesting. */
7364 if (DECL_EXTERNAL (fndecl))
7365 return true;
7367 /* Interesting functions that we are emitting in this object file. */
7368 c_node = cgraph_get_node (fndecl);
7369 c_node = cgraph_function_or_thunk_node (c_node, NULL);
7370 return !cgraph_only_called_directly_p (c_node);
7372 return false;
7374 #endif
7376 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7377 for a call to a function whose data type is FNTYPE.
7378 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7380 For incoming args we set the number of arguments in the prototype large
7381 so we never return a PARALLEL. */
7383 void
7384 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7385 rtx libname ATTRIBUTE_UNUSED, int incoming,
7386 int libcall, int n_named_args,
7387 tree fndecl ATTRIBUTE_UNUSED,
7388 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7390 static CUMULATIVE_ARGS zero_cumulative;
7392 *cum = zero_cumulative;
7393 cum->words = 0;
7394 cum->fregno = FP_ARG_MIN_REG;
7395 cum->vregno = ALTIVEC_ARG_MIN_REG;
7396 cum->prototype = (fntype && prototype_p (fntype));
7397 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7398 ? CALL_LIBCALL : CALL_NORMAL);
7399 cum->sysv_gregno = GP_ARG_MIN_REG;
7400 cum->stdarg = stdarg_p (fntype);
7402 cum->nargs_prototype = 0;
7403 if (incoming || cum->prototype)
7404 cum->nargs_prototype = n_named_args;
7406 /* Check for a longcall attribute. */
7407 if ((!fntype && rs6000_default_long_calls)
7408 || (fntype
7409 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7410 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7411 cum->call_cookie |= CALL_LONG;
7413 if (TARGET_DEBUG_ARG)
7415 fprintf (stderr, "\ninit_cumulative_args:");
7416 if (fntype)
7418 tree ret_type = TREE_TYPE (fntype);
7419 fprintf (stderr, " ret code = %s,",
7420 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7423 if (cum->call_cookie & CALL_LONG)
7424 fprintf (stderr, " longcall,");
7426 fprintf (stderr, " proto = %d, nargs = %d\n",
7427 cum->prototype, cum->nargs_prototype);
7430 #ifdef HAVE_AS_GNU_ATTRIBUTE
7431 if (DEFAULT_ABI == ABI_V4)
7433 cum->escapes = call_ABI_of_interest (fndecl);
7434 if (cum->escapes)
7436 tree return_type;
7438 if (fntype)
7440 return_type = TREE_TYPE (fntype);
7441 return_mode = TYPE_MODE (return_type);
7443 else
7444 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
7446 if (return_type != NULL)
7448 if (TREE_CODE (return_type) == RECORD_TYPE
7449 && TYPE_TRANSPARENT_AGGR (return_type))
7451 return_type = TREE_TYPE (first_field (return_type));
7452 return_mode = TYPE_MODE (return_type);
7454 if (AGGREGATE_TYPE_P (return_type)
7455 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
7456 <= 8))
7457 rs6000_returns_struct = true;
7459 if (SCALAR_FLOAT_MODE_P (return_mode))
7460 rs6000_passes_float = true;
7461 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
7462 || SPE_VECTOR_MODE (return_mode))
7463 rs6000_passes_vector = true;
7466 #endif
7468 if (fntype
7469 && !TARGET_ALTIVEC
7470 && TARGET_ALTIVEC_ABI
7471 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7473 error ("cannot return value in vector register because"
7474 " altivec instructions are disabled, use -maltivec"
7475 " to enable them");
7479 /* Return true if TYPE must be passed on the stack and not in registers. */
7481 static bool
7482 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7484 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7485 return must_pass_in_stack_var_size (mode, type);
7486 else
7487 return must_pass_in_stack_var_size_or_pad (mode, type);
7490 /* If defined, a C expression which determines whether, and in which
7491 direction, to pad out an argument with extra space. The value
7492 should be of type `enum direction': either `upward' to pad above
7493 the argument, `downward' to pad below, or `none' to inhibit
7494 padding.
7496 For the AIX ABI structs are always stored left shifted in their
7497 argument slot. */
7499 enum direction
7500 function_arg_padding (enum machine_mode mode, const_tree type)
7502 #ifndef AGGREGATE_PADDING_FIXED
7503 #define AGGREGATE_PADDING_FIXED 0
7504 #endif
7505 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7506 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7507 #endif
7509 if (!AGGREGATE_PADDING_FIXED)
7511 /* GCC used to pass structures of the same size as integer types as
7512 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7513 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7514 passed padded downward, except that -mstrict-align further
7515 muddied the water in that multi-component structures of 2 and 4
7516 bytes in size were passed padded upward.
7518 The following arranges for best compatibility with previous
7519 versions of gcc, but removes the -mstrict-align dependency. */
7520 if (BYTES_BIG_ENDIAN)
7522 HOST_WIDE_INT size = 0;
7524 if (mode == BLKmode)
7526 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7527 size = int_size_in_bytes (type);
7529 else
7530 size = GET_MODE_SIZE (mode);
7532 if (size == 1 || size == 2 || size == 4)
7533 return downward;
7535 return upward;
7538 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7540 if (type != 0 && AGGREGATE_TYPE_P (type))
7541 return upward;
7544 /* Fall back to the default. */
7545 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7548 /* If defined, a C expression that gives the alignment boundary, in bits,
7549 of an argument with the specified mode and type. If it is not defined,
7550 PARM_BOUNDARY is used for all arguments.
7552 V.4 wants long longs and doubles to be double word aligned. Just
7553 testing the mode size is a boneheaded way to do this as it means
7554 that other types such as complex int are also double word aligned.
7555 However, we're stuck with this because changing the ABI might break
7556 existing library interfaces.
7558 Doubleword align SPE vectors.
7559 Quadword align Altivec/VSX vectors.
7560 Quadword align large synthetic vector types. */
7562 static unsigned int
7563 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
7565 if (DEFAULT_ABI == ABI_V4
7566 && (GET_MODE_SIZE (mode) == 8
7567 || (TARGET_HARD_FLOAT
7568 && TARGET_FPRS
7569 && (mode == TFmode || mode == TDmode))))
7570 return 64;
7571 else if (SPE_VECTOR_MODE (mode)
7572 || (type && TREE_CODE (type) == VECTOR_TYPE
7573 && int_size_in_bytes (type) >= 8
7574 && int_size_in_bytes (type) < 16))
7575 return 64;
7576 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7577 || (type && TREE_CODE (type) == VECTOR_TYPE
7578 && int_size_in_bytes (type) >= 16))
7579 return 128;
7580 else if (TARGET_MACHO
7581 && rs6000_darwin64_abi
7582 && mode == BLKmode
7583 && type && TYPE_ALIGN (type) > 64)
7584 return 128;
7585 else
7586 return PARM_BOUNDARY;
7589 /* For a function parm of MODE and TYPE, return the starting word in
7590 the parameter area. NWORDS of the parameter area are already used. */
7592 static unsigned int
7593 rs6000_parm_start (enum machine_mode mode, const_tree type,
7594 unsigned int nwords)
7596 unsigned int align;
7597 unsigned int parm_offset;
7599 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7600 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7601 return nwords + (-(parm_offset + nwords) & align);
7604 /* Compute the size (in words) of a function argument. */
7606 static unsigned long
7607 rs6000_arg_size (enum machine_mode mode, const_tree type)
7609 unsigned long size;
7611 if (mode != BLKmode)
7612 size = GET_MODE_SIZE (mode);
7613 else
7614 size = int_size_in_bytes (type);
7616 if (TARGET_32BIT)
7617 return (size + 3) >> 2;
7618 else
7619 return (size + 7) >> 3;
7622 /* Use this to flush pending int fields. */
7624 static void
7625 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7626 HOST_WIDE_INT bitpos, int final)
7628 unsigned int startbit, endbit;
7629 int intregs, intoffset;
7630 enum machine_mode mode;
7632 /* Handle the situations where a float is taking up the first half
7633 of the GPR, and the other half is empty (typically due to
7634 alignment restrictions). We can detect this by a 8-byte-aligned
7635 int field, or by seeing that this is the final flush for this
7636 argument. Count the word and continue on. */
7637 if (cum->floats_in_gpr == 1
7638 && (cum->intoffset % 64 == 0
7639 || (cum->intoffset == -1 && final)))
7641 cum->words++;
7642 cum->floats_in_gpr = 0;
7645 if (cum->intoffset == -1)
7646 return;
7648 intoffset = cum->intoffset;
7649 cum->intoffset = -1;
7650 cum->floats_in_gpr = 0;
7652 if (intoffset % BITS_PER_WORD != 0)
7654 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7655 MODE_INT, 0);
7656 if (mode == BLKmode)
7658 /* We couldn't find an appropriate mode, which happens,
7659 e.g., in packed structs when there are 3 bytes to load.
7660 Back intoffset back to the beginning of the word in this
7661 case. */
7662 intoffset = intoffset & -BITS_PER_WORD;
7666 startbit = intoffset & -BITS_PER_WORD;
7667 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7668 intregs = (endbit - startbit) / BITS_PER_WORD;
7669 cum->words += intregs;
7670 /* words should be unsigned. */
7671 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7673 int pad = (endbit/BITS_PER_WORD) - cum->words;
7674 cum->words += pad;
7678 /* The darwin64 ABI calls for us to recurse down through structs,
7679 looking for elements passed in registers. Unfortunately, we have
7680 to track int register count here also because of misalignments
7681 in powerpc alignment mode. */
7683 static void
7684 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7685 const_tree type,
7686 HOST_WIDE_INT startbitpos)
7688 tree f;
7690 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7691 if (TREE_CODE (f) == FIELD_DECL)
7693 HOST_WIDE_INT bitpos = startbitpos;
7694 tree ftype = TREE_TYPE (f);
7695 enum machine_mode mode;
7696 if (ftype == error_mark_node)
7697 continue;
7698 mode = TYPE_MODE (ftype);
7700 if (DECL_SIZE (f) != 0
7701 && host_integerp (bit_position (f), 1))
7702 bitpos += int_bit_position (f);
7704 /* ??? FIXME: else assume zero offset. */
7706 if (TREE_CODE (ftype) == RECORD_TYPE)
7707 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7708 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7710 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
7711 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7712 cum->fregno += n_fpregs;
7713 /* Single-precision floats present a special problem for
7714 us, because they are smaller than an 8-byte GPR, and so
7715 the structure-packing rules combined with the standard
7716 varargs behavior mean that we want to pack float/float
7717 and float/int combinations into a single register's
7718 space. This is complicated by the arg advance flushing,
7719 which works on arbitrarily large groups of int-type
7720 fields. */
7721 if (mode == SFmode)
7723 if (cum->floats_in_gpr == 1)
7725 /* Two floats in a word; count the word and reset
7726 the float count. */
7727 cum->words++;
7728 cum->floats_in_gpr = 0;
7730 else if (bitpos % 64 == 0)
7732 /* A float at the beginning of an 8-byte word;
7733 count it and put off adjusting cum->words until
7734 we see if a arg advance flush is going to do it
7735 for us. */
7736 cum->floats_in_gpr++;
7738 else
7740 /* The float is at the end of a word, preceded
7741 by integer fields, so the arg advance flush
7742 just above has already set cum->words and
7743 everything is taken care of. */
7746 else
7747 cum->words += n_fpregs;
7749 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7751 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7752 cum->vregno++;
7753 cum->words += 2;
7755 else if (cum->intoffset == -1)
7756 cum->intoffset = bitpos;
7760 /* Check for an item that needs to be considered specially under the darwin 64
7761 bit ABI. These are record types where the mode is BLK or the structure is
7762 8 bytes in size. */
7763 static int
7764 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7766 return rs6000_darwin64_abi
7767 && ((mode == BLKmode
7768 && TREE_CODE (type) == RECORD_TYPE
7769 && int_size_in_bytes (type) > 0)
7770 || (type && TREE_CODE (type) == RECORD_TYPE
7771 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7774 /* Update the data in CUM to advance over an argument
7775 of mode MODE and data type TYPE.
7776 (TYPE is null for libcalls where that information may not be available.)
7778 Note that for args passed by reference, function_arg will be called
7779 with MODE and TYPE set to that of the pointer to the arg, not the arg
7780 itself. */
7782 static void
7783 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7784 const_tree type, bool named, int depth)
7786 /* Only tick off an argument if we're not recursing. */
7787 if (depth == 0)
7788 cum->nargs_prototype--;
7790 #ifdef HAVE_AS_GNU_ATTRIBUTE
7791 if (DEFAULT_ABI == ABI_V4
7792 && cum->escapes)
7794 if (SCALAR_FLOAT_MODE_P (mode))
7795 rs6000_passes_float = true;
7796 else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
7797 rs6000_passes_vector = true;
7798 else if (SPE_VECTOR_MODE (mode)
7799 && !cum->stdarg
7800 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7801 rs6000_passes_vector = true;
7803 #endif
7805 if (TARGET_ALTIVEC_ABI
7806 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7807 || (type && TREE_CODE (type) == VECTOR_TYPE
7808 && int_size_in_bytes (type) == 16)))
7810 bool stack = false;
7812 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7814 cum->vregno++;
7815 if (!TARGET_ALTIVEC)
7816 error ("cannot pass argument in vector register because"
7817 " altivec instructions are disabled, use -maltivec"
7818 " to enable them");
7820 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7821 even if it is going to be passed in a vector register.
7822 Darwin does the same for variable-argument functions. */
7823 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7824 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7825 stack = true;
7827 else
7828 stack = true;
7830 if (stack)
7832 int align;
7834 /* Vector parameters must be 16-byte aligned. This places
7835 them at 2 mod 4 in terms of words in 32-bit mode, since
7836 the parameter save area starts at offset 24 from the
7837 stack. In 64-bit mode, they just have to start on an
7838 even word, since the parameter save area is 16-byte
7839 aligned. Space for GPRs is reserved even if the argument
7840 will be passed in memory. */
7841 if (TARGET_32BIT)
7842 align = (2 - cum->words) & 3;
7843 else
7844 align = cum->words & 1;
7845 cum->words += align + rs6000_arg_size (mode, type);
7847 if (TARGET_DEBUG_ARG)
7849 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7850 cum->words, align);
7851 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7852 cum->nargs_prototype, cum->prototype,
7853 GET_MODE_NAME (mode));
7857 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7858 && !cum->stdarg
7859 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7860 cum->sysv_gregno++;
7862 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
7864 int size = int_size_in_bytes (type);
7865 /* Variable sized types have size == -1 and are
7866 treated as if consisting entirely of ints.
7867 Pad to 16 byte boundary if needed. */
7868 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7869 && (cum->words % 2) != 0)
7870 cum->words++;
7871 /* For varargs, we can just go up by the size of the struct. */
7872 if (!named)
7873 cum->words += (size + 7) / 8;
7874 else
7876 /* It is tempting to say int register count just goes up by
7877 sizeof(type)/8, but this is wrong in a case such as
7878 { int; double; int; } [powerpc alignment]. We have to
7879 grovel through the fields for these too. */
7880 cum->intoffset = 0;
7881 cum->floats_in_gpr = 0;
7882 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7883 rs6000_darwin64_record_arg_advance_flush (cum,
7884 size * BITS_PER_UNIT, 1);
7886 if (TARGET_DEBUG_ARG)
7888 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
7889 cum->words, TYPE_ALIGN (type), size);
7890 fprintf (stderr,
7891 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7892 cum->nargs_prototype, cum->prototype,
7893 GET_MODE_NAME (mode));
7896 else if (DEFAULT_ABI == ABI_V4)
7898 if (TARGET_HARD_FLOAT && TARGET_FPRS
7899 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7900 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7901 || (mode == TFmode && !TARGET_IEEEQUAD)
7902 || mode == SDmode || mode == DDmode || mode == TDmode))
7904 /* _Decimal128 must use an even/odd register pair. This assumes
7905 that the register number is odd when fregno is odd. */
7906 if (mode == TDmode && (cum->fregno % 2) == 1)
7907 cum->fregno++;
7909 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7910 <= FP_ARG_V4_MAX_REG)
7911 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7912 else
7914 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7915 if (mode == DFmode || mode == TFmode
7916 || mode == DDmode || mode == TDmode)
7917 cum->words += cum->words & 1;
7918 cum->words += rs6000_arg_size (mode, type);
7921 else
7923 int n_words = rs6000_arg_size (mode, type);
7924 int gregno = cum->sysv_gregno;
7926 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7927 (r7,r8) or (r9,r10). As does any other 2 word item such
7928 as complex int due to a historical mistake. */
7929 if (n_words == 2)
7930 gregno += (1 - gregno) & 1;
7932 /* Multi-reg args are not split between registers and stack. */
7933 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7935 /* Long long and SPE vectors are aligned on the stack.
7936 So are other 2 word items such as complex int due to
7937 a historical mistake. */
7938 if (n_words == 2)
7939 cum->words += cum->words & 1;
7940 cum->words += n_words;
7943 /* Note: continuing to accumulate gregno past when we've started
7944 spilling to the stack indicates the fact that we've started
7945 spilling to the stack to expand_builtin_saveregs. */
7946 cum->sysv_gregno = gregno + n_words;
7949 if (TARGET_DEBUG_ARG)
7951 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7952 cum->words, cum->fregno);
7953 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7954 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7955 fprintf (stderr, "mode = %4s, named = %d\n",
7956 GET_MODE_NAME (mode), named);
7959 else
7961 int n_words = rs6000_arg_size (mode, type);
7962 int start_words = cum->words;
7963 int align_words = rs6000_parm_start (mode, type, start_words);
7965 cum->words = align_words + n_words;
7967 if (SCALAR_FLOAT_MODE_P (mode)
7968 && TARGET_HARD_FLOAT && TARGET_FPRS)
7970 /* _Decimal128 must be passed in an even/odd float register pair.
7971 This assumes that the register number is odd when fregno is
7972 odd. */
7973 if (mode == TDmode && (cum->fregno % 2) == 1)
7974 cum->fregno++;
7975 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7978 if (TARGET_DEBUG_ARG)
7980 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7981 cum->words, cum->fregno);
7982 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7983 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7984 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7985 named, align_words - start_words, depth);
7990 static void
7991 rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
7992 const_tree type, bool named)
7994 rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
7998 static rtx
7999 spe_build_register_parallel (enum machine_mode mode, int gregno)
8001 rtx r1, r3, r5, r7;
8003 switch (mode)
8005 case DFmode:
8006 r1 = gen_rtx_REG (DImode, gregno);
8007 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8008 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8010 case DCmode:
8011 case TFmode:
8012 r1 = gen_rtx_REG (DImode, gregno);
8013 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8014 r3 = gen_rtx_REG (DImode, gregno + 2);
8015 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8016 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8018 case TCmode:
8019 r1 = gen_rtx_REG (DImode, gregno);
8020 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8021 r3 = gen_rtx_REG (DImode, gregno + 2);
8022 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8023 r5 = gen_rtx_REG (DImode, gregno + 4);
8024 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8025 r7 = gen_rtx_REG (DImode, gregno + 6);
8026 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8027 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8029 default:
8030 gcc_unreachable ();
8034 /* Determine where to put a SIMD argument on the SPE. */
8035 static rtx
8036 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8037 const_tree type)
8039 int gregno = cum->sysv_gregno;
8041 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8042 are passed and returned in a pair of GPRs for ABI compatibility. */
8043 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8044 || mode == DCmode || mode == TCmode))
8046 int n_words = rs6000_arg_size (mode, type);
8048 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8049 if (mode == DFmode)
8050 gregno += (1 - gregno) & 1;
8052 /* Multi-reg args are not split between registers and stack. */
8053 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8054 return NULL_RTX;
8056 return spe_build_register_parallel (mode, gregno);
8058 if (cum->stdarg)
8060 int n_words = rs6000_arg_size (mode, type);
8062 /* SPE vectors are put in odd registers. */
8063 if (n_words == 2 && (gregno & 1) == 0)
8064 gregno += 1;
8066 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8068 rtx r1, r2;
8069 enum machine_mode m = SImode;
8071 r1 = gen_rtx_REG (m, gregno);
8072 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8073 r2 = gen_rtx_REG (m, gregno + 1);
8074 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8075 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8077 else
8078 return NULL_RTX;
8080 else
8082 if (gregno <= GP_ARG_MAX_REG)
8083 return gen_rtx_REG (mode, gregno);
8084 else
8085 return NULL_RTX;
8089 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8090 structure between cum->intoffset and bitpos to integer registers. */
8092 static void
8093 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8094 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8096 enum machine_mode mode;
8097 unsigned int regno;
8098 unsigned int startbit, endbit;
8099 int this_regno, intregs, intoffset;
8100 rtx reg;
8102 if (cum->intoffset == -1)
8103 return;
8105 intoffset = cum->intoffset;
8106 cum->intoffset = -1;
8108 /* If this is the trailing part of a word, try to only load that
8109 much into the register. Otherwise load the whole register. Note
8110 that in the latter case we may pick up unwanted bits. It's not a
8111 problem at the moment but may wish to revisit. */
8113 if (intoffset % BITS_PER_WORD != 0)
8115 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8116 MODE_INT, 0);
8117 if (mode == BLKmode)
8119 /* We couldn't find an appropriate mode, which happens,
8120 e.g., in packed structs when there are 3 bytes to load.
8121 Back intoffset back to the beginning of the word in this
8122 case. */
8123 intoffset = intoffset & -BITS_PER_WORD;
8124 mode = word_mode;
8127 else
8128 mode = word_mode;
8130 startbit = intoffset & -BITS_PER_WORD;
8131 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8132 intregs = (endbit - startbit) / BITS_PER_WORD;
8133 this_regno = cum->words + intoffset / BITS_PER_WORD;
8135 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8136 cum->use_stack = 1;
8138 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8139 if (intregs <= 0)
8140 return;
8142 intoffset /= BITS_PER_UNIT;
8145 regno = GP_ARG_MIN_REG + this_regno;
8146 reg = gen_rtx_REG (mode, regno);
8147 rvec[(*k)++] =
8148 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8150 this_regno += 1;
8151 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8152 mode = word_mode;
8153 intregs -= 1;
8155 while (intregs > 0);
8158 /* Recursive workhorse for the following. */
8160 static void
8161 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8162 HOST_WIDE_INT startbitpos, rtx rvec[],
8163 int *k)
8165 tree f;
8167 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8168 if (TREE_CODE (f) == FIELD_DECL)
8170 HOST_WIDE_INT bitpos = startbitpos;
8171 tree ftype = TREE_TYPE (f);
8172 enum machine_mode mode;
8173 if (ftype == error_mark_node)
8174 continue;
8175 mode = TYPE_MODE (ftype);
8177 if (DECL_SIZE (f) != 0
8178 && host_integerp (bit_position (f), 1))
8179 bitpos += int_bit_position (f);
8181 /* ??? FIXME: else assume zero offset. */
8183 if (TREE_CODE (ftype) == RECORD_TYPE)
8184 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8185 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8187 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8188 #if 0
8189 switch (mode)
8191 case SCmode: mode = SFmode; break;
8192 case DCmode: mode = DFmode; break;
8193 case TCmode: mode = TFmode; break;
8194 default: break;
8196 #endif
8197 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8198 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8200 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8201 && (mode == TFmode || mode == TDmode));
8202 /* Long double or _Decimal128 split over regs and memory. */
8203 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8204 cum->use_stack=1;
8206 rvec[(*k)++]
8207 = gen_rtx_EXPR_LIST (VOIDmode,
8208 gen_rtx_REG (mode, cum->fregno++),
8209 GEN_INT (bitpos / BITS_PER_UNIT));
8210 if (mode == TFmode || mode == TDmode)
8211 cum->fregno++;
8213 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8215 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8216 rvec[(*k)++]
8217 = gen_rtx_EXPR_LIST (VOIDmode,
8218 gen_rtx_REG (mode, cum->vregno++),
8219 GEN_INT (bitpos / BITS_PER_UNIT));
8221 else if (cum->intoffset == -1)
8222 cum->intoffset = bitpos;
8226 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8227 the register(s) to be used for each field and subfield of a struct
8228 being passed by value, along with the offset of where the
8229 register's value may be found in the block. FP fields go in FP
8230 register, vector fields go in vector registers, and everything
8231 else goes in int registers, packed as in memory.
8233 This code is also used for function return values. RETVAL indicates
8234 whether this is the case.
8236 Much of this is taken from the SPARC V9 port, which has a similar
8237 calling convention. */
8239 static rtx
8240 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8241 bool named, bool retval)
8243 rtx rvec[FIRST_PSEUDO_REGISTER];
8244 int k = 1, kbase = 1;
8245 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8246 /* This is a copy; modifications are not visible to our caller. */
8247 CUMULATIVE_ARGS copy_cum = *orig_cum;
8248 CUMULATIVE_ARGS *cum = &copy_cum;
8250 /* Pad to 16 byte boundary if needed. */
8251 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8252 && (cum->words % 2) != 0)
8253 cum->words++;
8255 cum->intoffset = 0;
8256 cum->use_stack = 0;
8257 cum->named = named;
8259 /* Put entries into rvec[] for individual FP and vector fields, and
8260 for the chunks of memory that go in int regs. Note we start at
8261 element 1; 0 is reserved for an indication of using memory, and
8262 may or may not be filled in below. */
8263 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8264 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8266 /* If any part of the struct went on the stack put all of it there.
8267 This hack is because the generic code for
8268 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8269 parts of the struct are not at the beginning. */
8270 if (cum->use_stack)
8272 if (retval)
8273 return NULL_RTX; /* doesn't go in registers at all */
8274 kbase = 0;
8275 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8277 if (k > 1 || cum->use_stack)
8278 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8279 else
8280 return NULL_RTX;
8283 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8285 static rtx
8286 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8287 int align_words)
8289 int n_units;
8290 int i, k;
8291 rtx rvec[GP_ARG_NUM_REG + 1];
8293 if (align_words >= GP_ARG_NUM_REG)
8294 return NULL_RTX;
8296 n_units = rs6000_arg_size (mode, type);
8298 /* Optimize the simple case where the arg fits in one gpr, except in
8299 the case of BLKmode due to assign_parms assuming that registers are
8300 BITS_PER_WORD wide. */
8301 if (n_units == 0
8302 || (n_units == 1 && mode != BLKmode))
8303 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8305 k = 0;
8306 if (align_words + n_units > GP_ARG_NUM_REG)
8307 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8308 using a magic NULL_RTX component.
8309 This is not strictly correct. Only some of the arg belongs in
8310 memory, not all of it. However, the normal scheme using
8311 function_arg_partial_nregs can result in unusual subregs, eg.
8312 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8313 store the whole arg to memory is often more efficient than code
8314 to store pieces, and we know that space is available in the right
8315 place for the whole arg. */
8316 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8318 i = 0;
8321 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8322 rtx off = GEN_INT (i++ * 4);
8323 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8325 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8327 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8330 /* Determine where to put an argument to a function.
8331 Value is zero to push the argument on the stack,
8332 or a hard register in which to store the argument.
8334 MODE is the argument's machine mode.
8335 TYPE is the data type of the argument (as a tree).
8336 This is null for libcalls where that information may
8337 not be available.
8338 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8339 the preceding args and about the function being called. It is
8340 not modified in this routine.
8341 NAMED is nonzero if this argument is a named parameter
8342 (otherwise it is an extra parameter matching an ellipsis).
8344 On RS/6000 the first eight words of non-FP are normally in registers
8345 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8346 Under V.4, the first 8 FP args are in registers.
8348 If this is floating-point and no prototype is specified, we use
8349 both an FP and integer register (or possibly FP reg and stack). Library
8350 functions (when CALL_LIBCALL is set) always have the proper types for args,
8351 so we can pass the FP value just in one register. emit_library_function
8352 doesn't support PARALLEL anyway.
8354 Note that for args passed by reference, function_arg will be called
8355 with MODE and TYPE set to that of the pointer to the arg, not the arg
8356 itself. */
8358 static rtx
8359 rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
8360 const_tree type, bool named)
8362 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8363 enum rs6000_abi abi = DEFAULT_ABI;
8365 /* Return a marker to indicate whether CR1 needs to set or clear the
8366 bit that V.4 uses to say fp args were passed in registers.
8367 Assume that we don't need the marker for software floating point,
8368 or compiler generated library calls. */
8369 if (mode == VOIDmode)
8371 if (abi == ABI_V4
8372 && (cum->call_cookie & CALL_LIBCALL) == 0
8373 && (cum->stdarg
8374 || (cum->nargs_prototype < 0
8375 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8377 /* For the SPE, we need to crxor CR6 always. */
8378 if (TARGET_SPE_ABI)
8379 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8380 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8381 return GEN_INT (cum->call_cookie
8382 | ((cum->fregno == FP_ARG_MIN_REG)
8383 ? CALL_V4_SET_FP_ARGS
8384 : CALL_V4_CLEAR_FP_ARGS));
8387 return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
8390 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8392 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8393 if (rslt != NULL_RTX)
8394 return rslt;
8395 /* Else fall through to usual handling. */
8398 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8399 if (TARGET_64BIT && ! cum->prototype)
8401 /* Vector parameters get passed in vector register
8402 and also in GPRs or memory, in absence of prototype. */
8403 int align_words;
8404 rtx slot;
8405 align_words = (cum->words + 1) & ~1;
8407 if (align_words >= GP_ARG_NUM_REG)
8409 slot = NULL_RTX;
8411 else
8413 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8415 return gen_rtx_PARALLEL (mode,
8416 gen_rtvec (2,
8417 gen_rtx_EXPR_LIST (VOIDmode,
8418 slot, const0_rtx),
8419 gen_rtx_EXPR_LIST (VOIDmode,
8420 gen_rtx_REG (mode, cum->vregno),
8421 const0_rtx)));
8423 else
8424 return gen_rtx_REG (mode, cum->vregno);
8425 else if (TARGET_ALTIVEC_ABI
8426 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8427 || (type && TREE_CODE (type) == VECTOR_TYPE
8428 && int_size_in_bytes (type) == 16)))
8430 if (named || abi == ABI_V4)
8431 return NULL_RTX;
8432 else
8434 /* Vector parameters to varargs functions under AIX or Darwin
8435 get passed in memory and possibly also in GPRs. */
8436 int align, align_words, n_words;
8437 enum machine_mode part_mode;
8439 /* Vector parameters must be 16-byte aligned. This places them at
8440 2 mod 4 in terms of words in 32-bit mode, since the parameter
8441 save area starts at offset 24 from the stack. In 64-bit mode,
8442 they just have to start on an even word, since the parameter
8443 save area is 16-byte aligned. */
8444 if (TARGET_32BIT)
8445 align = (2 - cum->words) & 3;
8446 else
8447 align = cum->words & 1;
8448 align_words = cum->words + align;
8450 /* Out of registers? Memory, then. */
8451 if (align_words >= GP_ARG_NUM_REG)
8452 return NULL_RTX;
8454 if (TARGET_32BIT && TARGET_POWERPC64)
8455 return rs6000_mixed_function_arg (mode, type, align_words);
8457 /* The vector value goes in GPRs. Only the part of the
8458 value in GPRs is reported here. */
8459 part_mode = mode;
8460 n_words = rs6000_arg_size (mode, type);
8461 if (align_words + n_words > GP_ARG_NUM_REG)
8462 /* Fortunately, there are only two possibilities, the value
8463 is either wholly in GPRs or half in GPRs and half not. */
8464 part_mode = DImode;
8466 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8469 else if (TARGET_SPE_ABI && TARGET_SPE
8470 && (SPE_VECTOR_MODE (mode)
8471 || (TARGET_E500_DOUBLE && (mode == DFmode
8472 || mode == DCmode
8473 || mode == TFmode
8474 || mode == TCmode))))
8475 return rs6000_spe_function_arg (cum, mode, type);
8477 else if (abi == ABI_V4)
8479 if (TARGET_HARD_FLOAT && TARGET_FPRS
8480 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8481 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8482 || (mode == TFmode && !TARGET_IEEEQUAD)
8483 || mode == SDmode || mode == DDmode || mode == TDmode))
8485 /* _Decimal128 must use an even/odd register pair. This assumes
8486 that the register number is odd when fregno is odd. */
8487 if (mode == TDmode && (cum->fregno % 2) == 1)
8488 cum->fregno++;
8490 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8491 <= FP_ARG_V4_MAX_REG)
8492 return gen_rtx_REG (mode, cum->fregno);
8493 else
8494 return NULL_RTX;
8496 else
8498 int n_words = rs6000_arg_size (mode, type);
8499 int gregno = cum->sysv_gregno;
8501 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8502 (r7,r8) or (r9,r10). As does any other 2 word item such
8503 as complex int due to a historical mistake. */
8504 if (n_words == 2)
8505 gregno += (1 - gregno) & 1;
8507 /* Multi-reg args are not split between registers and stack. */
8508 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8509 return NULL_RTX;
8511 if (TARGET_32BIT && TARGET_POWERPC64)
8512 return rs6000_mixed_function_arg (mode, type,
8513 gregno - GP_ARG_MIN_REG);
8514 return gen_rtx_REG (mode, gregno);
8517 else
8519 int align_words = rs6000_parm_start (mode, type, cum->words);
8521 /* _Decimal128 must be passed in an even/odd float register pair.
8522 This assumes that the register number is odd when fregno is odd. */
8523 if (mode == TDmode && (cum->fregno % 2) == 1)
8524 cum->fregno++;
8526 if (USE_FP_FOR_ARG_P (cum, mode, type))
8528 rtx rvec[GP_ARG_NUM_REG + 1];
8529 rtx r;
8530 int k;
8531 bool needs_psave;
8532 enum machine_mode fmode = mode;
8533 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8535 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8537 /* Currently, we only ever need one reg here because complex
8538 doubles are split. */
8539 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8540 && (fmode == TFmode || fmode == TDmode));
8542 /* Long double or _Decimal128 split over regs and memory. */
8543 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8546 /* Do we also need to pass this arg in the parameter save
8547 area? */
8548 needs_psave = (type
8549 && (cum->nargs_prototype <= 0
8550 || (DEFAULT_ABI == ABI_AIX
8551 && TARGET_XL_COMPAT
8552 && align_words >= GP_ARG_NUM_REG)));
8554 if (!needs_psave && mode == fmode)
8555 return gen_rtx_REG (fmode, cum->fregno);
8557 k = 0;
8558 if (needs_psave)
8560 /* Describe the part that goes in gprs or the stack.
8561 This piece must come first, before the fprs. */
8562 if (align_words < GP_ARG_NUM_REG)
8564 unsigned long n_words = rs6000_arg_size (mode, type);
8566 if (align_words + n_words > GP_ARG_NUM_REG
8567 || (TARGET_32BIT && TARGET_POWERPC64))
8569 /* If this is partially on the stack, then we only
8570 include the portion actually in registers here. */
8571 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8572 rtx off;
8573 int i = 0;
8574 if (align_words + n_words > GP_ARG_NUM_REG)
8575 /* Not all of the arg fits in gprs. Say that it
8576 goes in memory too, using a magic NULL_RTX
8577 component. Also see comment in
8578 rs6000_mixed_function_arg for why the normal
8579 function_arg_partial_nregs scheme doesn't work
8580 in this case. */
8581 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8582 const0_rtx);
8585 r = gen_rtx_REG (rmode,
8586 GP_ARG_MIN_REG + align_words);
8587 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8588 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8590 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8592 else
8594 /* The whole arg fits in gprs. */
8595 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8596 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8599 else
8600 /* It's entirely in memory. */
8601 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8604 /* Describe where this piece goes in the fprs. */
8605 r = gen_rtx_REG (fmode, cum->fregno);
8606 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8608 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8610 else if (align_words < GP_ARG_NUM_REG)
8612 if (TARGET_32BIT && TARGET_POWERPC64)
8613 return rs6000_mixed_function_arg (mode, type, align_words);
8615 if (mode == BLKmode)
8616 mode = Pmode;
8618 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8620 else
8621 return NULL_RTX;
8625 /* For an arg passed partly in registers and partly in memory, this is
8626 the number of bytes passed in registers. For args passed entirely in
8627 registers or entirely in memory, zero. When an arg is described by a
8628 PARALLEL, perhaps using more than one register type, this function
8629 returns the number of bytes used by the first element of the PARALLEL. */
8631 static int
8632 rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
8633 tree type, bool named)
8635 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
8636 int ret = 0;
8637 int align_words;
8639 if (DEFAULT_ABI == ABI_V4)
8640 return 0;
8642 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8643 && cum->nargs_prototype >= 0)
8644 return 0;
8646 /* In this complicated case we just disable the partial_nregs code. */
8647 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8648 return 0;
8650 align_words = rs6000_parm_start (mode, type, cum->words);
8652 if (USE_FP_FOR_ARG_P (cum, mode, type))
8654 /* If we are passing this arg in the fixed parameter save area
8655 (gprs or memory) as well as fprs, then this function should
8656 return the number of partial bytes passed in the parameter
8657 save area rather than partial bytes passed in fprs. */
8658 if (type
8659 && (cum->nargs_prototype <= 0
8660 || (DEFAULT_ABI == ABI_AIX
8661 && TARGET_XL_COMPAT
8662 && align_words >= GP_ARG_NUM_REG)))
8663 return 0;
8664 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8665 > FP_ARG_MAX_REG + 1)
8666 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8667 else if (cum->nargs_prototype >= 0)
8668 return 0;
8671 if (align_words < GP_ARG_NUM_REG
8672 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8673 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8675 if (ret != 0 && TARGET_DEBUG_ARG)
8676 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8678 return ret;
8681 /* A C expression that indicates when an argument must be passed by
8682 reference. If nonzero for an argument, a copy of that argument is
8683 made in memory and a pointer to the argument is passed instead of
8684 the argument itself. The pointer is passed in whatever way is
8685 appropriate for passing a pointer to that type.
8687 Under V.4, aggregates and long double are passed by reference.
8689 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8690 reference unless the AltiVec vector extension ABI is in force.
8692 As an extension to all ABIs, variable sized types are passed by
8693 reference. */
8695 static bool
8696 rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
8697 enum machine_mode mode, const_tree type,
8698 bool named ATTRIBUTE_UNUSED)
8700 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8702 if (TARGET_DEBUG_ARG)
8703 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8704 return 1;
8707 if (!type)
8708 return 0;
8710 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8712 if (TARGET_DEBUG_ARG)
8713 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8714 return 1;
8717 if (int_size_in_bytes (type) < 0)
8719 if (TARGET_DEBUG_ARG)
8720 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8721 return 1;
8724 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8725 modes only exist for GCC vector types if -maltivec. */
8726 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8728 if (TARGET_DEBUG_ARG)
8729 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8730 return 1;
8733 /* Pass synthetic vectors in memory. */
8734 if (TREE_CODE (type) == VECTOR_TYPE
8735 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8737 static bool warned_for_pass_big_vectors = false;
8738 if (TARGET_DEBUG_ARG)
8739 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8740 if (!warned_for_pass_big_vectors)
8742 warning (0, "GCC vector passed by reference: "
8743 "non-standard ABI extension with no compatibility guarantee");
8744 warned_for_pass_big_vectors = true;
8746 return 1;
8749 return 0;
8752 static void
8753 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8755 int i;
8756 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8758 if (nregs == 0)
8759 return;
8761 for (i = 0; i < nregs; i++)
8763 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8764 if (reload_completed)
8766 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8767 tem = NULL_RTX;
8768 else
8769 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8770 i * GET_MODE_SIZE (reg_mode));
8772 else
8773 tem = replace_equiv_address (tem, XEXP (tem, 0));
8775 gcc_assert (tem);
8777 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8781 /* Perform any needed actions needed for a function that is receiving a
8782 variable number of arguments.
8784 CUM is as above.
8786 MODE and TYPE are the mode and type of the current parameter.
8788 PRETEND_SIZE is a variable that should be set to the amount of stack
8789 that must be pushed by the prolog to pretend that our caller pushed
8792 Normally, this macro will push all remaining incoming registers on the
8793 stack and set PRETEND_SIZE to the length of the registers pushed. */
8795 static void
8796 setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode,
8797 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8798 int no_rtl)
8800 CUMULATIVE_ARGS next_cum;
8801 int reg_size = TARGET_32BIT ? 4 : 8;
8802 rtx save_area = NULL_RTX, mem;
8803 int first_reg_offset;
8804 alias_set_type set;
8806 /* Skip the last named argument. */
8807 next_cum = *get_cumulative_args (cum);
8808 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8810 if (DEFAULT_ABI == ABI_V4)
8812 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8814 if (! no_rtl)
8816 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8817 HOST_WIDE_INT offset = 0;
8819 /* Try to optimize the size of the varargs save area.
8820 The ABI requires that ap.reg_save_area is doubleword
8821 aligned, but we don't need to allocate space for all
8822 the bytes, only those to which we actually will save
8823 anything. */
8824 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8825 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8826 if (TARGET_HARD_FLOAT && TARGET_FPRS
8827 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8828 && cfun->va_list_fpr_size)
8830 if (gpr_reg_num)
8831 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8832 * UNITS_PER_FP_WORD;
8833 if (cfun->va_list_fpr_size
8834 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8835 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8836 else
8837 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8838 * UNITS_PER_FP_WORD;
8840 if (gpr_reg_num)
8842 offset = -((first_reg_offset * reg_size) & ~7);
8843 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8845 gpr_reg_num = cfun->va_list_gpr_size;
8846 if (reg_size == 4 && (first_reg_offset & 1))
8847 gpr_reg_num++;
8849 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8851 else if (fpr_size)
8852 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8853 * UNITS_PER_FP_WORD
8854 - (int) (GP_ARG_NUM_REG * reg_size);
8856 if (gpr_size + fpr_size)
8858 rtx reg_save_area
8859 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8860 gcc_assert (GET_CODE (reg_save_area) == MEM);
8861 reg_save_area = XEXP (reg_save_area, 0);
8862 if (GET_CODE (reg_save_area) == PLUS)
8864 gcc_assert (XEXP (reg_save_area, 0)
8865 == virtual_stack_vars_rtx);
8866 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8867 offset += INTVAL (XEXP (reg_save_area, 1));
8869 else
8870 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8873 cfun->machine->varargs_save_offset = offset;
8874 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8877 else
8879 first_reg_offset = next_cum.words;
8880 save_area = virtual_incoming_args_rtx;
8882 if (targetm.calls.must_pass_in_stack (mode, type))
8883 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8886 set = get_varargs_alias_set ();
8887 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8888 && cfun->va_list_gpr_size)
8890 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8892 if (va_list_gpr_counter_field)
8894 /* V4 va_list_gpr_size counts number of registers needed. */
8895 if (nregs > cfun->va_list_gpr_size)
8896 nregs = cfun->va_list_gpr_size;
8898 else
8900 /* char * va_list instead counts number of bytes needed. */
8901 if (nregs > cfun->va_list_gpr_size / reg_size)
8902 nregs = cfun->va_list_gpr_size / reg_size;
8905 mem = gen_rtx_MEM (BLKmode,
8906 plus_constant (save_area,
8907 first_reg_offset * reg_size));
8908 MEM_NOTRAP_P (mem) = 1;
8909 set_mem_alias_set (mem, set);
8910 set_mem_align (mem, BITS_PER_WORD);
8912 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8913 nregs);
8916 /* Save FP registers if needed. */
8917 if (DEFAULT_ABI == ABI_V4
8918 && TARGET_HARD_FLOAT && TARGET_FPRS
8919 && ! no_rtl
8920 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8921 && cfun->va_list_fpr_size)
8923 int fregno = next_cum.fregno, nregs;
8924 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8925 rtx lab = gen_label_rtx ();
8926 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8927 * UNITS_PER_FP_WORD);
8929 emit_jump_insn
8930 (gen_rtx_SET (VOIDmode,
8931 pc_rtx,
8932 gen_rtx_IF_THEN_ELSE (VOIDmode,
8933 gen_rtx_NE (VOIDmode, cr1,
8934 const0_rtx),
8935 gen_rtx_LABEL_REF (VOIDmode, lab),
8936 pc_rtx)));
8938 for (nregs = 0;
8939 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8940 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8942 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8943 ? DFmode : SFmode,
8944 plus_constant (save_area, off));
8945 MEM_NOTRAP_P (mem) = 1;
8946 set_mem_alias_set (mem, set);
8947 set_mem_align (mem, GET_MODE_ALIGNMENT (
8948 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8949 ? DFmode : SFmode));
8950 emit_move_insn (mem, gen_rtx_REG (
8951 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8952 ? DFmode : SFmode, fregno));
8955 emit_label (lab);
8959 /* Create the va_list data type. */
8961 static tree
8962 rs6000_build_builtin_va_list (void)
8964 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8966 /* For AIX, prefer 'char *' because that's what the system
8967 header files like. */
8968 if (DEFAULT_ABI != ABI_V4)
8969 return build_pointer_type (char_type_node);
8971 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8972 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8973 get_identifier ("__va_list_tag"), record);
8975 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8976 unsigned_char_type_node);
8977 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8978 unsigned_char_type_node);
8979 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8980 every user file. */
8981 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8982 get_identifier ("reserved"), short_unsigned_type_node);
8983 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8984 get_identifier ("overflow_arg_area"),
8985 ptr_type_node);
8986 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8987 get_identifier ("reg_save_area"),
8988 ptr_type_node);
8990 va_list_gpr_counter_field = f_gpr;
8991 va_list_fpr_counter_field = f_fpr;
8993 DECL_FIELD_CONTEXT (f_gpr) = record;
8994 DECL_FIELD_CONTEXT (f_fpr) = record;
8995 DECL_FIELD_CONTEXT (f_res) = record;
8996 DECL_FIELD_CONTEXT (f_ovf) = record;
8997 DECL_FIELD_CONTEXT (f_sav) = record;
8999 TYPE_STUB_DECL (record) = type_decl;
9000 TYPE_NAME (record) = type_decl;
9001 TYPE_FIELDS (record) = f_gpr;
9002 DECL_CHAIN (f_gpr) = f_fpr;
9003 DECL_CHAIN (f_fpr) = f_res;
9004 DECL_CHAIN (f_res) = f_ovf;
9005 DECL_CHAIN (f_ovf) = f_sav;
9007 layout_type (record);
9009 /* The correct type is an array type of one element. */
9010 return build_array_type (record, build_index_type (size_zero_node));
9013 /* Implement va_start. */
9015 static void
9016 rs6000_va_start (tree valist, rtx nextarg)
9018 HOST_WIDE_INT words, n_gpr, n_fpr;
9019 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9020 tree gpr, fpr, ovf, sav, t;
9022 /* Only SVR4 needs something special. */
9023 if (DEFAULT_ABI != ABI_V4)
9025 std_expand_builtin_va_start (valist, nextarg);
9026 return;
9029 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9030 f_fpr = DECL_CHAIN (f_gpr);
9031 f_res = DECL_CHAIN (f_fpr);
9032 f_ovf = DECL_CHAIN (f_res);
9033 f_sav = DECL_CHAIN (f_ovf);
9035 valist = build_simple_mem_ref (valist);
9036 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9037 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9038 f_fpr, NULL_TREE);
9039 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9040 f_ovf, NULL_TREE);
9041 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9042 f_sav, NULL_TREE);
9044 /* Count number of gp and fp argument registers used. */
9045 words = crtl->args.info.words;
9046 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9047 GP_ARG_NUM_REG);
9048 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9049 FP_ARG_NUM_REG);
9051 if (TARGET_DEBUG_ARG)
9052 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9053 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9054 words, n_gpr, n_fpr);
9056 if (cfun->va_list_gpr_size)
9058 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9059 build_int_cst (NULL_TREE, n_gpr));
9060 TREE_SIDE_EFFECTS (t) = 1;
9061 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9064 if (cfun->va_list_fpr_size)
9066 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9067 build_int_cst (NULL_TREE, n_fpr));
9068 TREE_SIDE_EFFECTS (t) = 1;
9069 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9071 #ifdef HAVE_AS_GNU_ATTRIBUTE
9072 if (call_ABI_of_interest (cfun->decl))
9073 rs6000_passes_float = true;
9074 #endif
9077 /* Find the overflow area. */
9078 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9079 if (words != 0)
9080 t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
9081 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9082 TREE_SIDE_EFFECTS (t) = 1;
9083 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9085 /* If there were no va_arg invocations, don't set up the register
9086 save area. */
9087 if (!cfun->va_list_gpr_size
9088 && !cfun->va_list_fpr_size
9089 && n_gpr < GP_ARG_NUM_REG
9090 && n_fpr < FP_ARG_V4_MAX_REG)
9091 return;
9093 /* Find the register save area. */
9094 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9095 if (cfun->machine->varargs_save_offset)
9096 t = fold_build_pointer_plus_hwi (t, cfun->machine->varargs_save_offset);
9097 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9098 TREE_SIDE_EFFECTS (t) = 1;
9099 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9102 /* Implement va_arg. */
9104 tree
9105 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9106 gimple_seq *post_p)
9108 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9109 tree gpr, fpr, ovf, sav, reg, t, u;
9110 int size, rsize, n_reg, sav_ofs, sav_scale;
9111 tree lab_false, lab_over, addr;
9112 int align;
9113 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9114 int regalign = 0;
9115 gimple stmt;
9117 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9119 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9120 return build_va_arg_indirect_ref (t);
9123 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9124 earlier version of gcc, with the property that it always applied alignment
9125 adjustments to the va-args (even for zero-sized types). The cheapest way
9126 to deal with this is to replicate the effect of the part of
9127 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9128 of relevance.
9129 We don't need to check for pass-by-reference because of the test above.
9130 We can return a simplifed answer, since we know there's no offset to add. */
9132 if (TARGET_MACHO
9133 && rs6000_darwin64_abi
9134 && integer_zerop (TYPE_SIZE (type)))
9136 unsigned HOST_WIDE_INT align, boundary;
9137 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9138 align = PARM_BOUNDARY / BITS_PER_UNIT;
9139 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9140 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9141 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9142 boundary /= BITS_PER_UNIT;
9143 if (boundary > align)
9145 tree t ;
9146 /* This updates arg ptr by the amount that would be necessary
9147 to align the zero-sized (but not zero-alignment) item. */
9148 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9149 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
9150 gimplify_and_add (t, pre_p);
9152 t = fold_convert (sizetype, valist_tmp);
9153 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9154 fold_convert (TREE_TYPE (valist),
9155 fold_build2 (BIT_AND_EXPR, sizetype, t,
9156 size_int (-boundary))));
9157 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9158 gimplify_and_add (t, pre_p);
9160 /* Since it is zero-sized there's no increment for the item itself. */
9161 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9162 return build_va_arg_indirect_ref (valist_tmp);
9165 if (DEFAULT_ABI != ABI_V4)
9167 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9169 tree elem_type = TREE_TYPE (type);
9170 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9171 int elem_size = GET_MODE_SIZE (elem_mode);
9173 if (elem_size < UNITS_PER_WORD)
9175 tree real_part, imag_part;
9176 gimple_seq post = NULL;
9178 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9179 &post);
9180 /* Copy the value into a temporary, lest the formal temporary
9181 be reused out from under us. */
9182 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9183 gimple_seq_add_seq (pre_p, post);
9185 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9186 post_p);
9188 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9192 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9195 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9196 f_fpr = DECL_CHAIN (f_gpr);
9197 f_res = DECL_CHAIN (f_fpr);
9198 f_ovf = DECL_CHAIN (f_res);
9199 f_sav = DECL_CHAIN (f_ovf);
9201 valist = build_va_arg_indirect_ref (valist);
9202 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9203 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9204 f_fpr, NULL_TREE);
9205 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9206 f_ovf, NULL_TREE);
9207 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9208 f_sav, NULL_TREE);
9210 size = int_size_in_bytes (type);
9211 rsize = (size + 3) / 4;
9212 align = 1;
9214 if (TARGET_HARD_FLOAT && TARGET_FPRS
9215 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9216 || (TARGET_DOUBLE_FLOAT
9217 && (TYPE_MODE (type) == DFmode
9218 || TYPE_MODE (type) == TFmode
9219 || TYPE_MODE (type) == SDmode
9220 || TYPE_MODE (type) == DDmode
9221 || TYPE_MODE (type) == TDmode))))
9223 /* FP args go in FP registers, if present. */
9224 reg = fpr;
9225 n_reg = (size + 7) / 8;
9226 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9227 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9228 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9229 align = 8;
9231 else
9233 /* Otherwise into GP registers. */
9234 reg = gpr;
9235 n_reg = rsize;
9236 sav_ofs = 0;
9237 sav_scale = 4;
9238 if (n_reg == 2)
9239 align = 8;
9242 /* Pull the value out of the saved registers.... */
9244 lab_over = NULL;
9245 addr = create_tmp_var (ptr_type_node, "addr");
9247 /* AltiVec vectors never go in registers when -mabi=altivec. */
9248 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9249 align = 16;
9250 else
9252 lab_false = create_artificial_label (input_location);
9253 lab_over = create_artificial_label (input_location);
9255 /* Long long and SPE vectors are aligned in the registers.
9256 As are any other 2 gpr item such as complex int due to a
9257 historical mistake. */
9258 u = reg;
9259 if (n_reg == 2 && reg == gpr)
9261 regalign = 1;
9262 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9263 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9264 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9265 unshare_expr (reg), u);
9267 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9268 reg number is 0 for f1, so we want to make it odd. */
9269 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9271 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9272 build_int_cst (TREE_TYPE (reg), 1));
9273 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9276 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9277 t = build2 (GE_EXPR, boolean_type_node, u, t);
9278 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9279 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9280 gimplify_and_add (t, pre_p);
9282 t = sav;
9283 if (sav_ofs)
9284 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
9286 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9287 build_int_cst (TREE_TYPE (reg), n_reg));
9288 u = fold_convert (sizetype, u);
9289 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9290 t = fold_build_pointer_plus (t, u);
9292 /* _Decimal32 varargs are located in the second word of the 64-bit
9293 FP register for 32-bit binaries. */
9294 if (!TARGET_POWERPC64
9295 && TARGET_HARD_FLOAT && TARGET_FPRS
9296 && TYPE_MODE (type) == SDmode)
9297 t = fold_build_pointer_plus_hwi (t, size);
9299 gimplify_assign (addr, t, pre_p);
9301 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9303 stmt = gimple_build_label (lab_false);
9304 gimple_seq_add_stmt (pre_p, stmt);
9306 if ((n_reg == 2 && !regalign) || n_reg > 2)
9308 /* Ensure that we don't find any more args in regs.
9309 Alignment has taken care of for special cases. */
9310 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9314 /* ... otherwise out of the overflow area. */
9316 /* Care for on-stack alignment if needed. */
9317 t = ovf;
9318 if (align != 1)
9320 t = fold_build_pointer_plus_hwi (t, align - 1);
9321 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9322 build_int_cst (TREE_TYPE (t), -align));
9324 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9326 gimplify_assign (unshare_expr (addr), t, pre_p);
9328 t = fold_build_pointer_plus_hwi (t, size);
9329 gimplify_assign (unshare_expr (ovf), t, pre_p);
9331 if (lab_over)
9333 stmt = gimple_build_label (lab_over);
9334 gimple_seq_add_stmt (pre_p, stmt);
9337 if (STRICT_ALIGNMENT
9338 && (TYPE_ALIGN (type)
9339 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9341 /* The value (of type complex double, for example) may not be
9342 aligned in memory in the saved registers, so copy via a
9343 temporary. (This is the same code as used for SPARC.) */
9344 tree tmp = create_tmp_var (type, "va_arg_tmp");
9345 tree dest_addr = build_fold_addr_expr (tmp);
9347 tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
9348 3, dest_addr, addr, size_int (rsize * 4));
9350 gimplify_and_add (copy, pre_p);
9351 addr = dest_addr;
9354 addr = fold_convert (ptrtype, addr);
9355 return build_va_arg_indirect_ref (addr);
9358 /* Builtins. */
9360 static void
9361 def_builtin (int mask, const char *name, tree type, int code)
9363 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9365 tree t;
9366 if (rs6000_builtin_decls[code])
9367 fatal_error ("internal error: builtin function to %s already processed",
9368 name);
9370 rs6000_builtin_decls[code] = t =
9371 add_builtin_function (name, type, code, BUILT_IN_MD,
9372 NULL, NULL_TREE);
9374 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9375 switch (builtin_classify[code])
9377 default:
9378 gcc_unreachable ();
9380 /* assume builtin can do anything. */
9381 case RS6000_BTC_MISC:
9382 break;
9384 /* const function, function only depends on the inputs. */
9385 case RS6000_BTC_CONST:
9386 TREE_READONLY (t) = 1;
9387 TREE_NOTHROW (t) = 1;
9388 break;
9390 /* pure function, function can read global memory. */
9391 case RS6000_BTC_PURE:
9392 DECL_PURE_P (t) = 1;
9393 TREE_NOTHROW (t) = 1;
9394 break;
9396 /* Function is a math function. If rounding mode is on, then treat
9397 the function as not reading global memory, but it can have
9398 arbitrary side effects. If it is off, then assume the function is
9399 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9400 attribute in builtin-attribute.def that is used for the math
9401 functions. */
9402 case RS6000_BTC_FP_PURE:
9403 TREE_NOTHROW (t) = 1;
9404 if (flag_rounding_math)
9406 DECL_PURE_P (t) = 1;
9407 DECL_IS_NOVOPS (t) = 1;
9409 else
9410 TREE_READONLY (t) = 1;
9411 break;
9416 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9418 static const struct builtin_description bdesc_3arg[] =
9420 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9421 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9422 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9423 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9424 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9425 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9426 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9427 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9428 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9429 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9430 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9431 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9432 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9433 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9434 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9435 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9436 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9437 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9438 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9439 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9440 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9441 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9442 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9443 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9444 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9445 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9446 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9447 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9448 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9449 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9450 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9451 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9452 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9453 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9454 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9472 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9473 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9474 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9475 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9477 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9478 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9479 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9480 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9485 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9486 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9487 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9488 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9489 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9490 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9491 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9492 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9493 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9494 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9496 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9497 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9498 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9499 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9500 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9501 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9502 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9503 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9504 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9505 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9507 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9508 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9509 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9510 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9511 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9512 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9513 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9514 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9515 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9517 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9518 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9519 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9520 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9521 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9522 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9523 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9525 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9526 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9527 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9528 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9529 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9530 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9531 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9532 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9533 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9536 /* DST operations: void foo (void *, const int, const char). */
9538 static const struct builtin_description bdesc_dst[] =
9540 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9541 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9542 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9543 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9545 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9546 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9547 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9548 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9551 /* Simple binary operations: VECc = foo (VECa, VECb). */
9553 static struct builtin_description bdesc_2arg[] =
9555 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9556 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9557 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9558 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9559 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9560 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9561 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9562 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9563 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9564 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9565 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9566 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9567 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9568 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9569 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9570 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9571 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9572 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9573 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9574 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9575 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9576 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9577 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9578 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9579 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9580 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9581 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9582 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9583 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9584 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9585 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9586 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9587 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9588 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9589 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9590 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9591 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9592 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9593 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9594 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9595 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9596 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9597 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9598 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9599 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9600 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9601 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9602 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9603 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9604 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9605 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9606 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9607 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9608 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9609 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9610 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9611 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9612 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9613 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9614 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9615 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9616 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9617 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9618 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9619 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9620 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9621 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9622 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9623 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9624 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9625 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9626 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9627 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9628 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9629 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9630 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9631 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9632 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9633 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9634 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9635 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9636 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9637 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9638 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9639 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9640 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9641 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9642 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9643 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9644 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9645 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9646 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9647 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9648 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9649 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9650 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9651 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9652 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9653 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9654 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9655 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9656 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9657 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9658 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9659 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9660 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9661 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9662 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9663 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9664 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9665 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9666 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9667 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9668 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9669 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9670 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9671 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9673 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9674 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9675 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9676 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9677 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9678 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9679 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9680 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9681 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9682 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9683 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9684 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9686 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9687 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9688 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9689 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9690 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9691 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9692 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9693 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9694 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9695 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9696 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9697 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9699 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9700 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9701 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9702 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9703 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9704 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9706 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9707 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9708 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9709 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9710 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9711 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9712 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9713 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9714 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9715 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9716 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9717 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9719 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9720 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9721 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9722 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9723 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9726 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9727 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9728 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9729 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9730 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9731 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9732 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9733 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9734 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9735 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9736 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9737 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9738 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9739 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9740 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9744 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9745 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9746 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9747 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9748 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9749 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9751 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9752 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9753 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9754 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9755 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9756 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9757 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9758 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9759 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9760 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9761 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9762 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9763 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9764 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9765 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9766 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9767 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9768 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9769 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9770 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9771 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9772 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9775 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9776 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9779 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9780 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9793 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9794 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9828 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9829 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9847 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9849 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9850 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9852 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9853 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9854 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9855 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9856 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9857 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9858 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9859 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9860 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9861 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9863 /* Place holder, leave as first spe builtin. */
9864 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9865 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9866 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9867 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9868 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9869 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9870 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9871 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9872 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9873 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9874 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9875 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9876 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9877 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9878 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9879 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9880 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9881 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9882 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9883 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9884 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9885 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9886 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9887 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9888 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9889 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9890 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9891 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9892 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9893 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9894 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9895 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9896 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9897 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9898 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9899 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9900 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9901 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9902 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9903 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9904 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9905 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9906 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9907 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9908 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9909 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9910 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9911 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9912 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9913 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9914 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9915 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9916 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9917 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9918 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9919 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9920 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9921 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9922 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9923 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9924 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9925 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9926 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9927 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9928 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9929 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9930 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9931 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9932 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9933 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9934 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9935 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9936 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9937 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9938 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9939 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9940 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9941 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9942 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9943 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9944 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9945 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9946 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9947 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9948 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9949 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9950 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9951 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9952 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9953 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9954 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9955 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9956 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9957 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9958 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9959 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9960 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9961 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9962 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9963 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9964 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9965 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9966 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9967 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9968 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9969 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9970 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9971 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9972 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9974 /* SPE binary operations expecting a 5-bit unsigned literal. */
9975 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9977 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9978 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9979 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9980 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9981 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9982 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9983 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9984 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9985 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9986 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9987 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9988 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9989 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9990 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9991 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9992 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9993 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9994 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9995 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9996 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9997 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9998 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9999 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10000 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10001 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10002 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10004 /* Place-holder. Leave as last binary SPE builtin. */
10005 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10008 /* AltiVec predicates. */
10010 struct builtin_description_predicates
10012 const unsigned int mask;
10013 const enum insn_code icode;
10014 const char *const name;
10015 const enum rs6000_builtins code;
10018 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10020 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10021 ALTIVEC_BUILTIN_VCMPBFP_P },
10022 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10023 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10024 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10025 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10026 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10027 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10028 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10029 ALTIVEC_BUILTIN_VCMPEQUW_P },
10030 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10031 ALTIVEC_BUILTIN_VCMPGTSW_P },
10032 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10033 ALTIVEC_BUILTIN_VCMPGTUW_P },
10034 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10035 ALTIVEC_BUILTIN_VCMPEQUH_P },
10036 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10037 ALTIVEC_BUILTIN_VCMPGTSH_P },
10038 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10039 ALTIVEC_BUILTIN_VCMPGTUH_P },
10040 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10041 ALTIVEC_BUILTIN_VCMPEQUB_P },
10042 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10043 ALTIVEC_BUILTIN_VCMPGTSB_P },
10044 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10045 ALTIVEC_BUILTIN_VCMPGTUB_P },
10047 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10048 VSX_BUILTIN_XVCMPEQSP_P },
10049 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10050 VSX_BUILTIN_XVCMPGESP_P },
10051 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10052 VSX_BUILTIN_XVCMPGTSP_P },
10053 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10054 VSX_BUILTIN_XVCMPEQDP_P },
10055 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10056 VSX_BUILTIN_XVCMPGEDP_P },
10057 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10058 VSX_BUILTIN_XVCMPGTDP_P },
10060 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10061 ALTIVEC_BUILTIN_VCMPEQ_P },
10062 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10063 ALTIVEC_BUILTIN_VCMPGT_P },
10064 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10065 ALTIVEC_BUILTIN_VCMPGE_P }
10068 /* SPE predicates. */
10069 static struct builtin_description bdesc_spe_predicates[] =
10071 /* Place-holder. Leave as first. */
10072 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10073 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10074 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10075 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10076 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10077 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10078 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10079 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10080 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10081 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10082 /* Place-holder. Leave as last. */
10083 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10086 /* SPE evsel predicates. */
10087 static struct builtin_description bdesc_spe_evsel[] =
10089 /* Place-holder. Leave as first. */
10090 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10091 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10092 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10093 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10094 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10095 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10096 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10097 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10098 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10099 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10100 /* Place-holder. Leave as last. */
10101 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10104 /* PAIRED predicates. */
10105 static const struct builtin_description bdesc_paired_preds[] =
10107 /* Place-holder. Leave as first. */
10108 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10109 /* Place-holder. Leave as last. */
10110 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10113 /* ABS* operations. */
10115 static const struct builtin_description bdesc_abs[] =
10117 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10118 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10119 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10120 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10121 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10122 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10123 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10124 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10125 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10126 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10127 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10130 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10131 foo (VECa). */
10133 static struct builtin_description bdesc_1arg[] =
10135 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10136 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10137 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10138 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10139 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10140 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10141 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10142 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10143 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10144 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10145 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10146 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10147 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10148 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10149 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10150 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10151 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10152 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10154 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10155 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10156 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10157 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10158 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10159 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10160 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10162 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10163 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10164 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10165 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10166 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10167 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10168 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10170 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10171 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10172 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10173 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10174 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10175 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10177 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10178 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10179 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10180 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10181 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10182 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10184 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10185 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10186 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10187 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10189 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10190 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10191 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10192 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10193 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10194 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10195 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10196 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10197 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10199 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10200 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10201 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10202 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10203 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10204 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10205 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10206 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10207 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10209 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10210 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10211 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10212 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10213 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10219 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10220 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10221 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10222 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10223 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10224 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10225 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10226 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10227 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10228 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10229 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10230 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10231 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10232 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10233 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10234 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10236 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10237 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10238 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10240 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10241 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10242 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10243 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10245 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10246 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10247 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10248 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10249 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10250 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10251 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10252 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10253 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10254 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10255 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10256 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10257 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10258 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10259 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10260 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10261 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10262 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10263 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10264 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10265 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10266 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10267 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10268 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10269 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10270 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10271 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10272 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10273 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10274 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10276 /* Place-holder. Leave as last unary SPE builtin. */
10277 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10279 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10280 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10281 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10282 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10283 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10286 static rtx
10287 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10289 rtx pat;
10290 tree arg0 = CALL_EXPR_ARG (exp, 0);
10291 rtx op0 = expand_normal (arg0);
10292 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10293 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10295 if (icode == CODE_FOR_nothing)
10296 /* Builtin not supported on this processor. */
10297 return 0;
10299 /* If we got invalid arguments bail out before generating bad rtl. */
10300 if (arg0 == error_mark_node)
10301 return const0_rtx;
10303 if (icode == CODE_FOR_altivec_vspltisb
10304 || icode == CODE_FOR_altivec_vspltish
10305 || icode == CODE_FOR_altivec_vspltisw
10306 || icode == CODE_FOR_spe_evsplatfi
10307 || icode == CODE_FOR_spe_evsplati)
10309 /* Only allow 5-bit *signed* literals. */
10310 if (GET_CODE (op0) != CONST_INT
10311 || INTVAL (op0) > 15
10312 || INTVAL (op0) < -16)
10314 error ("argument 1 must be a 5-bit signed literal");
10315 return const0_rtx;
10319 if (target == 0
10320 || GET_MODE (target) != tmode
10321 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10322 target = gen_reg_rtx (tmode);
10324 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10325 op0 = copy_to_mode_reg (mode0, op0);
10327 pat = GEN_FCN (icode) (target, op0);
10328 if (! pat)
10329 return 0;
10330 emit_insn (pat);
10332 return target;
10335 static rtx
10336 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10338 rtx pat, scratch1, scratch2;
10339 tree arg0 = CALL_EXPR_ARG (exp, 0);
10340 rtx op0 = expand_normal (arg0);
10341 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10342 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10344 /* If we have invalid arguments, bail out before generating bad rtl. */
10345 if (arg0 == error_mark_node)
10346 return const0_rtx;
10348 if (target == 0
10349 || GET_MODE (target) != tmode
10350 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10351 target = gen_reg_rtx (tmode);
10353 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10354 op0 = copy_to_mode_reg (mode0, op0);
10356 scratch1 = gen_reg_rtx (mode0);
10357 scratch2 = gen_reg_rtx (mode0);
10359 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10360 if (! pat)
10361 return 0;
10362 emit_insn (pat);
10364 return target;
10367 static rtx
10368 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10370 rtx pat;
10371 tree arg0 = CALL_EXPR_ARG (exp, 0);
10372 tree arg1 = CALL_EXPR_ARG (exp, 1);
10373 rtx op0 = expand_normal (arg0);
10374 rtx op1 = expand_normal (arg1);
10375 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10376 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10377 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10379 if (icode == CODE_FOR_nothing)
10380 /* Builtin not supported on this processor. */
10381 return 0;
10383 /* If we got invalid arguments bail out before generating bad rtl. */
10384 if (arg0 == error_mark_node || arg1 == error_mark_node)
10385 return const0_rtx;
10387 if (icode == CODE_FOR_altivec_vcfux
10388 || icode == CODE_FOR_altivec_vcfsx
10389 || icode == CODE_FOR_altivec_vctsxs
10390 || icode == CODE_FOR_altivec_vctuxs
10391 || icode == CODE_FOR_altivec_vspltb
10392 || icode == CODE_FOR_altivec_vsplth
10393 || icode == CODE_FOR_altivec_vspltw
10394 || icode == CODE_FOR_spe_evaddiw
10395 || icode == CODE_FOR_spe_evldd
10396 || icode == CODE_FOR_spe_evldh
10397 || icode == CODE_FOR_spe_evldw
10398 || icode == CODE_FOR_spe_evlhhesplat
10399 || icode == CODE_FOR_spe_evlhhossplat
10400 || icode == CODE_FOR_spe_evlhhousplat
10401 || icode == CODE_FOR_spe_evlwhe
10402 || icode == CODE_FOR_spe_evlwhos
10403 || icode == CODE_FOR_spe_evlwhou
10404 || icode == CODE_FOR_spe_evlwhsplat
10405 || icode == CODE_FOR_spe_evlwwsplat
10406 || icode == CODE_FOR_spe_evrlwi
10407 || icode == CODE_FOR_spe_evslwi
10408 || icode == CODE_FOR_spe_evsrwis
10409 || icode == CODE_FOR_spe_evsubifw
10410 || icode == CODE_FOR_spe_evsrwiu)
10412 /* Only allow 5-bit unsigned literals. */
10413 STRIP_NOPS (arg1);
10414 if (TREE_CODE (arg1) != INTEGER_CST
10415 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10417 error ("argument 2 must be a 5-bit unsigned literal");
10418 return const0_rtx;
10422 if (target == 0
10423 || GET_MODE (target) != tmode
10424 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10425 target = gen_reg_rtx (tmode);
10427 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10428 op0 = copy_to_mode_reg (mode0, op0);
10429 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10430 op1 = copy_to_mode_reg (mode1, op1);
10432 pat = GEN_FCN (icode) (target, op0, op1);
10433 if (! pat)
10434 return 0;
10435 emit_insn (pat);
10437 return target;
10440 static rtx
10441 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10443 rtx pat, scratch;
10444 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10445 tree arg0 = CALL_EXPR_ARG (exp, 1);
10446 tree arg1 = CALL_EXPR_ARG (exp, 2);
10447 rtx op0 = expand_normal (arg0);
10448 rtx op1 = expand_normal (arg1);
10449 enum machine_mode tmode = SImode;
10450 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10451 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10452 int cr6_form_int;
10454 if (TREE_CODE (cr6_form) != INTEGER_CST)
10456 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10457 return const0_rtx;
10459 else
10460 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10462 gcc_assert (mode0 == mode1);
10464 /* If we have invalid arguments, bail out before generating bad rtl. */
10465 if (arg0 == error_mark_node || arg1 == error_mark_node)
10466 return const0_rtx;
10468 if (target == 0
10469 || GET_MODE (target) != tmode
10470 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10471 target = gen_reg_rtx (tmode);
10473 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10474 op0 = copy_to_mode_reg (mode0, op0);
10475 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10476 op1 = copy_to_mode_reg (mode1, op1);
10478 scratch = gen_reg_rtx (mode0);
10480 pat = GEN_FCN (icode) (scratch, op0, op1);
10481 if (! pat)
10482 return 0;
10483 emit_insn (pat);
10485 /* The vec_any* and vec_all* predicates use the same opcodes for two
10486 different operations, but the bits in CR6 will be different
10487 depending on what information we want. So we have to play tricks
10488 with CR6 to get the right bits out.
10490 If you think this is disgusting, look at the specs for the
10491 AltiVec predicates. */
10493 switch (cr6_form_int)
10495 case 0:
10496 emit_insn (gen_cr6_test_for_zero (target));
10497 break;
10498 case 1:
10499 emit_insn (gen_cr6_test_for_zero_reverse (target));
10500 break;
10501 case 2:
10502 emit_insn (gen_cr6_test_for_lt (target));
10503 break;
10504 case 3:
10505 emit_insn (gen_cr6_test_for_lt_reverse (target));
10506 break;
10507 default:
10508 error ("argument 1 of __builtin_altivec_predicate is out of range");
10509 break;
10512 return target;
10515 static rtx
10516 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10518 rtx pat, addr;
10519 tree arg0 = CALL_EXPR_ARG (exp, 0);
10520 tree arg1 = CALL_EXPR_ARG (exp, 1);
10521 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10522 enum machine_mode mode0 = Pmode;
10523 enum machine_mode mode1 = Pmode;
10524 rtx op0 = expand_normal (arg0);
10525 rtx op1 = expand_normal (arg1);
10527 if (icode == CODE_FOR_nothing)
10528 /* Builtin not supported on this processor. */
10529 return 0;
10531 /* If we got invalid arguments bail out before generating bad rtl. */
10532 if (arg0 == error_mark_node || arg1 == error_mark_node)
10533 return const0_rtx;
10535 if (target == 0
10536 || GET_MODE (target) != tmode
10537 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10538 target = gen_reg_rtx (tmode);
10540 op1 = copy_to_mode_reg (mode1, op1);
10542 if (op0 == const0_rtx)
10544 addr = gen_rtx_MEM (tmode, op1);
10546 else
10548 op0 = copy_to_mode_reg (mode0, op0);
10549 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10552 pat = GEN_FCN (icode) (target, addr);
10554 if (! pat)
10555 return 0;
10556 emit_insn (pat);
10558 return target;
10561 static rtx
10562 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10564 rtx pat, addr;
10565 tree arg0 = CALL_EXPR_ARG (exp, 0);
10566 tree arg1 = CALL_EXPR_ARG (exp, 1);
10567 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10568 enum machine_mode mode0 = Pmode;
10569 enum machine_mode mode1 = Pmode;
10570 rtx op0 = expand_normal (arg0);
10571 rtx op1 = expand_normal (arg1);
10573 if (icode == CODE_FOR_nothing)
10574 /* Builtin not supported on this processor. */
10575 return 0;
10577 /* If we got invalid arguments bail out before generating bad rtl. */
10578 if (arg0 == error_mark_node || arg1 == error_mark_node)
10579 return const0_rtx;
10581 if (target == 0
10582 || GET_MODE (target) != tmode
10583 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10584 target = gen_reg_rtx (tmode);
10586 op1 = copy_to_mode_reg (mode1, op1);
10588 if (op0 == const0_rtx)
10590 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10592 else
10594 op0 = copy_to_mode_reg (mode0, op0);
10595 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10598 pat = GEN_FCN (icode) (target, addr);
10600 if (! pat)
10601 return 0;
10602 emit_insn (pat);
10604 return target;
10607 static rtx
10608 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10610 tree arg0 = CALL_EXPR_ARG (exp, 0);
10611 tree arg1 = CALL_EXPR_ARG (exp, 1);
10612 tree arg2 = CALL_EXPR_ARG (exp, 2);
10613 rtx op0 = expand_normal (arg0);
10614 rtx op1 = expand_normal (arg1);
10615 rtx op2 = expand_normal (arg2);
10616 rtx pat;
10617 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10618 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10619 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10621 /* Invalid arguments. Bail before doing anything stoopid! */
10622 if (arg0 == error_mark_node
10623 || arg1 == error_mark_node
10624 || arg2 == error_mark_node)
10625 return const0_rtx;
10627 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10628 op0 = copy_to_mode_reg (mode2, op0);
10629 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10630 op1 = copy_to_mode_reg (mode0, op1);
10631 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10632 op2 = copy_to_mode_reg (mode1, op2);
10634 pat = GEN_FCN (icode) (op1, op2, op0);
10635 if (pat)
10636 emit_insn (pat);
10637 return NULL_RTX;
10640 static rtx
10641 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10643 tree arg0 = CALL_EXPR_ARG (exp, 0);
10644 tree arg1 = CALL_EXPR_ARG (exp, 1);
10645 tree arg2 = CALL_EXPR_ARG (exp, 2);
10646 rtx op0 = expand_normal (arg0);
10647 rtx op1 = expand_normal (arg1);
10648 rtx op2 = expand_normal (arg2);
10649 rtx pat, addr;
10650 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10651 enum machine_mode mode1 = Pmode;
10652 enum machine_mode mode2 = Pmode;
10654 /* Invalid arguments. Bail before doing anything stoopid! */
10655 if (arg0 == error_mark_node
10656 || arg1 == error_mark_node
10657 || arg2 == error_mark_node)
10658 return const0_rtx;
10660 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10661 op0 = copy_to_mode_reg (tmode, op0);
10663 op2 = copy_to_mode_reg (mode2, op2);
10665 if (op1 == const0_rtx)
10667 addr = gen_rtx_MEM (tmode, op2);
10669 else
10671 op1 = copy_to_mode_reg (mode1, op1);
10672 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10675 pat = GEN_FCN (icode) (addr, op0);
10676 if (pat)
10677 emit_insn (pat);
10678 return NULL_RTX;
10681 static rtx
10682 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10684 tree arg0 = CALL_EXPR_ARG (exp, 0);
10685 tree arg1 = CALL_EXPR_ARG (exp, 1);
10686 tree arg2 = CALL_EXPR_ARG (exp, 2);
10687 rtx op0 = expand_normal (arg0);
10688 rtx op1 = expand_normal (arg1);
10689 rtx op2 = expand_normal (arg2);
10690 rtx pat, addr;
10691 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10692 enum machine_mode smode = insn_data[icode].operand[1].mode;
10693 enum machine_mode mode1 = Pmode;
10694 enum machine_mode mode2 = Pmode;
10696 /* Invalid arguments. Bail before doing anything stoopid! */
10697 if (arg0 == error_mark_node
10698 || arg1 == error_mark_node
10699 || arg2 == error_mark_node)
10700 return const0_rtx;
10702 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
10703 op0 = copy_to_mode_reg (smode, op0);
10705 op2 = copy_to_mode_reg (mode2, op2);
10707 if (op1 == const0_rtx)
10709 addr = gen_rtx_MEM (tmode, op2);
10711 else
10713 op1 = copy_to_mode_reg (mode1, op1);
10714 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10717 pat = GEN_FCN (icode) (addr, op0);
10718 if (pat)
10719 emit_insn (pat);
10720 return NULL_RTX;
10723 static rtx
10724 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10726 rtx pat;
10727 tree arg0 = CALL_EXPR_ARG (exp, 0);
10728 tree arg1 = CALL_EXPR_ARG (exp, 1);
10729 tree arg2 = CALL_EXPR_ARG (exp, 2);
10730 rtx op0 = expand_normal (arg0);
10731 rtx op1 = expand_normal (arg1);
10732 rtx op2 = expand_normal (arg2);
10733 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10734 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10735 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10736 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10738 if (icode == CODE_FOR_nothing)
10739 /* Builtin not supported on this processor. */
10740 return 0;
10742 /* If we got invalid arguments bail out before generating bad rtl. */
10743 if (arg0 == error_mark_node
10744 || arg1 == error_mark_node
10745 || arg2 == error_mark_node)
10746 return const0_rtx;
10748 /* Check and prepare argument depending on the instruction code.
10750 Note that a switch statement instead of the sequence of tests
10751 would be incorrect as many of the CODE_FOR values could be
10752 CODE_FOR_nothing and that would yield multiple alternatives
10753 with identical values. We'd never reach here at runtime in
10754 this case. */
10755 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10756 || icode == CODE_FOR_altivec_vsldoi_v4si
10757 || icode == CODE_FOR_altivec_vsldoi_v8hi
10758 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10760 /* Only allow 4-bit unsigned literals. */
10761 STRIP_NOPS (arg2);
10762 if (TREE_CODE (arg2) != INTEGER_CST
10763 || TREE_INT_CST_LOW (arg2) & ~0xf)
10765 error ("argument 3 must be a 4-bit unsigned literal");
10766 return const0_rtx;
10769 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10770 || icode == CODE_FOR_vsx_xxpermdi_v2di
10771 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10772 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10773 || icode == CODE_FOR_vsx_xxsldwi_v4si
10774 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10775 || icode == CODE_FOR_vsx_xxsldwi_v2di
10776 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10778 /* Only allow 2-bit unsigned literals. */
10779 STRIP_NOPS (arg2);
10780 if (TREE_CODE (arg2) != INTEGER_CST
10781 || TREE_INT_CST_LOW (arg2) & ~0x3)
10783 error ("argument 3 must be a 2-bit unsigned literal");
10784 return const0_rtx;
10787 else if (icode == CODE_FOR_vsx_set_v2df
10788 || icode == CODE_FOR_vsx_set_v2di)
10790 /* Only allow 1-bit unsigned literals. */
10791 STRIP_NOPS (arg2);
10792 if (TREE_CODE (arg2) != INTEGER_CST
10793 || TREE_INT_CST_LOW (arg2) & ~0x1)
10795 error ("argument 3 must be a 1-bit unsigned literal");
10796 return const0_rtx;
10800 if (target == 0
10801 || GET_MODE (target) != tmode
10802 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10803 target = gen_reg_rtx (tmode);
10805 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10806 op0 = copy_to_mode_reg (mode0, op0);
10807 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10808 op1 = copy_to_mode_reg (mode1, op1);
10809 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10810 op2 = copy_to_mode_reg (mode2, op2);
10812 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10813 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10814 else
10815 pat = GEN_FCN (icode) (target, op0, op1, op2);
10816 if (! pat)
10817 return 0;
10818 emit_insn (pat);
10820 return target;
10823 /* Expand the lvx builtins. */
10824 static rtx
10825 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10827 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10828 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10829 tree arg0;
10830 enum machine_mode tmode, mode0;
10831 rtx pat, op0;
10832 enum insn_code icode;
10834 switch (fcode)
10836 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10837 icode = CODE_FOR_vector_altivec_load_v16qi;
10838 break;
10839 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10840 icode = CODE_FOR_vector_altivec_load_v8hi;
10841 break;
10842 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10843 icode = CODE_FOR_vector_altivec_load_v4si;
10844 break;
10845 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10846 icode = CODE_FOR_vector_altivec_load_v4sf;
10847 break;
10848 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
10849 icode = CODE_FOR_vector_altivec_load_v2df;
10850 break;
10851 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
10852 icode = CODE_FOR_vector_altivec_load_v2di;
10853 break;
10854 default:
10855 *expandedp = false;
10856 return NULL_RTX;
10859 *expandedp = true;
10861 arg0 = CALL_EXPR_ARG (exp, 0);
10862 op0 = expand_normal (arg0);
10863 tmode = insn_data[icode].operand[0].mode;
10864 mode0 = insn_data[icode].operand[1].mode;
10866 if (target == 0
10867 || GET_MODE (target) != tmode
10868 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10869 target = gen_reg_rtx (tmode);
10871 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10872 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10874 pat = GEN_FCN (icode) (target, op0);
10875 if (! pat)
10876 return 0;
10877 emit_insn (pat);
10878 return target;
10881 /* Expand the stvx builtins. */
10882 static rtx
10883 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10884 bool *expandedp)
10886 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10887 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10888 tree arg0, arg1;
10889 enum machine_mode mode0, mode1;
10890 rtx pat, op0, op1;
10891 enum insn_code icode;
10893 switch (fcode)
10895 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10896 icode = CODE_FOR_vector_altivec_store_v16qi;
10897 break;
10898 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10899 icode = CODE_FOR_vector_altivec_store_v8hi;
10900 break;
10901 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10902 icode = CODE_FOR_vector_altivec_store_v4si;
10903 break;
10904 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10905 icode = CODE_FOR_vector_altivec_store_v4sf;
10906 break;
10907 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
10908 icode = CODE_FOR_vector_altivec_store_v2df;
10909 break;
10910 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
10911 icode = CODE_FOR_vector_altivec_store_v2di;
10912 break;
10913 default:
10914 *expandedp = false;
10915 return NULL_RTX;
10918 arg0 = CALL_EXPR_ARG (exp, 0);
10919 arg1 = CALL_EXPR_ARG (exp, 1);
10920 op0 = expand_normal (arg0);
10921 op1 = expand_normal (arg1);
10922 mode0 = insn_data[icode].operand[0].mode;
10923 mode1 = insn_data[icode].operand[1].mode;
10925 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10926 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10927 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10928 op1 = copy_to_mode_reg (mode1, op1);
10930 pat = GEN_FCN (icode) (op0, op1);
10931 if (pat)
10932 emit_insn (pat);
10934 *expandedp = true;
10935 return NULL_RTX;
10938 /* Expand the dst builtins. */
10939 static rtx
10940 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10941 bool *expandedp)
10943 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10944 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10945 tree arg0, arg1, arg2;
10946 enum machine_mode mode0, mode1;
10947 rtx pat, op0, op1, op2;
10948 const struct builtin_description *d;
10949 size_t i;
10951 *expandedp = false;
10953 /* Handle DST variants. */
10954 d = bdesc_dst;
10955 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10956 if (d->code == fcode)
10958 arg0 = CALL_EXPR_ARG (exp, 0);
10959 arg1 = CALL_EXPR_ARG (exp, 1);
10960 arg2 = CALL_EXPR_ARG (exp, 2);
10961 op0 = expand_normal (arg0);
10962 op1 = expand_normal (arg1);
10963 op2 = expand_normal (arg2);
10964 mode0 = insn_data[d->icode].operand[0].mode;
10965 mode1 = insn_data[d->icode].operand[1].mode;
10967 /* Invalid arguments, bail out before generating bad rtl. */
10968 if (arg0 == error_mark_node
10969 || arg1 == error_mark_node
10970 || arg2 == error_mark_node)
10971 return const0_rtx;
10973 *expandedp = true;
10974 STRIP_NOPS (arg2);
10975 if (TREE_CODE (arg2) != INTEGER_CST
10976 || TREE_INT_CST_LOW (arg2) & ~0x3)
10978 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10979 return const0_rtx;
10982 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10983 op0 = copy_to_mode_reg (Pmode, op0);
10984 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10985 op1 = copy_to_mode_reg (mode1, op1);
10987 pat = GEN_FCN (d->icode) (op0, op1, op2);
10988 if (pat != 0)
10989 emit_insn (pat);
10991 return NULL_RTX;
10994 return NULL_RTX;
10997 /* Expand vec_init builtin. */
10998 static rtx
10999 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11001 enum machine_mode tmode = TYPE_MODE (type);
11002 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11003 int i, n_elt = GET_MODE_NUNITS (tmode);
11004 rtvec v = rtvec_alloc (n_elt);
11006 gcc_assert (VECTOR_MODE_P (tmode));
11007 gcc_assert (n_elt == call_expr_nargs (exp));
11009 for (i = 0; i < n_elt; ++i)
11011 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11012 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11015 if (!target || !register_operand (target, tmode))
11016 target = gen_reg_rtx (tmode);
11018 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11019 return target;
11022 /* Return the integer constant in ARG. Constrain it to be in the range
11023 of the subparts of VEC_TYPE; issue an error if not. */
11025 static int
11026 get_element_number (tree vec_type, tree arg)
11028 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11030 if (!host_integerp (arg, 1)
11031 || (elt = tree_low_cst (arg, 1), elt > max))
11033 error ("selector must be an integer constant in the range 0..%wi", max);
11034 return 0;
11037 return elt;
11040 /* Expand vec_set builtin. */
11041 static rtx
11042 altivec_expand_vec_set_builtin (tree exp)
11044 enum machine_mode tmode, mode1;
11045 tree arg0, arg1, arg2;
11046 int elt;
11047 rtx op0, op1;
11049 arg0 = CALL_EXPR_ARG (exp, 0);
11050 arg1 = CALL_EXPR_ARG (exp, 1);
11051 arg2 = CALL_EXPR_ARG (exp, 2);
11053 tmode = TYPE_MODE (TREE_TYPE (arg0));
11054 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11055 gcc_assert (VECTOR_MODE_P (tmode));
11057 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11058 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11059 elt = get_element_number (TREE_TYPE (arg0), arg2);
11061 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11062 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11064 op0 = force_reg (tmode, op0);
11065 op1 = force_reg (mode1, op1);
11067 rs6000_expand_vector_set (op0, op1, elt);
11069 return op0;
11072 /* Expand vec_ext builtin. */
11073 static rtx
11074 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11076 enum machine_mode tmode, mode0;
11077 tree arg0, arg1;
11078 int elt;
11079 rtx op0;
11081 arg0 = CALL_EXPR_ARG (exp, 0);
11082 arg1 = CALL_EXPR_ARG (exp, 1);
11084 op0 = expand_normal (arg0);
11085 elt = get_element_number (TREE_TYPE (arg0), arg1);
11087 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11088 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11089 gcc_assert (VECTOR_MODE_P (mode0));
11091 op0 = force_reg (mode0, op0);
11093 if (optimize || !target || !register_operand (target, tmode))
11094 target = gen_reg_rtx (tmode);
11096 rs6000_expand_vector_extract (target, op0, elt);
11098 return target;
11101 /* Expand the builtin in EXP and store the result in TARGET. Store
11102 true in *EXPANDEDP if we found a builtin to expand. */
11103 static rtx
11104 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11106 const struct builtin_description *d;
11107 const struct builtin_description_predicates *dp;
11108 size_t i;
11109 enum insn_code icode;
11110 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11111 tree arg0;
11112 rtx op0, pat;
11113 enum machine_mode tmode, mode0;
11114 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11116 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11117 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11118 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11119 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11121 *expandedp = true;
11122 error ("unresolved overload for Altivec builtin %qF", fndecl);
11123 return const0_rtx;
11126 target = altivec_expand_ld_builtin (exp, target, expandedp);
11127 if (*expandedp)
11128 return target;
11130 target = altivec_expand_st_builtin (exp, target, expandedp);
11131 if (*expandedp)
11132 return target;
11134 target = altivec_expand_dst_builtin (exp, target, expandedp);
11135 if (*expandedp)
11136 return target;
11138 *expandedp = true;
11140 switch (fcode)
11142 case ALTIVEC_BUILTIN_STVX:
11143 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11144 case ALTIVEC_BUILTIN_STVEBX:
11145 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11146 case ALTIVEC_BUILTIN_STVEHX:
11147 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11148 case ALTIVEC_BUILTIN_STVEWX:
11149 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11150 case ALTIVEC_BUILTIN_STVXL:
11151 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11153 case ALTIVEC_BUILTIN_STVLX:
11154 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11155 case ALTIVEC_BUILTIN_STVLXL:
11156 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11157 case ALTIVEC_BUILTIN_STVRX:
11158 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11159 case ALTIVEC_BUILTIN_STVRXL:
11160 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11162 case VSX_BUILTIN_STXVD2X_V2DF:
11163 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11164 case VSX_BUILTIN_STXVD2X_V2DI:
11165 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11166 case VSX_BUILTIN_STXVW4X_V4SF:
11167 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11168 case VSX_BUILTIN_STXVW4X_V4SI:
11169 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11170 case VSX_BUILTIN_STXVW4X_V8HI:
11171 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11172 case VSX_BUILTIN_STXVW4X_V16QI:
11173 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11175 case ALTIVEC_BUILTIN_MFVSCR:
11176 icode = CODE_FOR_altivec_mfvscr;
11177 tmode = insn_data[icode].operand[0].mode;
11179 if (target == 0
11180 || GET_MODE (target) != tmode
11181 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11182 target = gen_reg_rtx (tmode);
11184 pat = GEN_FCN (icode) (target);
11185 if (! pat)
11186 return 0;
11187 emit_insn (pat);
11188 return target;
11190 case ALTIVEC_BUILTIN_MTVSCR:
11191 icode = CODE_FOR_altivec_mtvscr;
11192 arg0 = CALL_EXPR_ARG (exp, 0);
11193 op0 = expand_normal (arg0);
11194 mode0 = insn_data[icode].operand[0].mode;
11196 /* If we got invalid arguments bail out before generating bad rtl. */
11197 if (arg0 == error_mark_node)
11198 return const0_rtx;
11200 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11201 op0 = copy_to_mode_reg (mode0, op0);
11203 pat = GEN_FCN (icode) (op0);
11204 if (pat)
11205 emit_insn (pat);
11206 return NULL_RTX;
11208 case ALTIVEC_BUILTIN_DSSALL:
11209 emit_insn (gen_altivec_dssall ());
11210 return NULL_RTX;
11212 case ALTIVEC_BUILTIN_DSS:
11213 icode = CODE_FOR_altivec_dss;
11214 arg0 = CALL_EXPR_ARG (exp, 0);
11215 STRIP_NOPS (arg0);
11216 op0 = expand_normal (arg0);
11217 mode0 = insn_data[icode].operand[0].mode;
11219 /* If we got invalid arguments bail out before generating bad rtl. */
11220 if (arg0 == error_mark_node)
11221 return const0_rtx;
11223 if (TREE_CODE (arg0) != INTEGER_CST
11224 || TREE_INT_CST_LOW (arg0) & ~0x3)
11226 error ("argument to dss must be a 2-bit unsigned literal");
11227 return const0_rtx;
11230 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11231 op0 = copy_to_mode_reg (mode0, op0);
11233 emit_insn (gen_altivec_dss (op0));
11234 return NULL_RTX;
11236 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11237 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11238 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11239 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11240 case VSX_BUILTIN_VEC_INIT_V2DF:
11241 case VSX_BUILTIN_VEC_INIT_V2DI:
11242 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11244 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11245 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11246 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11247 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11248 case VSX_BUILTIN_VEC_SET_V2DF:
11249 case VSX_BUILTIN_VEC_SET_V2DI:
11250 return altivec_expand_vec_set_builtin (exp);
11252 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11253 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11254 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11255 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11256 case VSX_BUILTIN_VEC_EXT_V2DF:
11257 case VSX_BUILTIN_VEC_EXT_V2DI:
11258 return altivec_expand_vec_ext_builtin (exp, target);
11260 default:
11261 break;
11262 /* Fall through. */
11265 /* Expand abs* operations. */
11266 d = bdesc_abs;
11267 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11268 if (d->code == fcode)
11269 return altivec_expand_abs_builtin (d->icode, exp, target);
11271 /* Expand the AltiVec predicates. */
11272 dp = bdesc_altivec_preds;
11273 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11274 if (dp->code == fcode)
11275 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11277 /* LV* are funky. We initialized them differently. */
11278 switch (fcode)
11280 case ALTIVEC_BUILTIN_LVSL:
11281 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11282 exp, target, false);
11283 case ALTIVEC_BUILTIN_LVSR:
11284 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11285 exp, target, false);
11286 case ALTIVEC_BUILTIN_LVEBX:
11287 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11288 exp, target, false);
11289 case ALTIVEC_BUILTIN_LVEHX:
11290 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11291 exp, target, false);
11292 case ALTIVEC_BUILTIN_LVEWX:
11293 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11294 exp, target, false);
11295 case ALTIVEC_BUILTIN_LVXL:
11296 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11297 exp, target, false);
11298 case ALTIVEC_BUILTIN_LVX:
11299 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11300 exp, target, false);
11301 case ALTIVEC_BUILTIN_LVLX:
11302 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11303 exp, target, true);
11304 case ALTIVEC_BUILTIN_LVLXL:
11305 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11306 exp, target, true);
11307 case ALTIVEC_BUILTIN_LVRX:
11308 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11309 exp, target, true);
11310 case ALTIVEC_BUILTIN_LVRXL:
11311 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11312 exp, target, true);
11313 case VSX_BUILTIN_LXVD2X_V2DF:
11314 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11315 exp, target, false);
11316 case VSX_BUILTIN_LXVD2X_V2DI:
11317 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11318 exp, target, false);
11319 case VSX_BUILTIN_LXVW4X_V4SF:
11320 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11321 exp, target, false);
11322 case VSX_BUILTIN_LXVW4X_V4SI:
11323 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11324 exp, target, false);
11325 case VSX_BUILTIN_LXVW4X_V8HI:
11326 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11327 exp, target, false);
11328 case VSX_BUILTIN_LXVW4X_V16QI:
11329 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11330 exp, target, false);
11331 break;
11332 default:
11333 break;
11334 /* Fall through. */
11337 *expandedp = false;
11338 return NULL_RTX;
11341 /* Expand the builtin in EXP and store the result in TARGET. Store
11342 true in *EXPANDEDP if we found a builtin to expand. */
11343 static rtx
11344 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11346 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11347 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11348 const struct builtin_description *d;
11349 size_t i;
11351 *expandedp = true;
11353 switch (fcode)
11355 case PAIRED_BUILTIN_STX:
11356 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11357 case PAIRED_BUILTIN_LX:
11358 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11359 default:
11360 break;
11361 /* Fall through. */
11364 /* Expand the paired predicates. */
11365 d = bdesc_paired_preds;
11366 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11367 if (d->code == fcode)
11368 return paired_expand_predicate_builtin (d->icode, exp, target);
11370 *expandedp = false;
11371 return NULL_RTX;
11374 /* Binops that need to be initialized manually, but can be expanded
11375 automagically by rs6000_expand_binop_builtin. */
11376 static struct builtin_description bdesc_2arg_spe[] =
11378 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11379 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11380 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11381 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11382 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11383 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11384 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11385 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11386 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11387 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11388 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11389 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11390 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11391 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11392 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11393 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11394 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11395 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11396 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11397 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11398 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11399 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11402 /* Expand the builtin in EXP and store the result in TARGET. Store
11403 true in *EXPANDEDP if we found a builtin to expand.
11405 This expands the SPE builtins that are not simple unary and binary
11406 operations. */
11407 static rtx
11408 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11410 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11411 tree arg1, arg0;
11412 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11413 enum insn_code icode;
11414 enum machine_mode tmode, mode0;
11415 rtx pat, op0;
11416 struct builtin_description *d;
11417 size_t i;
11419 *expandedp = true;
11421 /* Syntax check for a 5-bit unsigned immediate. */
11422 switch (fcode)
11424 case SPE_BUILTIN_EVSTDD:
11425 case SPE_BUILTIN_EVSTDH:
11426 case SPE_BUILTIN_EVSTDW:
11427 case SPE_BUILTIN_EVSTWHE:
11428 case SPE_BUILTIN_EVSTWHO:
11429 case SPE_BUILTIN_EVSTWWE:
11430 case SPE_BUILTIN_EVSTWWO:
11431 arg1 = CALL_EXPR_ARG (exp, 2);
11432 if (TREE_CODE (arg1) != INTEGER_CST
11433 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11435 error ("argument 2 must be a 5-bit unsigned literal");
11436 return const0_rtx;
11438 break;
11439 default:
11440 break;
11443 /* The evsplat*i instructions are not quite generic. */
11444 switch (fcode)
11446 case SPE_BUILTIN_EVSPLATFI:
11447 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11448 exp, target);
11449 case SPE_BUILTIN_EVSPLATI:
11450 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11451 exp, target);
11452 default:
11453 break;
11456 d = (struct builtin_description *) bdesc_2arg_spe;
11457 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11458 if (d->code == fcode)
11459 return rs6000_expand_binop_builtin (d->icode, exp, target);
11461 d = (struct builtin_description *) bdesc_spe_predicates;
11462 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11463 if (d->code == fcode)
11464 return spe_expand_predicate_builtin (d->icode, exp, target);
11466 d = (struct builtin_description *) bdesc_spe_evsel;
11467 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11468 if (d->code == fcode)
11469 return spe_expand_evsel_builtin (d->icode, exp, target);
11471 switch (fcode)
11473 case SPE_BUILTIN_EVSTDDX:
11474 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11475 case SPE_BUILTIN_EVSTDHX:
11476 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11477 case SPE_BUILTIN_EVSTDWX:
11478 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11479 case SPE_BUILTIN_EVSTWHEX:
11480 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11481 case SPE_BUILTIN_EVSTWHOX:
11482 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11483 case SPE_BUILTIN_EVSTWWEX:
11484 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11485 case SPE_BUILTIN_EVSTWWOX:
11486 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11487 case SPE_BUILTIN_EVSTDD:
11488 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11489 case SPE_BUILTIN_EVSTDH:
11490 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11491 case SPE_BUILTIN_EVSTDW:
11492 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11493 case SPE_BUILTIN_EVSTWHE:
11494 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11495 case SPE_BUILTIN_EVSTWHO:
11496 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11497 case SPE_BUILTIN_EVSTWWE:
11498 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11499 case SPE_BUILTIN_EVSTWWO:
11500 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11501 case SPE_BUILTIN_MFSPEFSCR:
11502 icode = CODE_FOR_spe_mfspefscr;
11503 tmode = insn_data[icode].operand[0].mode;
11505 if (target == 0
11506 || GET_MODE (target) != tmode
11507 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11508 target = gen_reg_rtx (tmode);
11510 pat = GEN_FCN (icode) (target);
11511 if (! pat)
11512 return 0;
11513 emit_insn (pat);
11514 return target;
11515 case SPE_BUILTIN_MTSPEFSCR:
11516 icode = CODE_FOR_spe_mtspefscr;
11517 arg0 = CALL_EXPR_ARG (exp, 0);
11518 op0 = expand_normal (arg0);
11519 mode0 = insn_data[icode].operand[0].mode;
11521 if (arg0 == error_mark_node)
11522 return const0_rtx;
11524 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11525 op0 = copy_to_mode_reg (mode0, op0);
11527 pat = GEN_FCN (icode) (op0);
11528 if (pat)
11529 emit_insn (pat);
11530 return NULL_RTX;
11531 default:
11532 break;
11535 *expandedp = false;
11536 return NULL_RTX;
11539 static rtx
11540 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11542 rtx pat, scratch, tmp;
11543 tree form = CALL_EXPR_ARG (exp, 0);
11544 tree arg0 = CALL_EXPR_ARG (exp, 1);
11545 tree arg1 = CALL_EXPR_ARG (exp, 2);
11546 rtx op0 = expand_normal (arg0);
11547 rtx op1 = expand_normal (arg1);
11548 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11549 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11550 int form_int;
11551 enum rtx_code code;
11553 if (TREE_CODE (form) != INTEGER_CST)
11555 error ("argument 1 of __builtin_paired_predicate must be a constant");
11556 return const0_rtx;
11558 else
11559 form_int = TREE_INT_CST_LOW (form);
11561 gcc_assert (mode0 == mode1);
11563 if (arg0 == error_mark_node || arg1 == error_mark_node)
11564 return const0_rtx;
11566 if (target == 0
11567 || GET_MODE (target) != SImode
11568 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11569 target = gen_reg_rtx (SImode);
11570 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11571 op0 = copy_to_mode_reg (mode0, op0);
11572 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11573 op1 = copy_to_mode_reg (mode1, op1);
11575 scratch = gen_reg_rtx (CCFPmode);
11577 pat = GEN_FCN (icode) (scratch, op0, op1);
11578 if (!pat)
11579 return const0_rtx;
11581 emit_insn (pat);
11583 switch (form_int)
11585 /* LT bit. */
11586 case 0:
11587 code = LT;
11588 break;
11589 /* GT bit. */
11590 case 1:
11591 code = GT;
11592 break;
11593 /* EQ bit. */
11594 case 2:
11595 code = EQ;
11596 break;
11597 /* UN bit. */
11598 case 3:
11599 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11600 return target;
11601 default:
11602 error ("argument 1 of __builtin_paired_predicate is out of range");
11603 return const0_rtx;
11606 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11607 emit_move_insn (target, tmp);
11608 return target;
11611 static rtx
11612 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11614 rtx pat, scratch, tmp;
11615 tree form = CALL_EXPR_ARG (exp, 0);
11616 tree arg0 = CALL_EXPR_ARG (exp, 1);
11617 tree arg1 = CALL_EXPR_ARG (exp, 2);
11618 rtx op0 = expand_normal (arg0);
11619 rtx op1 = expand_normal (arg1);
11620 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11621 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11622 int form_int;
11623 enum rtx_code code;
11625 if (TREE_CODE (form) != INTEGER_CST)
11627 error ("argument 1 of __builtin_spe_predicate must be a constant");
11628 return const0_rtx;
11630 else
11631 form_int = TREE_INT_CST_LOW (form);
11633 gcc_assert (mode0 == mode1);
11635 if (arg0 == error_mark_node || arg1 == error_mark_node)
11636 return const0_rtx;
11638 if (target == 0
11639 || GET_MODE (target) != SImode
11640 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11641 target = gen_reg_rtx (SImode);
11643 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11644 op0 = copy_to_mode_reg (mode0, op0);
11645 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11646 op1 = copy_to_mode_reg (mode1, op1);
11648 scratch = gen_reg_rtx (CCmode);
11650 pat = GEN_FCN (icode) (scratch, op0, op1);
11651 if (! pat)
11652 return const0_rtx;
11653 emit_insn (pat);
11655 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11656 _lower_. We use one compare, but look in different bits of the
11657 CR for each variant.
11659 There are 2 elements in each SPE simd type (upper/lower). The CR
11660 bits are set as follows:
11662 BIT0 | BIT 1 | BIT 2 | BIT 3
11663 U | L | (U | L) | (U & L)
11665 So, for an "all" relationship, BIT 3 would be set.
11666 For an "any" relationship, BIT 2 would be set. Etc.
11668 Following traditional nomenclature, these bits map to:
11670 BIT0 | BIT 1 | BIT 2 | BIT 3
11671 LT | GT | EQ | OV
11673 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11676 switch (form_int)
11678 /* All variant. OV bit. */
11679 case 0:
11680 /* We need to get to the OV bit, which is the ORDERED bit. We
11681 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11682 that's ugly and will make validate_condition_mode die.
11683 So let's just use another pattern. */
11684 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11685 return target;
11686 /* Any variant. EQ bit. */
11687 case 1:
11688 code = EQ;
11689 break;
11690 /* Upper variant. LT bit. */
11691 case 2:
11692 code = LT;
11693 break;
11694 /* Lower variant. GT bit. */
11695 case 3:
11696 code = GT;
11697 break;
11698 default:
11699 error ("argument 1 of __builtin_spe_predicate is out of range");
11700 return const0_rtx;
11703 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11704 emit_move_insn (target, tmp);
11706 return target;
11709 /* The evsel builtins look like this:
11711 e = __builtin_spe_evsel_OP (a, b, c, d);
11713 and work like this:
11715 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11716 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11719 static rtx
11720 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11722 rtx pat, scratch;
11723 tree arg0 = CALL_EXPR_ARG (exp, 0);
11724 tree arg1 = CALL_EXPR_ARG (exp, 1);
11725 tree arg2 = CALL_EXPR_ARG (exp, 2);
11726 tree arg3 = CALL_EXPR_ARG (exp, 3);
11727 rtx op0 = expand_normal (arg0);
11728 rtx op1 = expand_normal (arg1);
11729 rtx op2 = expand_normal (arg2);
11730 rtx op3 = expand_normal (arg3);
11731 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11732 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11734 gcc_assert (mode0 == mode1);
11736 if (arg0 == error_mark_node || arg1 == error_mark_node
11737 || arg2 == error_mark_node || arg3 == error_mark_node)
11738 return const0_rtx;
11740 if (target == 0
11741 || GET_MODE (target) != mode0
11742 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11743 target = gen_reg_rtx (mode0);
11745 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11746 op0 = copy_to_mode_reg (mode0, op0);
11747 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11748 op1 = copy_to_mode_reg (mode0, op1);
11749 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11750 op2 = copy_to_mode_reg (mode0, op2);
11751 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11752 op3 = copy_to_mode_reg (mode0, op3);
11754 /* Generate the compare. */
11755 scratch = gen_reg_rtx (CCmode);
11756 pat = GEN_FCN (icode) (scratch, op0, op1);
11757 if (! pat)
11758 return const0_rtx;
11759 emit_insn (pat);
11761 if (mode0 == V2SImode)
11762 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11763 else
11764 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11766 return target;
11769 /* Expand an expression EXP that calls a built-in function,
11770 with result going to TARGET if that's convenient
11771 (and in mode MODE if that's convenient).
11772 SUBTARGET may be used as the target for computing one of EXP's operands.
11773 IGNORE is nonzero if the value is to be ignored. */
11775 static rtx
11776 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11777 enum machine_mode mode ATTRIBUTE_UNUSED,
11778 int ignore ATTRIBUTE_UNUSED)
11780 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11781 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11782 const struct builtin_description *d;
11783 size_t i;
11784 rtx ret;
11785 bool success;
11787 switch (fcode)
11789 case RS6000_BUILTIN_RECIP:
11790 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11792 case RS6000_BUILTIN_RECIPF:
11793 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11795 case RS6000_BUILTIN_RSQRTF:
11796 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11798 case RS6000_BUILTIN_RSQRT:
11799 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11801 case RS6000_BUILTIN_BSWAP_HI:
11802 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11804 case POWER7_BUILTIN_BPERMD:
11805 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11806 ? CODE_FOR_bpermd_di
11807 : CODE_FOR_bpermd_si), exp, target);
11809 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11810 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11812 int icode = (int) CODE_FOR_altivec_lvsr;
11813 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11814 enum machine_mode mode = insn_data[icode].operand[1].mode;
11815 tree arg;
11816 rtx op, addr, pat;
11818 gcc_assert (TARGET_ALTIVEC);
11820 arg = CALL_EXPR_ARG (exp, 0);
11821 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11822 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11823 addr = memory_address (mode, op);
11824 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11825 op = addr;
11826 else
11828 /* For the load case need to negate the address. */
11829 op = gen_reg_rtx (GET_MODE (addr));
11830 emit_insn (gen_rtx_SET (VOIDmode, op,
11831 gen_rtx_NEG (GET_MODE (addr), addr)));
11833 op = gen_rtx_MEM (mode, op);
11835 if (target == 0
11836 || GET_MODE (target) != tmode
11837 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11838 target = gen_reg_rtx (tmode);
11840 /*pat = gen_altivec_lvsr (target, op);*/
11841 pat = GEN_FCN (icode) (target, op);
11842 if (!pat)
11843 return 0;
11844 emit_insn (pat);
11846 return target;
11849 case ALTIVEC_BUILTIN_VCFUX:
11850 case ALTIVEC_BUILTIN_VCFSX:
11851 case ALTIVEC_BUILTIN_VCTUXS:
11852 case ALTIVEC_BUILTIN_VCTSXS:
11853 /* FIXME: There's got to be a nicer way to handle this case than
11854 constructing a new CALL_EXPR. */
11855 if (call_expr_nargs (exp) == 1)
11857 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11858 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11860 break;
11862 default:
11863 break;
11866 if (TARGET_ALTIVEC)
11868 ret = altivec_expand_builtin (exp, target, &success);
11870 if (success)
11871 return ret;
11873 if (TARGET_SPE)
11875 ret = spe_expand_builtin (exp, target, &success);
11877 if (success)
11878 return ret;
11880 if (TARGET_PAIRED_FLOAT)
11882 ret = paired_expand_builtin (exp, target, &success);
11884 if (success)
11885 return ret;
11888 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11890 /* Handle simple unary operations. */
11891 d = (struct builtin_description *) bdesc_1arg;
11892 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11893 if (d->code == fcode)
11894 return rs6000_expand_unop_builtin (d->icode, exp, target);
11896 /* Handle simple binary operations. */
11897 d = (struct builtin_description *) bdesc_2arg;
11898 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11899 if (d->code == fcode)
11900 return rs6000_expand_binop_builtin (d->icode, exp, target);
11902 /* Handle simple ternary operations. */
11903 d = bdesc_3arg;
11904 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11905 if (d->code == fcode)
11906 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11908 gcc_unreachable ();
11911 static void
11912 rs6000_init_builtins (void)
11914 tree tdecl;
11915 tree ftype;
11917 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11918 V2SF_type_node = build_vector_type (float_type_node, 2);
11919 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11920 V2DF_type_node = build_vector_type (double_type_node, 2);
11921 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11922 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11923 V4SF_type_node = build_vector_type (float_type_node, 4);
11924 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11925 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11927 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11928 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11929 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11930 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11932 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11933 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11934 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11935 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11937 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11938 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11939 'vector unsigned short'. */
11941 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11942 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11943 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11944 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11945 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11947 long_integer_type_internal_node = long_integer_type_node;
11948 long_unsigned_type_internal_node = long_unsigned_type_node;
11949 long_long_integer_type_internal_node = long_long_integer_type_node;
11950 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
11951 intQI_type_internal_node = intQI_type_node;
11952 uintQI_type_internal_node = unsigned_intQI_type_node;
11953 intHI_type_internal_node = intHI_type_node;
11954 uintHI_type_internal_node = unsigned_intHI_type_node;
11955 intSI_type_internal_node = intSI_type_node;
11956 uintSI_type_internal_node = unsigned_intSI_type_node;
11957 intDI_type_internal_node = intDI_type_node;
11958 uintDI_type_internal_node = unsigned_intDI_type_node;
11959 float_type_internal_node = float_type_node;
11960 double_type_internal_node = double_type_node;
11961 void_type_internal_node = void_type_node;
11963 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11964 tree type node. */
11965 builtin_mode_to_type[QImode][0] = integer_type_node;
11966 builtin_mode_to_type[HImode][0] = integer_type_node;
11967 builtin_mode_to_type[SImode][0] = intSI_type_node;
11968 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11969 builtin_mode_to_type[DImode][0] = intDI_type_node;
11970 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11971 builtin_mode_to_type[SFmode][0] = float_type_node;
11972 builtin_mode_to_type[DFmode][0] = double_type_node;
11973 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11974 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11975 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11976 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11977 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11978 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11979 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11980 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11981 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11982 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11983 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11984 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11985 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11987 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11988 get_identifier ("__bool char"),
11989 bool_char_type_node);
11990 TYPE_NAME (bool_char_type_node) = tdecl;
11991 (*lang_hooks.decls.pushdecl) (tdecl);
11992 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11993 get_identifier ("__bool short"),
11994 bool_short_type_node);
11995 TYPE_NAME (bool_short_type_node) = tdecl;
11996 (*lang_hooks.decls.pushdecl) (tdecl);
11997 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11998 get_identifier ("__bool int"),
11999 bool_int_type_node);
12000 TYPE_NAME (bool_int_type_node) = tdecl;
12001 (*lang_hooks.decls.pushdecl) (tdecl);
12002 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12003 pixel_type_node);
12004 TYPE_NAME (pixel_type_node) = tdecl;
12005 (*lang_hooks.decls.pushdecl) (tdecl);
12007 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12008 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12009 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12010 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12011 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12013 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12014 get_identifier ("__vector unsigned char"),
12015 unsigned_V16QI_type_node);
12016 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12017 (*lang_hooks.decls.pushdecl) (tdecl);
12018 tdecl = build_decl (BUILTINS_LOCATION,
12019 TYPE_DECL, get_identifier ("__vector signed char"),
12020 V16QI_type_node);
12021 TYPE_NAME (V16QI_type_node) = tdecl;
12022 (*lang_hooks.decls.pushdecl) (tdecl);
12023 tdecl = build_decl (BUILTINS_LOCATION,
12024 TYPE_DECL, get_identifier ("__vector __bool char"),
12025 bool_V16QI_type_node);
12026 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12027 (*lang_hooks.decls.pushdecl) (tdecl);
12029 tdecl = build_decl (BUILTINS_LOCATION,
12030 TYPE_DECL, get_identifier ("__vector unsigned short"),
12031 unsigned_V8HI_type_node);
12032 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12033 (*lang_hooks.decls.pushdecl) (tdecl);
12034 tdecl = build_decl (BUILTINS_LOCATION,
12035 TYPE_DECL, get_identifier ("__vector signed short"),
12036 V8HI_type_node);
12037 TYPE_NAME (V8HI_type_node) = tdecl;
12038 (*lang_hooks.decls.pushdecl) (tdecl);
12039 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12040 get_identifier ("__vector __bool short"),
12041 bool_V8HI_type_node);
12042 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12043 (*lang_hooks.decls.pushdecl) (tdecl);
12045 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12046 get_identifier ("__vector unsigned int"),
12047 unsigned_V4SI_type_node);
12048 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12049 (*lang_hooks.decls.pushdecl) (tdecl);
12050 tdecl = build_decl (BUILTINS_LOCATION,
12051 TYPE_DECL, get_identifier ("__vector signed int"),
12052 V4SI_type_node);
12053 TYPE_NAME (V4SI_type_node) = tdecl;
12054 (*lang_hooks.decls.pushdecl) (tdecl);
12055 tdecl = build_decl (BUILTINS_LOCATION,
12056 TYPE_DECL, get_identifier ("__vector __bool int"),
12057 bool_V4SI_type_node);
12058 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12059 (*lang_hooks.decls.pushdecl) (tdecl);
12061 tdecl = build_decl (BUILTINS_LOCATION,
12062 TYPE_DECL, get_identifier ("__vector float"),
12063 V4SF_type_node);
12064 TYPE_NAME (V4SF_type_node) = tdecl;
12065 (*lang_hooks.decls.pushdecl) (tdecl);
12066 tdecl = build_decl (BUILTINS_LOCATION,
12067 TYPE_DECL, get_identifier ("__vector __pixel"),
12068 pixel_V8HI_type_node);
12069 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12070 (*lang_hooks.decls.pushdecl) (tdecl);
12072 if (TARGET_VSX)
12074 tdecl = build_decl (BUILTINS_LOCATION,
12075 TYPE_DECL, get_identifier ("__vector double"),
12076 V2DF_type_node);
12077 TYPE_NAME (V2DF_type_node) = tdecl;
12078 (*lang_hooks.decls.pushdecl) (tdecl);
12080 tdecl = build_decl (BUILTINS_LOCATION,
12081 TYPE_DECL, get_identifier ("__vector long"),
12082 V2DI_type_node);
12083 TYPE_NAME (V2DI_type_node) = tdecl;
12084 (*lang_hooks.decls.pushdecl) (tdecl);
12086 tdecl = build_decl (BUILTINS_LOCATION,
12087 TYPE_DECL, get_identifier ("__vector unsigned long"),
12088 unsigned_V2DI_type_node);
12089 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12090 (*lang_hooks.decls.pushdecl) (tdecl);
12092 tdecl = build_decl (BUILTINS_LOCATION,
12093 TYPE_DECL, get_identifier ("__vector __bool long"),
12094 bool_V2DI_type_node);
12095 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12096 (*lang_hooks.decls.pushdecl) (tdecl);
12099 if (TARGET_PAIRED_FLOAT)
12100 paired_init_builtins ();
12101 if (TARGET_SPE)
12102 spe_init_builtins ();
12103 if (TARGET_ALTIVEC)
12104 altivec_init_builtins ();
12105 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12106 rs6000_common_init_builtins ();
12107 if (TARGET_FRE)
12109 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12110 RS6000_BUILTIN_RECIP,
12111 "__builtin_recipdiv");
12112 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12113 RS6000_BUILTIN_RECIP);
12115 if (TARGET_FRES)
12117 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12118 RS6000_BUILTIN_RECIPF,
12119 "__builtin_recipdivf");
12120 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12121 RS6000_BUILTIN_RECIPF);
12123 if (TARGET_FRSQRTE)
12125 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12126 RS6000_BUILTIN_RSQRT,
12127 "__builtin_rsqrt");
12128 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12129 RS6000_BUILTIN_RSQRT);
12131 if (TARGET_FRSQRTES)
12133 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12134 RS6000_BUILTIN_RSQRTF,
12135 "__builtin_rsqrtf");
12136 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12137 RS6000_BUILTIN_RSQRTF);
12139 if (TARGET_POPCNTD)
12141 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12142 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12143 POWER7_BUILTIN_BPERMD,
12144 "__builtin_bpermd");
12145 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12146 POWER7_BUILTIN_BPERMD);
12148 if (TARGET_POWERPC)
12150 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12151 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12152 unsigned_intHI_type_node,
12153 NULL_TREE);
12154 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12155 RS6000_BUILTIN_BSWAP_HI);
12158 #if TARGET_XCOFF
12159 /* AIX libm provides clog as __clog. */
12160 if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
12161 set_user_assembler_name (tdecl, "__clog");
12162 #endif
12164 #ifdef SUBTARGET_INIT_BUILTINS
12165 SUBTARGET_INIT_BUILTINS;
12166 #endif
12169 /* Returns the rs6000 builtin decl for CODE. */
12171 static tree
12172 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12174 if (code >= RS6000_BUILTIN_COUNT)
12175 return error_mark_node;
12177 return rs6000_builtin_decls[code];
12180 /* Search through a set of builtins and enable the mask bits.
12181 DESC is an array of builtins.
12182 SIZE is the total number of builtins.
12183 START is the builtin enum at which to start.
12184 END is the builtin enum at which to end. */
12185 static void
12186 enable_mask_for_builtins (struct builtin_description *desc, int size,
12187 enum rs6000_builtins start,
12188 enum rs6000_builtins end)
12190 int i;
12192 for (i = 0; i < size; ++i)
12193 if (desc[i].code == start)
12194 break;
12196 if (i == size)
12197 return;
12199 for (; i < size; ++i)
12201 /* Flip all the bits on. */
12202 desc[i].mask = target_flags;
12203 if (desc[i].code == end)
12204 break;
12208 static void
12209 spe_init_builtins (void)
12211 tree puint_type_node = build_pointer_type (unsigned_type_node);
12212 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12213 struct builtin_description *d;
12214 size_t i;
12216 tree v2si_ftype_4_v2si
12217 = build_function_type_list (opaque_V2SI_type_node,
12218 opaque_V2SI_type_node,
12219 opaque_V2SI_type_node,
12220 opaque_V2SI_type_node,
12221 opaque_V2SI_type_node,
12222 NULL_TREE);
12224 tree v2sf_ftype_4_v2sf
12225 = build_function_type_list (opaque_V2SF_type_node,
12226 opaque_V2SF_type_node,
12227 opaque_V2SF_type_node,
12228 opaque_V2SF_type_node,
12229 opaque_V2SF_type_node,
12230 NULL_TREE);
12232 tree int_ftype_int_v2si_v2si
12233 = build_function_type_list (integer_type_node,
12234 integer_type_node,
12235 opaque_V2SI_type_node,
12236 opaque_V2SI_type_node,
12237 NULL_TREE);
12239 tree int_ftype_int_v2sf_v2sf
12240 = build_function_type_list (integer_type_node,
12241 integer_type_node,
12242 opaque_V2SF_type_node,
12243 opaque_V2SF_type_node,
12244 NULL_TREE);
12246 tree void_ftype_v2si_puint_int
12247 = build_function_type_list (void_type_node,
12248 opaque_V2SI_type_node,
12249 puint_type_node,
12250 integer_type_node,
12251 NULL_TREE);
12253 tree void_ftype_v2si_puint_char
12254 = build_function_type_list (void_type_node,
12255 opaque_V2SI_type_node,
12256 puint_type_node,
12257 char_type_node,
12258 NULL_TREE);
12260 tree void_ftype_v2si_pv2si_int
12261 = build_function_type_list (void_type_node,
12262 opaque_V2SI_type_node,
12263 opaque_p_V2SI_type_node,
12264 integer_type_node,
12265 NULL_TREE);
12267 tree void_ftype_v2si_pv2si_char
12268 = build_function_type_list (void_type_node,
12269 opaque_V2SI_type_node,
12270 opaque_p_V2SI_type_node,
12271 char_type_node,
12272 NULL_TREE);
12274 tree void_ftype_int
12275 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12277 tree int_ftype_void
12278 = build_function_type_list (integer_type_node, NULL_TREE);
12280 tree v2si_ftype_pv2si_int
12281 = build_function_type_list (opaque_V2SI_type_node,
12282 opaque_p_V2SI_type_node,
12283 integer_type_node,
12284 NULL_TREE);
12286 tree v2si_ftype_puint_int
12287 = build_function_type_list (opaque_V2SI_type_node,
12288 puint_type_node,
12289 integer_type_node,
12290 NULL_TREE);
12292 tree v2si_ftype_pushort_int
12293 = build_function_type_list (opaque_V2SI_type_node,
12294 pushort_type_node,
12295 integer_type_node,
12296 NULL_TREE);
12298 tree v2si_ftype_signed_char
12299 = build_function_type_list (opaque_V2SI_type_node,
12300 signed_char_type_node,
12301 NULL_TREE);
12303 /* The initialization of the simple binary and unary builtins is
12304 done in rs6000_common_init_builtins, but we have to enable the
12305 mask bits here manually because we have run out of `target_flags'
12306 bits. We really need to redesign this mask business. */
12308 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12309 ARRAY_SIZE (bdesc_2arg),
12310 SPE_BUILTIN_EVADDW,
12311 SPE_BUILTIN_EVXOR);
12312 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12313 ARRAY_SIZE (bdesc_1arg),
12314 SPE_BUILTIN_EVABS,
12315 SPE_BUILTIN_EVSUBFUSIAAW);
12316 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12317 ARRAY_SIZE (bdesc_spe_predicates),
12318 SPE_BUILTIN_EVCMPEQ,
12319 SPE_BUILTIN_EVFSTSTLT);
12320 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12321 ARRAY_SIZE (bdesc_spe_evsel),
12322 SPE_BUILTIN_EVSEL_CMPGTS,
12323 SPE_BUILTIN_EVSEL_FSTSTEQ);
12325 (*lang_hooks.decls.pushdecl)
12326 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12327 get_identifier ("__ev64_opaque__"),
12328 opaque_V2SI_type_node));
12330 /* Initialize irregular SPE builtins. */
12332 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12333 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12334 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12335 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12336 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12337 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12338 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12339 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12340 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12341 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12342 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12343 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12344 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12345 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12346 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12347 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12348 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12349 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12351 /* Loads. */
12352 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12353 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12354 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12355 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12356 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12357 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12358 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12359 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12360 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12361 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12362 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12363 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12364 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12365 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12366 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12367 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12368 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12369 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12370 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12371 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12372 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12373 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12375 /* Predicates. */
12376 d = (struct builtin_description *) bdesc_spe_predicates;
12377 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12379 tree type;
12381 switch (insn_data[d->icode].operand[1].mode)
12383 case V2SImode:
12384 type = int_ftype_int_v2si_v2si;
12385 break;
12386 case V2SFmode:
12387 type = int_ftype_int_v2sf_v2sf;
12388 break;
12389 default:
12390 gcc_unreachable ();
12393 def_builtin (d->mask, d->name, type, d->code);
12396 /* Evsel predicates. */
12397 d = (struct builtin_description *) bdesc_spe_evsel;
12398 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12400 tree type;
12402 switch (insn_data[d->icode].operand[1].mode)
12404 case V2SImode:
12405 type = v2si_ftype_4_v2si;
12406 break;
12407 case V2SFmode:
12408 type = v2sf_ftype_4_v2sf;
12409 break;
12410 default:
12411 gcc_unreachable ();
12414 def_builtin (d->mask, d->name, type, d->code);
12418 static void
12419 paired_init_builtins (void)
12421 const struct builtin_description *d;
12422 size_t i;
12424 tree int_ftype_int_v2sf_v2sf
12425 = build_function_type_list (integer_type_node,
12426 integer_type_node,
12427 V2SF_type_node,
12428 V2SF_type_node,
12429 NULL_TREE);
12430 tree pcfloat_type_node =
12431 build_pointer_type (build_qualified_type
12432 (float_type_node, TYPE_QUAL_CONST));
12434 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12435 long_integer_type_node,
12436 pcfloat_type_node,
12437 NULL_TREE);
12438 tree void_ftype_v2sf_long_pcfloat =
12439 build_function_type_list (void_type_node,
12440 V2SF_type_node,
12441 long_integer_type_node,
12442 pcfloat_type_node,
12443 NULL_TREE);
12446 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12447 PAIRED_BUILTIN_LX);
12450 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12451 PAIRED_BUILTIN_STX);
12453 /* Predicates. */
12454 d = bdesc_paired_preds;
12455 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12457 tree type;
12459 switch (insn_data[d->icode].operand[1].mode)
12461 case V2SFmode:
12462 type = int_ftype_int_v2sf_v2sf;
12463 break;
12464 default:
12465 gcc_unreachable ();
12468 def_builtin (d->mask, d->name, type, d->code);
12472 static void
12473 altivec_init_builtins (void)
12475 const struct builtin_description *d;
12476 const struct builtin_description_predicates *dp;
12477 size_t i;
12478 tree ftype;
12480 tree pvoid_type_node = build_pointer_type (void_type_node);
12482 tree pcvoid_type_node
12483 = build_pointer_type (build_qualified_type (void_type_node,
12484 TYPE_QUAL_CONST));
12486 tree int_ftype_opaque
12487 = build_function_type_list (integer_type_node,
12488 opaque_V4SI_type_node, NULL_TREE);
12489 tree opaque_ftype_opaque
12490 = build_function_type_list (integer_type_node, NULL_TREE);
12491 tree opaque_ftype_opaque_int
12492 = build_function_type_list (opaque_V4SI_type_node,
12493 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12494 tree opaque_ftype_opaque_opaque_int
12495 = build_function_type_list (opaque_V4SI_type_node,
12496 opaque_V4SI_type_node, opaque_V4SI_type_node,
12497 integer_type_node, NULL_TREE);
12498 tree int_ftype_int_opaque_opaque
12499 = build_function_type_list (integer_type_node,
12500 integer_type_node, opaque_V4SI_type_node,
12501 opaque_V4SI_type_node, NULL_TREE);
12502 tree int_ftype_int_v4si_v4si
12503 = build_function_type_list (integer_type_node,
12504 integer_type_node, V4SI_type_node,
12505 V4SI_type_node, NULL_TREE);
12506 tree void_ftype_v4si
12507 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12508 tree v8hi_ftype_void
12509 = build_function_type_list (V8HI_type_node, NULL_TREE);
12510 tree void_ftype_void
12511 = build_function_type_list (void_type_node, NULL_TREE);
12512 tree void_ftype_int
12513 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12515 tree opaque_ftype_long_pcvoid
12516 = build_function_type_list (opaque_V4SI_type_node,
12517 long_integer_type_node, pcvoid_type_node,
12518 NULL_TREE);
12519 tree v16qi_ftype_long_pcvoid
12520 = build_function_type_list (V16QI_type_node,
12521 long_integer_type_node, pcvoid_type_node,
12522 NULL_TREE);
12523 tree v8hi_ftype_long_pcvoid
12524 = build_function_type_list (V8HI_type_node,
12525 long_integer_type_node, pcvoid_type_node,
12526 NULL_TREE);
12527 tree v4si_ftype_long_pcvoid
12528 = build_function_type_list (V4SI_type_node,
12529 long_integer_type_node, pcvoid_type_node,
12530 NULL_TREE);
12531 tree v4sf_ftype_long_pcvoid
12532 = build_function_type_list (V4SF_type_node,
12533 long_integer_type_node, pcvoid_type_node,
12534 NULL_TREE);
12535 tree v2df_ftype_long_pcvoid
12536 = build_function_type_list (V2DF_type_node,
12537 long_integer_type_node, pcvoid_type_node,
12538 NULL_TREE);
12539 tree v2di_ftype_long_pcvoid
12540 = build_function_type_list (V2DI_type_node,
12541 long_integer_type_node, pcvoid_type_node,
12542 NULL_TREE);
12544 tree void_ftype_opaque_long_pvoid
12545 = build_function_type_list (void_type_node,
12546 opaque_V4SI_type_node, long_integer_type_node,
12547 pvoid_type_node, NULL_TREE);
12548 tree void_ftype_v4si_long_pvoid
12549 = build_function_type_list (void_type_node,
12550 V4SI_type_node, long_integer_type_node,
12551 pvoid_type_node, NULL_TREE);
12552 tree void_ftype_v16qi_long_pvoid
12553 = build_function_type_list (void_type_node,
12554 V16QI_type_node, long_integer_type_node,
12555 pvoid_type_node, NULL_TREE);
12556 tree void_ftype_v8hi_long_pvoid
12557 = build_function_type_list (void_type_node,
12558 V8HI_type_node, long_integer_type_node,
12559 pvoid_type_node, NULL_TREE);
12560 tree void_ftype_v4sf_long_pvoid
12561 = build_function_type_list (void_type_node,
12562 V4SF_type_node, long_integer_type_node,
12563 pvoid_type_node, NULL_TREE);
12564 tree void_ftype_v2df_long_pvoid
12565 = build_function_type_list (void_type_node,
12566 V2DF_type_node, long_integer_type_node,
12567 pvoid_type_node, NULL_TREE);
12568 tree void_ftype_v2di_long_pvoid
12569 = build_function_type_list (void_type_node,
12570 V2DI_type_node, long_integer_type_node,
12571 pvoid_type_node, NULL_TREE);
12572 tree int_ftype_int_v8hi_v8hi
12573 = build_function_type_list (integer_type_node,
12574 integer_type_node, V8HI_type_node,
12575 V8HI_type_node, NULL_TREE);
12576 tree int_ftype_int_v16qi_v16qi
12577 = build_function_type_list (integer_type_node,
12578 integer_type_node, V16QI_type_node,
12579 V16QI_type_node, NULL_TREE);
12580 tree int_ftype_int_v4sf_v4sf
12581 = build_function_type_list (integer_type_node,
12582 integer_type_node, V4SF_type_node,
12583 V4SF_type_node, NULL_TREE);
12584 tree int_ftype_int_v2df_v2df
12585 = build_function_type_list (integer_type_node,
12586 integer_type_node, V2DF_type_node,
12587 V2DF_type_node, NULL_TREE);
12588 tree v4si_ftype_v4si
12589 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12590 tree v8hi_ftype_v8hi
12591 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12592 tree v16qi_ftype_v16qi
12593 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12594 tree v4sf_ftype_v4sf
12595 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12596 tree v2df_ftype_v2df
12597 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12598 tree void_ftype_pcvoid_int_int
12599 = build_function_type_list (void_type_node,
12600 pcvoid_type_node, integer_type_node,
12601 integer_type_node, NULL_TREE);
12603 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12604 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12605 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12606 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12607 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12608 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12609 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12610 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12611 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12612 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12613 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12614 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12615 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12616 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12617 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12618 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12619 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12620 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12621 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12622 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12623 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12624 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12625 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12626 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12627 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12628 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12629 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12630 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12631 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12632 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12634 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
12635 VSX_BUILTIN_LXVD2X_V2DF);
12636 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
12637 VSX_BUILTIN_LXVD2X_V2DI);
12638 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
12639 VSX_BUILTIN_LXVW4X_V4SF);
12640 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
12641 VSX_BUILTIN_LXVW4X_V4SI);
12642 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
12643 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
12644 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
12645 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
12646 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
12647 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
12648 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
12649 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
12650 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
12651 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
12652 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
12653 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
12654 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
12655 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
12656 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
12657 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
12658 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
12659 VSX_BUILTIN_VEC_LD);
12660 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
12661 VSX_BUILTIN_VEC_ST);
12663 if (rs6000_cpu == PROCESSOR_CELL)
12665 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12666 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12667 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12668 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12670 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12671 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12672 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12673 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12675 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12676 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12677 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12678 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12680 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12681 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12682 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12683 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12685 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12686 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12687 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12689 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12690 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12691 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12692 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12693 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12694 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12695 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12696 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12697 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12698 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12699 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12700 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12702 /* Add the DST variants. */
12703 d = bdesc_dst;
12704 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12705 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12707 /* Initialize the predicates. */
12708 dp = bdesc_altivec_preds;
12709 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12711 enum machine_mode mode1;
12712 tree type;
12713 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12714 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12715 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12716 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12718 if (is_overloaded)
12719 mode1 = VOIDmode;
12720 else
12721 mode1 = insn_data[dp->icode].operand[1].mode;
12723 switch (mode1)
12725 case VOIDmode:
12726 type = int_ftype_int_opaque_opaque;
12727 break;
12728 case V4SImode:
12729 type = int_ftype_int_v4si_v4si;
12730 break;
12731 case V8HImode:
12732 type = int_ftype_int_v8hi_v8hi;
12733 break;
12734 case V16QImode:
12735 type = int_ftype_int_v16qi_v16qi;
12736 break;
12737 case V4SFmode:
12738 type = int_ftype_int_v4sf_v4sf;
12739 break;
12740 case V2DFmode:
12741 type = int_ftype_int_v2df_v2df;
12742 break;
12743 default:
12744 gcc_unreachable ();
12747 def_builtin (dp->mask, dp->name, type, dp->code);
12750 /* Initialize the abs* operators. */
12751 d = bdesc_abs;
12752 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12754 enum machine_mode mode0;
12755 tree type;
12757 mode0 = insn_data[d->icode].operand[0].mode;
12759 switch (mode0)
12761 case V4SImode:
12762 type = v4si_ftype_v4si;
12763 break;
12764 case V8HImode:
12765 type = v8hi_ftype_v8hi;
12766 break;
12767 case V16QImode:
12768 type = v16qi_ftype_v16qi;
12769 break;
12770 case V4SFmode:
12771 type = v4sf_ftype_v4sf;
12772 break;
12773 case V2DFmode:
12774 type = v2df_ftype_v2df;
12775 break;
12776 default:
12777 gcc_unreachable ();
12780 def_builtin (d->mask, d->name, type, d->code);
12783 if (TARGET_ALTIVEC)
12785 tree decl;
12787 /* Initialize target builtin that implements
12788 targetm.vectorize.builtin_mask_for_load. */
12790 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12791 v16qi_ftype_long_pcvoid,
12792 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12793 BUILT_IN_MD, NULL, NULL_TREE);
12794 TREE_READONLY (decl) = 1;
12795 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12796 altivec_builtin_mask_for_load = decl;
12799 /* Access to the vec_init patterns. */
12800 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12801 integer_type_node, integer_type_node,
12802 integer_type_node, NULL_TREE);
12803 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12804 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12806 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12807 short_integer_type_node,
12808 short_integer_type_node,
12809 short_integer_type_node,
12810 short_integer_type_node,
12811 short_integer_type_node,
12812 short_integer_type_node,
12813 short_integer_type_node, NULL_TREE);
12814 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12815 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12817 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12818 char_type_node, char_type_node,
12819 char_type_node, char_type_node,
12820 char_type_node, char_type_node,
12821 char_type_node, char_type_node,
12822 char_type_node, char_type_node,
12823 char_type_node, char_type_node,
12824 char_type_node, char_type_node,
12825 char_type_node, NULL_TREE);
12826 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12827 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12829 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12830 float_type_node, float_type_node,
12831 float_type_node, NULL_TREE);
12832 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12833 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12835 if (TARGET_VSX)
12837 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12838 double_type_node, NULL_TREE);
12839 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12840 VSX_BUILTIN_VEC_INIT_V2DF);
12842 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12843 intDI_type_node, NULL_TREE);
12844 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12845 VSX_BUILTIN_VEC_INIT_V2DI);
12848 /* Access to the vec_set patterns. */
12849 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12850 intSI_type_node,
12851 integer_type_node, NULL_TREE);
12852 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12853 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12855 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12856 intHI_type_node,
12857 integer_type_node, NULL_TREE);
12858 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12859 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12861 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12862 intQI_type_node,
12863 integer_type_node, NULL_TREE);
12864 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12865 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12867 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12868 float_type_node,
12869 integer_type_node, NULL_TREE);
12870 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12871 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12873 if (TARGET_VSX)
12875 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12876 double_type_node,
12877 integer_type_node, NULL_TREE);
12878 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12879 VSX_BUILTIN_VEC_SET_V2DF);
12881 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12882 intDI_type_node,
12883 integer_type_node, NULL_TREE);
12884 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12885 VSX_BUILTIN_VEC_SET_V2DI);
12888 /* Access to the vec_extract patterns. */
12889 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12890 integer_type_node, NULL_TREE);
12891 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12892 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12894 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12895 integer_type_node, NULL_TREE);
12896 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12897 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12899 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12900 integer_type_node, NULL_TREE);
12901 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12902 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12904 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12905 integer_type_node, NULL_TREE);
12906 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12907 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12909 if (TARGET_VSX)
12911 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12912 integer_type_node, NULL_TREE);
12913 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12914 VSX_BUILTIN_VEC_EXT_V2DF);
12916 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12917 integer_type_node, NULL_TREE);
12918 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12919 VSX_BUILTIN_VEC_EXT_V2DI);
12923 /* Hash function for builtin functions with up to 3 arguments and a return
12924 type. */
12925 static unsigned
12926 builtin_hash_function (const void *hash_entry)
12928 unsigned ret = 0;
12929 int i;
12930 const struct builtin_hash_struct *bh =
12931 (const struct builtin_hash_struct *) hash_entry;
12933 for (i = 0; i < 4; i++)
12935 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12936 ret = (ret * 2) + bh->uns_p[i];
12939 return ret;
12942 /* Compare builtin hash entries H1 and H2 for equivalence. */
12943 static int
12944 builtin_hash_eq (const void *h1, const void *h2)
12946 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12947 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12949 return ((p1->mode[0] == p2->mode[0])
12950 && (p1->mode[1] == p2->mode[1])
12951 && (p1->mode[2] == p2->mode[2])
12952 && (p1->mode[3] == p2->mode[3])
12953 && (p1->uns_p[0] == p2->uns_p[0])
12954 && (p1->uns_p[1] == p2->uns_p[1])
12955 && (p1->uns_p[2] == p2->uns_p[2])
12956 && (p1->uns_p[3] == p2->uns_p[3]));
12959 /* Map types for builtin functions with an explicit return type and up to 3
12960 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12961 of the argument. */
12962 static tree
12963 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12964 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12965 enum rs6000_builtins builtin, const char *name)
12967 struct builtin_hash_struct h;
12968 struct builtin_hash_struct *h2;
12969 void **found;
12970 int num_args = 3;
12971 int i;
12972 tree ret_type = NULL_TREE;
12973 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12975 /* Create builtin_hash_table. */
12976 if (builtin_hash_table == NULL)
12977 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12978 builtin_hash_eq, NULL);
12980 h.type = NULL_TREE;
12981 h.mode[0] = mode_ret;
12982 h.mode[1] = mode_arg0;
12983 h.mode[2] = mode_arg1;
12984 h.mode[3] = mode_arg2;
12985 h.uns_p[0] = 0;
12986 h.uns_p[1] = 0;
12987 h.uns_p[2] = 0;
12988 h.uns_p[3] = 0;
12990 /* If the builtin is a type that produces unsigned results or takes unsigned
12991 arguments, and it is returned as a decl for the vectorizer (such as
12992 widening multiplies, permute), make sure the arguments and return value
12993 are type correct. */
12994 switch (builtin)
12996 /* unsigned 2 argument functions. */
12997 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12998 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12999 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13000 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13001 h.uns_p[0] = 1;
13002 h.uns_p[1] = 1;
13003 h.uns_p[2] = 1;
13004 break;
13006 /* unsigned 3 argument functions. */
13007 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13008 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13009 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13010 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13011 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13012 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13013 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13014 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13015 case VSX_BUILTIN_VPERM_16QI_UNS:
13016 case VSX_BUILTIN_VPERM_8HI_UNS:
13017 case VSX_BUILTIN_VPERM_4SI_UNS:
13018 case VSX_BUILTIN_VPERM_2DI_UNS:
13019 case VSX_BUILTIN_XXSEL_16QI_UNS:
13020 case VSX_BUILTIN_XXSEL_8HI_UNS:
13021 case VSX_BUILTIN_XXSEL_4SI_UNS:
13022 case VSX_BUILTIN_XXSEL_2DI_UNS:
13023 h.uns_p[0] = 1;
13024 h.uns_p[1] = 1;
13025 h.uns_p[2] = 1;
13026 h.uns_p[3] = 1;
13027 break;
13029 /* signed permute functions with unsigned char mask. */
13030 case ALTIVEC_BUILTIN_VPERM_16QI:
13031 case ALTIVEC_BUILTIN_VPERM_8HI:
13032 case ALTIVEC_BUILTIN_VPERM_4SI:
13033 case ALTIVEC_BUILTIN_VPERM_4SF:
13034 case ALTIVEC_BUILTIN_VPERM_2DI:
13035 case ALTIVEC_BUILTIN_VPERM_2DF:
13036 case VSX_BUILTIN_VPERM_16QI:
13037 case VSX_BUILTIN_VPERM_8HI:
13038 case VSX_BUILTIN_VPERM_4SI:
13039 case VSX_BUILTIN_VPERM_4SF:
13040 case VSX_BUILTIN_VPERM_2DI:
13041 case VSX_BUILTIN_VPERM_2DF:
13042 h.uns_p[3] = 1;
13043 break;
13045 /* unsigned args, signed return. */
13046 case VSX_BUILTIN_XVCVUXDDP_UNS:
13047 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13048 h.uns_p[1] = 1;
13049 break;
13051 /* signed args, unsigned return. */
13052 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13053 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13054 h.uns_p[0] = 1;
13055 break;
13057 default:
13058 break;
13061 /* Figure out how many args are present. */
13062 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13063 num_args--;
13065 if (num_args == 0)
13066 fatal_error ("internal error: builtin function %s had no type", name);
13068 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13069 if (!ret_type && h.uns_p[0])
13070 ret_type = builtin_mode_to_type[h.mode[0]][0];
13072 if (!ret_type)
13073 fatal_error ("internal error: builtin function %s had an unexpected "
13074 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13076 for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
13077 arg_type[i] = NULL_TREE;
13079 for (i = 0; i < num_args; i++)
13081 int m = (int) h.mode[i+1];
13082 int uns_p = h.uns_p[i+1];
13084 arg_type[i] = builtin_mode_to_type[m][uns_p];
13085 if (!arg_type[i] && uns_p)
13086 arg_type[i] = builtin_mode_to_type[m][0];
13088 if (!arg_type[i])
13089 fatal_error ("internal error: builtin function %s, argument %d "
13090 "had unexpected argument type %s", name, i,
13091 GET_MODE_NAME (m));
13094 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13095 if (*found == NULL)
13097 h2 = ggc_alloc_builtin_hash_struct ();
13098 *h2 = h;
13099 *found = (void *)h2;
13101 h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
13102 arg_type[2], NULL_TREE);
13105 return ((struct builtin_hash_struct *)(*found))->type;
13108 static void
13109 rs6000_common_init_builtins (void)
13111 const struct builtin_description *d;
13112 size_t i;
13114 tree opaque_ftype_opaque = NULL_TREE;
13115 tree opaque_ftype_opaque_opaque = NULL_TREE;
13116 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13117 tree v2si_ftype_qi = NULL_TREE;
13118 tree v2si_ftype_v2si_qi = NULL_TREE;
13119 tree v2si_ftype_int_qi = NULL_TREE;
13121 if (!TARGET_PAIRED_FLOAT)
13123 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13124 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13127 /* Add the ternary operators. */
13128 d = bdesc_3arg;
13129 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13131 tree type;
13132 int mask = d->mask;
13134 if ((mask != 0 && (mask & target_flags) == 0)
13135 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13136 continue;
13138 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13139 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13140 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13141 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13143 if (! (type = opaque_ftype_opaque_opaque_opaque))
13144 type = opaque_ftype_opaque_opaque_opaque
13145 = build_function_type_list (opaque_V4SI_type_node,
13146 opaque_V4SI_type_node,
13147 opaque_V4SI_type_node,
13148 opaque_V4SI_type_node,
13149 NULL_TREE);
13151 else
13153 enum insn_code icode = d->icode;
13154 if (d->name == 0 || icode == CODE_FOR_nothing)
13155 continue;
13157 type = builtin_function_type (insn_data[icode].operand[0].mode,
13158 insn_data[icode].operand[1].mode,
13159 insn_data[icode].operand[2].mode,
13160 insn_data[icode].operand[3].mode,
13161 d->code, d->name);
13164 def_builtin (d->mask, d->name, type, d->code);
13167 /* Add the binary operators. */
13168 d = bdesc_2arg;
13169 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13171 enum machine_mode mode0, mode1, mode2;
13172 tree type;
13173 int mask = d->mask;
13175 if ((mask != 0 && (mask & target_flags) == 0)
13176 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13177 continue;
13179 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13180 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13181 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13182 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13184 if (! (type = opaque_ftype_opaque_opaque))
13185 type = opaque_ftype_opaque_opaque
13186 = build_function_type_list (opaque_V4SI_type_node,
13187 opaque_V4SI_type_node,
13188 opaque_V4SI_type_node,
13189 NULL_TREE);
13191 else
13193 enum insn_code icode = d->icode;
13194 if (d->name == 0 || icode == CODE_FOR_nothing)
13195 continue;
13197 mode0 = insn_data[icode].operand[0].mode;
13198 mode1 = insn_data[icode].operand[1].mode;
13199 mode2 = insn_data[icode].operand[2].mode;
13201 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13203 if (! (type = v2si_ftype_v2si_qi))
13204 type = v2si_ftype_v2si_qi
13205 = build_function_type_list (opaque_V2SI_type_node,
13206 opaque_V2SI_type_node,
13207 char_type_node,
13208 NULL_TREE);
13211 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13212 && mode2 == QImode)
13214 if (! (type = v2si_ftype_int_qi))
13215 type = v2si_ftype_int_qi
13216 = build_function_type_list (opaque_V2SI_type_node,
13217 integer_type_node,
13218 char_type_node,
13219 NULL_TREE);
13222 else
13223 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13224 d->code, d->name);
13227 def_builtin (d->mask, d->name, type, d->code);
13230 /* Add the simple unary operators. */
13231 d = (struct builtin_description *) bdesc_1arg;
13232 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13234 enum machine_mode mode0, mode1;
13235 tree type;
13236 int mask = d->mask;
13238 if ((mask != 0 && (mask & target_flags) == 0)
13239 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13240 continue;
13242 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13243 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13244 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13245 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13247 if (! (type = opaque_ftype_opaque))
13248 type = opaque_ftype_opaque
13249 = build_function_type_list (opaque_V4SI_type_node,
13250 opaque_V4SI_type_node,
13251 NULL_TREE);
13253 else
13255 enum insn_code icode = d->icode;
13256 if (d->name == 0 || icode == CODE_FOR_nothing)
13257 continue;
13259 mode0 = insn_data[icode].operand[0].mode;
13260 mode1 = insn_data[icode].operand[1].mode;
13262 if (mode0 == V2SImode && mode1 == QImode)
13264 if (! (type = v2si_ftype_qi))
13265 type = v2si_ftype_qi
13266 = build_function_type_list (opaque_V2SI_type_node,
13267 char_type_node,
13268 NULL_TREE);
13271 else
13272 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13273 d->code, d->name);
13276 def_builtin (d->mask, d->name, type, d->code);
13280 static void
13281 rs6000_init_libfuncs (void)
13283 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13284 && !TARGET_POWER2 && !TARGET_POWERPC)
13286 /* AIX library routines for float->int conversion. */
13287 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13288 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13289 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13290 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13293 if (!TARGET_IEEEQUAD)
13294 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13295 if (!TARGET_XL_COMPAT)
13297 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13298 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13299 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13300 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13302 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13304 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13305 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13306 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13307 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13308 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13309 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13310 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13312 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13313 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13314 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13315 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13316 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13317 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13318 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13319 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13322 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13323 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13325 else
13327 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13328 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13329 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13330 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13332 else
13334 /* 32-bit SVR4 quad floating point routines. */
13336 set_optab_libfunc (add_optab, TFmode, "_q_add");
13337 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13338 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13339 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13340 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13341 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13342 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13344 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13345 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13346 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13347 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13348 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13349 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13351 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13352 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13353 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13354 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13355 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13356 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13357 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13358 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13363 /* Expand a block clear operation, and return 1 if successful. Return 0
13364 if we should let the compiler generate normal code.
13366 operands[0] is the destination
13367 operands[1] is the length
13368 operands[3] is the alignment */
13371 expand_block_clear (rtx operands[])
13373 rtx orig_dest = operands[0];
13374 rtx bytes_rtx = operands[1];
13375 rtx align_rtx = operands[3];
13376 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13377 HOST_WIDE_INT align;
13378 HOST_WIDE_INT bytes;
13379 int offset;
13380 int clear_bytes;
13381 int clear_step;
13383 /* If this is not a fixed size move, just call memcpy */
13384 if (! constp)
13385 return 0;
13387 /* This must be a fixed size alignment */
13388 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13389 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13391 /* Anything to clear? */
13392 bytes = INTVAL (bytes_rtx);
13393 if (bytes <= 0)
13394 return 1;
13396 /* Use the builtin memset after a point, to avoid huge code bloat.
13397 When optimize_size, avoid any significant code bloat; calling
13398 memset is about 4 instructions, so allow for one instruction to
13399 load zero and three to do clearing. */
13400 if (TARGET_ALTIVEC && align >= 128)
13401 clear_step = 16;
13402 else if (TARGET_POWERPC64 && align >= 32)
13403 clear_step = 8;
13404 else if (TARGET_SPE && align >= 64)
13405 clear_step = 8;
13406 else
13407 clear_step = 4;
13409 if (optimize_size && bytes > 3 * clear_step)
13410 return 0;
13411 if (! optimize_size && bytes > 8 * clear_step)
13412 return 0;
13414 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13416 enum machine_mode mode = BLKmode;
13417 rtx dest;
13419 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13421 clear_bytes = 16;
13422 mode = V4SImode;
13424 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13426 clear_bytes = 8;
13427 mode = V2SImode;
13429 else if (bytes >= 8 && TARGET_POWERPC64
13430 /* 64-bit loads and stores require word-aligned
13431 displacements. */
13432 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13434 clear_bytes = 8;
13435 mode = DImode;
13437 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13438 { /* move 4 bytes */
13439 clear_bytes = 4;
13440 mode = SImode;
13442 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13443 { /* move 2 bytes */
13444 clear_bytes = 2;
13445 mode = HImode;
13447 else /* move 1 byte at a time */
13449 clear_bytes = 1;
13450 mode = QImode;
13453 dest = adjust_address (orig_dest, mode, offset);
13455 emit_move_insn (dest, CONST0_RTX (mode));
13458 return 1;
13462 /* Expand a block move operation, and return 1 if successful. Return 0
13463 if we should let the compiler generate normal code.
13465 operands[0] is the destination
13466 operands[1] is the source
13467 operands[2] is the length
13468 operands[3] is the alignment */
13470 #define MAX_MOVE_REG 4
13473 expand_block_move (rtx operands[])
13475 rtx orig_dest = operands[0];
13476 rtx orig_src = operands[1];
13477 rtx bytes_rtx = operands[2];
13478 rtx align_rtx = operands[3];
13479 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13480 int align;
13481 int bytes;
13482 int offset;
13483 int move_bytes;
13484 rtx stores[MAX_MOVE_REG];
13485 int num_reg = 0;
13487 /* If this is not a fixed size move, just call memcpy */
13488 if (! constp)
13489 return 0;
13491 /* This must be a fixed size alignment */
13492 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13493 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13495 /* Anything to move? */
13496 bytes = INTVAL (bytes_rtx);
13497 if (bytes <= 0)
13498 return 1;
13500 if (bytes > rs6000_block_move_inline_limit)
13501 return 0;
13503 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13505 union {
13506 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13507 rtx (*mov) (rtx, rtx);
13508 } gen_func;
13509 enum machine_mode mode = BLKmode;
13510 rtx src, dest;
13512 /* Altivec first, since it will be faster than a string move
13513 when it applies, and usually not significantly larger. */
13514 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13516 move_bytes = 16;
13517 mode = V4SImode;
13518 gen_func.mov = gen_movv4si;
13520 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13522 move_bytes = 8;
13523 mode = V2SImode;
13524 gen_func.mov = gen_movv2si;
13526 else if (TARGET_STRING
13527 && bytes > 24 /* move up to 32 bytes at a time */
13528 && ! fixed_regs[5]
13529 && ! fixed_regs[6]
13530 && ! fixed_regs[7]
13531 && ! fixed_regs[8]
13532 && ! fixed_regs[9]
13533 && ! fixed_regs[10]
13534 && ! fixed_regs[11]
13535 && ! fixed_regs[12])
13537 move_bytes = (bytes > 32) ? 32 : bytes;
13538 gen_func.movmemsi = gen_movmemsi_8reg;
13540 else if (TARGET_STRING
13541 && bytes > 16 /* move up to 24 bytes at a time */
13542 && ! fixed_regs[5]
13543 && ! fixed_regs[6]
13544 && ! fixed_regs[7]
13545 && ! fixed_regs[8]
13546 && ! fixed_regs[9]
13547 && ! fixed_regs[10])
13549 move_bytes = (bytes > 24) ? 24 : bytes;
13550 gen_func.movmemsi = gen_movmemsi_6reg;
13552 else if (TARGET_STRING
13553 && bytes > 8 /* move up to 16 bytes at a time */
13554 && ! fixed_regs[5]
13555 && ! fixed_regs[6]
13556 && ! fixed_regs[7]
13557 && ! fixed_regs[8])
13559 move_bytes = (bytes > 16) ? 16 : bytes;
13560 gen_func.movmemsi = gen_movmemsi_4reg;
13562 else if (bytes >= 8 && TARGET_POWERPC64
13563 /* 64-bit loads and stores require word-aligned
13564 displacements. */
13565 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13567 move_bytes = 8;
13568 mode = DImode;
13569 gen_func.mov = gen_movdi;
13571 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13572 { /* move up to 8 bytes at a time */
13573 move_bytes = (bytes > 8) ? 8 : bytes;
13574 gen_func.movmemsi = gen_movmemsi_2reg;
13576 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13577 { /* move 4 bytes */
13578 move_bytes = 4;
13579 mode = SImode;
13580 gen_func.mov = gen_movsi;
13582 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13583 { /* move 2 bytes */
13584 move_bytes = 2;
13585 mode = HImode;
13586 gen_func.mov = gen_movhi;
13588 else if (TARGET_STRING && bytes > 1)
13589 { /* move up to 4 bytes at a time */
13590 move_bytes = (bytes > 4) ? 4 : bytes;
13591 gen_func.movmemsi = gen_movmemsi_1reg;
13593 else /* move 1 byte at a time */
13595 move_bytes = 1;
13596 mode = QImode;
13597 gen_func.mov = gen_movqi;
13600 src = adjust_address (orig_src, mode, offset);
13601 dest = adjust_address (orig_dest, mode, offset);
13603 if (mode != BLKmode)
13605 rtx tmp_reg = gen_reg_rtx (mode);
13607 emit_insn ((*gen_func.mov) (tmp_reg, src));
13608 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13611 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13613 int i;
13614 for (i = 0; i < num_reg; i++)
13615 emit_insn (stores[i]);
13616 num_reg = 0;
13619 if (mode == BLKmode)
13621 /* Move the address into scratch registers. The movmemsi
13622 patterns require zero offset. */
13623 if (!REG_P (XEXP (src, 0)))
13625 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13626 src = replace_equiv_address (src, src_reg);
13628 set_mem_size (src, move_bytes);
13630 if (!REG_P (XEXP (dest, 0)))
13632 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13633 dest = replace_equiv_address (dest, dest_reg);
13635 set_mem_size (dest, move_bytes);
13637 emit_insn ((*gen_func.movmemsi) (dest, src,
13638 GEN_INT (move_bytes & 31),
13639 align_rtx));
13643 return 1;
13647 /* Return a string to perform a load_multiple operation.
13648 operands[0] is the vector.
13649 operands[1] is the source address.
13650 operands[2] is the first destination register. */
13652 const char *
13653 rs6000_output_load_multiple (rtx operands[3])
13655 /* We have to handle the case where the pseudo used to contain the address
13656 is assigned to one of the output registers. */
13657 int i, j;
13658 int words = XVECLEN (operands[0], 0);
13659 rtx xop[10];
13661 if (XVECLEN (operands[0], 0) == 1)
13662 return "{l|lwz} %2,0(%1)";
13664 for (i = 0; i < words; i++)
13665 if (refers_to_regno_p (REGNO (operands[2]) + i,
13666 REGNO (operands[2]) + i + 1, operands[1], 0))
13668 if (i == words-1)
13670 xop[0] = GEN_INT (4 * (words-1));
13671 xop[1] = operands[1];
13672 xop[2] = operands[2];
13673 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13674 return "";
13676 else if (i == 0)
13678 xop[0] = GEN_INT (4 * (words-1));
13679 xop[1] = operands[1];
13680 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13681 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);
13682 return "";
13684 else
13686 for (j = 0; j < words; j++)
13687 if (j != i)
13689 xop[0] = GEN_INT (j * 4);
13690 xop[1] = operands[1];
13691 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13692 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13694 xop[0] = GEN_INT (i * 4);
13695 xop[1] = operands[1];
13696 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13697 return "";
13701 return "{lsi|lswi} %2,%1,%N0";
13705 /* A validation routine: say whether CODE, a condition code, and MODE
13706 match. The other alternatives either don't make sense or should
13707 never be generated. */
13709 void
13710 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13712 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13713 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13714 && GET_MODE_CLASS (mode) == MODE_CC);
13716 /* These don't make sense. */
13717 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13718 || mode != CCUNSmode);
13720 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13721 || mode == CCUNSmode);
13723 gcc_assert (mode == CCFPmode
13724 || (code != ORDERED && code != UNORDERED
13725 && code != UNEQ && code != LTGT
13726 && code != UNGT && code != UNLT
13727 && code != UNGE && code != UNLE));
13729 /* These should never be generated except for
13730 flag_finite_math_only. */
13731 gcc_assert (mode != CCFPmode
13732 || flag_finite_math_only
13733 || (code != LE && code != GE
13734 && code != UNEQ && code != LTGT
13735 && code != UNGT && code != UNLT));
13737 /* These are invalid; the information is not there. */
13738 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13742 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13743 mask required to convert the result of a rotate insn into a shift
13744 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13747 includes_lshift_p (rtx shiftop, rtx andop)
13749 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13751 shift_mask <<= INTVAL (shiftop);
13753 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13756 /* Similar, but for right shift. */
13759 includes_rshift_p (rtx shiftop, rtx andop)
13761 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13763 shift_mask >>= INTVAL (shiftop);
13765 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13768 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13769 to perform a left shift. It must have exactly SHIFTOP least
13770 significant 0's, then one or more 1's, then zero or more 0's. */
13773 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13775 if (GET_CODE (andop) == CONST_INT)
13777 HOST_WIDE_INT c, lsb, shift_mask;
13779 c = INTVAL (andop);
13780 if (c == 0 || c == ~0)
13781 return 0;
13783 shift_mask = ~0;
13784 shift_mask <<= INTVAL (shiftop);
13786 /* Find the least significant one bit. */
13787 lsb = c & -c;
13789 /* It must coincide with the LSB of the shift mask. */
13790 if (-lsb != shift_mask)
13791 return 0;
13793 /* Invert to look for the next transition (if any). */
13794 c = ~c;
13796 /* Remove the low group of ones (originally low group of zeros). */
13797 c &= -lsb;
13799 /* Again find the lsb, and check we have all 1's above. */
13800 lsb = c & -c;
13801 return c == -lsb;
13803 else if (GET_CODE (andop) == CONST_DOUBLE
13804 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13806 HOST_WIDE_INT low, high, lsb;
13807 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13809 low = CONST_DOUBLE_LOW (andop);
13810 if (HOST_BITS_PER_WIDE_INT < 64)
13811 high = CONST_DOUBLE_HIGH (andop);
13813 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13814 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13815 return 0;
13817 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13819 shift_mask_high = ~0;
13820 if (INTVAL (shiftop) > 32)
13821 shift_mask_high <<= INTVAL (shiftop) - 32;
13823 lsb = high & -high;
13825 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13826 return 0;
13828 high = ~high;
13829 high &= -lsb;
13831 lsb = high & -high;
13832 return high == -lsb;
13835 shift_mask_low = ~0;
13836 shift_mask_low <<= INTVAL (shiftop);
13838 lsb = low & -low;
13840 if (-lsb != shift_mask_low)
13841 return 0;
13843 if (HOST_BITS_PER_WIDE_INT < 64)
13844 high = ~high;
13845 low = ~low;
13846 low &= -lsb;
13848 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13850 lsb = high & -high;
13851 return high == -lsb;
13854 lsb = low & -low;
13855 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13857 else
13858 return 0;
13861 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13862 to perform a left shift. It must have SHIFTOP or more least
13863 significant 0's, with the remainder of the word 1's. */
13866 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13868 if (GET_CODE (andop) == CONST_INT)
13870 HOST_WIDE_INT c, lsb, shift_mask;
13872 shift_mask = ~0;
13873 shift_mask <<= INTVAL (shiftop);
13874 c = INTVAL (andop);
13876 /* Find the least significant one bit. */
13877 lsb = c & -c;
13879 /* It must be covered by the shift mask.
13880 This test also rejects c == 0. */
13881 if ((lsb & shift_mask) == 0)
13882 return 0;
13884 /* Check we have all 1's above the transition, and reject all 1's. */
13885 return c == -lsb && lsb != 1;
13887 else if (GET_CODE (andop) == CONST_DOUBLE
13888 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13890 HOST_WIDE_INT low, lsb, shift_mask_low;
13892 low = CONST_DOUBLE_LOW (andop);
13894 if (HOST_BITS_PER_WIDE_INT < 64)
13896 HOST_WIDE_INT high, shift_mask_high;
13898 high = CONST_DOUBLE_HIGH (andop);
13900 if (low == 0)
13902 shift_mask_high = ~0;
13903 if (INTVAL (shiftop) > 32)
13904 shift_mask_high <<= INTVAL (shiftop) - 32;
13906 lsb = high & -high;
13908 if ((lsb & shift_mask_high) == 0)
13909 return 0;
13911 return high == -lsb;
13913 if (high != ~0)
13914 return 0;
13917 shift_mask_low = ~0;
13918 shift_mask_low <<= INTVAL (shiftop);
13920 lsb = low & -low;
13922 if ((lsb & shift_mask_low) == 0)
13923 return 0;
13925 return low == -lsb && lsb != 1;
13927 else
13928 return 0;
13931 /* Return 1 if operands will generate a valid arguments to rlwimi
13932 instruction for insert with right shift in 64-bit mode. The mask may
13933 not start on the first bit or stop on the last bit because wrap-around
13934 effects of instruction do not correspond to semantics of RTL insn. */
13937 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13939 if (INTVAL (startop) > 32
13940 && INTVAL (startop) < 64
13941 && INTVAL (sizeop) > 1
13942 && INTVAL (sizeop) + INTVAL (startop) < 64
13943 && INTVAL (shiftop) > 0
13944 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13945 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13946 return 1;
13948 return 0;
13951 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13952 for lfq and stfq insns iff the registers are hard registers. */
13955 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13957 /* We might have been passed a SUBREG. */
13958 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13959 return 0;
13961 /* We might have been passed non floating point registers. */
13962 if (!FP_REGNO_P (REGNO (reg1))
13963 || !FP_REGNO_P (REGNO (reg2)))
13964 return 0;
13966 return (REGNO (reg1) == REGNO (reg2) - 1);
13969 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13970 addr1 and addr2 must be in consecutive memory locations
13971 (addr2 == addr1 + 8). */
13974 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13976 rtx addr1, addr2;
13977 unsigned int reg1, reg2;
13978 int offset1, offset2;
13980 /* The mems cannot be volatile. */
13981 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13982 return 0;
13984 addr1 = XEXP (mem1, 0);
13985 addr2 = XEXP (mem2, 0);
13987 /* Extract an offset (if used) from the first addr. */
13988 if (GET_CODE (addr1) == PLUS)
13990 /* If not a REG, return zero. */
13991 if (GET_CODE (XEXP (addr1, 0)) != REG)
13992 return 0;
13993 else
13995 reg1 = REGNO (XEXP (addr1, 0));
13996 /* The offset must be constant! */
13997 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13998 return 0;
13999 offset1 = INTVAL (XEXP (addr1, 1));
14002 else if (GET_CODE (addr1) != REG)
14003 return 0;
14004 else
14006 reg1 = REGNO (addr1);
14007 /* This was a simple (mem (reg)) expression. Offset is 0. */
14008 offset1 = 0;
14011 /* And now for the second addr. */
14012 if (GET_CODE (addr2) == PLUS)
14014 /* If not a REG, return zero. */
14015 if (GET_CODE (XEXP (addr2, 0)) != REG)
14016 return 0;
14017 else
14019 reg2 = REGNO (XEXP (addr2, 0));
14020 /* The offset must be constant. */
14021 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14022 return 0;
14023 offset2 = INTVAL (XEXP (addr2, 1));
14026 else if (GET_CODE (addr2) != REG)
14027 return 0;
14028 else
14030 reg2 = REGNO (addr2);
14031 /* This was a simple (mem (reg)) expression. Offset is 0. */
14032 offset2 = 0;
14035 /* Both of these must have the same base register. */
14036 if (reg1 != reg2)
14037 return 0;
14039 /* The offset for the second addr must be 8 more than the first addr. */
14040 if (offset2 != offset1 + 8)
14041 return 0;
14043 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14044 instructions. */
14045 return 1;
14050 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14052 static bool eliminated = false;
14053 rtx ret;
14055 if (mode != SDmode)
14056 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14057 else
14059 rtx mem = cfun->machine->sdmode_stack_slot;
14060 gcc_assert (mem != NULL_RTX);
14062 if (!eliminated)
14064 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14065 cfun->machine->sdmode_stack_slot = mem;
14066 eliminated = true;
14068 ret = mem;
14071 if (TARGET_DEBUG_ADDR)
14073 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14074 GET_MODE_NAME (mode));
14075 if (!ret)
14076 fprintf (stderr, "\tNULL_RTX\n");
14077 else
14078 debug_rtx (ret);
14081 return ret;
14084 static tree
14085 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14087 /* Don't walk into types. */
14088 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14090 *walk_subtrees = 0;
14091 return NULL_TREE;
14094 switch (TREE_CODE (*tp))
14096 case VAR_DECL:
14097 case PARM_DECL:
14098 case FIELD_DECL:
14099 case RESULT_DECL:
14100 case SSA_NAME:
14101 case REAL_CST:
14102 case MEM_REF:
14103 case VIEW_CONVERT_EXPR:
14104 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14105 return *tp;
14106 break;
14107 default:
14108 break;
14111 return NULL_TREE;
14114 enum reload_reg_type {
14115 GPR_REGISTER_TYPE,
14116 VECTOR_REGISTER_TYPE,
14117 OTHER_REGISTER_TYPE
14120 static enum reload_reg_type
14121 rs6000_reload_register_type (enum reg_class rclass)
14123 switch (rclass)
14125 case GENERAL_REGS:
14126 case BASE_REGS:
14127 return GPR_REGISTER_TYPE;
14129 case FLOAT_REGS:
14130 case ALTIVEC_REGS:
14131 case VSX_REGS:
14132 return VECTOR_REGISTER_TYPE;
14134 default:
14135 return OTHER_REGISTER_TYPE;
14139 /* Inform reload about cases where moving X with a mode MODE to a register in
14140 RCLASS requires an extra scratch or immediate register. Return the class
14141 needed for the immediate register.
14143 For VSX and Altivec, we may need a register to convert sp+offset into
14144 reg+sp.
14146 For misaligned 64-bit gpr loads and stores we need a register to
14147 convert an offset address to indirect. */
14149 static reg_class_t
14150 rs6000_secondary_reload (bool in_p,
14151 rtx x,
14152 reg_class_t rclass_i,
14153 enum machine_mode mode,
14154 secondary_reload_info *sri)
14156 enum reg_class rclass = (enum reg_class) rclass_i;
14157 reg_class_t ret = ALL_REGS;
14158 enum insn_code icode;
14159 bool default_p = false;
14161 sri->icode = CODE_FOR_nothing;
14163 /* Convert vector loads and stores into gprs to use an additional base
14164 register. */
14165 icode = rs6000_vector_reload[mode][in_p != false];
14166 if (icode != CODE_FOR_nothing)
14168 ret = NO_REGS;
14169 sri->icode = CODE_FOR_nothing;
14170 sri->extra_cost = 0;
14172 if (GET_CODE (x) == MEM)
14174 rtx addr = XEXP (x, 0);
14176 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14177 an extra register in that case, but it would need an extra
14178 register if the addressing is reg+reg or (reg+reg)&(-16). */
14179 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14181 if (!legitimate_indirect_address_p (addr, false)
14182 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14184 sri->icode = icode;
14185 /* account for splitting the loads, and converting the
14186 address from reg+reg to reg. */
14187 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14188 + ((GET_CODE (addr) == AND) ? 1 : 0));
14191 /* Loads to and stores from vector registers can only do reg+reg
14192 addressing. Altivec registers can also do (reg+reg)&(-16). */
14193 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14194 || rclass == FLOAT_REGS || rclass == NO_REGS)
14196 if (!VECTOR_MEM_ALTIVEC_P (mode)
14197 && GET_CODE (addr) == AND
14198 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14199 && INTVAL (XEXP (addr, 1)) == -16
14200 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14201 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14203 sri->icode = icode;
14204 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14205 ? 2 : 1);
14207 else if (!legitimate_indirect_address_p (addr, false)
14208 && (rclass == NO_REGS
14209 || !legitimate_indexed_address_p (addr, false)))
14211 sri->icode = icode;
14212 sri->extra_cost = 1;
14214 else
14215 icode = CODE_FOR_nothing;
14217 /* Any other loads, including to pseudo registers which haven't been
14218 assigned to a register yet, default to require a scratch
14219 register. */
14220 else
14222 sri->icode = icode;
14223 sri->extra_cost = 2;
14226 else if (REG_P (x))
14228 int regno = true_regnum (x);
14230 icode = CODE_FOR_nothing;
14231 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14232 default_p = true;
14233 else
14235 enum reg_class xclass = REGNO_REG_CLASS (regno);
14236 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14237 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14239 /* If memory is needed, use default_secondary_reload to create the
14240 stack slot. */
14241 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14242 default_p = true;
14243 else
14244 ret = NO_REGS;
14247 else
14248 default_p = true;
14250 else if (TARGET_POWERPC64
14251 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14252 && MEM_P (x)
14253 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14255 rtx addr = XEXP (x, 0);
14257 if (GET_CODE (addr) == PRE_MODIFY)
14258 addr = XEXP (addr, 1);
14259 else if (GET_CODE (addr) == LO_SUM
14260 && GET_CODE (XEXP (addr, 0)) == REG
14261 && GET_CODE (XEXP (addr, 1)) == CONST)
14262 addr = XEXP (XEXP (addr, 1), 0);
14264 if (GET_CODE (addr) == PLUS
14265 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14266 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14268 if (in_p)
14269 sri->icode = CODE_FOR_reload_di_load;
14270 else
14271 sri->icode = CODE_FOR_reload_di_store;
14272 sri->extra_cost = 2;
14273 ret = NO_REGS;
14275 else
14276 default_p = true;
14278 else
14279 default_p = true;
14281 if (default_p)
14282 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14284 gcc_assert (ret != ALL_REGS);
14286 if (TARGET_DEBUG_ADDR)
14288 fprintf (stderr,
14289 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14290 "mode = %s",
14291 reg_class_names[ret],
14292 in_p ? "true" : "false",
14293 reg_class_names[rclass],
14294 GET_MODE_NAME (mode));
14296 if (default_p)
14297 fprintf (stderr, ", default secondary reload");
14299 if (sri->icode != CODE_FOR_nothing)
14300 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14301 insn_data[sri->icode].name, sri->extra_cost);
14302 else
14303 fprintf (stderr, "\n");
14305 debug_rtx (x);
14308 return ret;
14311 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14312 to SP+reg addressing. */
14314 void
14315 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14317 int regno = true_regnum (reg);
14318 enum machine_mode mode = GET_MODE (reg);
14319 enum reg_class rclass;
14320 rtx addr;
14321 rtx and_op2 = NULL_RTX;
14322 rtx addr_op1;
14323 rtx addr_op2;
14324 rtx scratch_or_premodify = scratch;
14325 rtx and_rtx;
14326 rtx cc_clobber;
14328 if (TARGET_DEBUG_ADDR)
14330 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14331 store_p ? "store" : "load");
14332 fprintf (stderr, "reg:\n");
14333 debug_rtx (reg);
14334 fprintf (stderr, "mem:\n");
14335 debug_rtx (mem);
14336 fprintf (stderr, "scratch:\n");
14337 debug_rtx (scratch);
14340 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14341 gcc_assert (GET_CODE (mem) == MEM);
14342 rclass = REGNO_REG_CLASS (regno);
14343 addr = XEXP (mem, 0);
14345 switch (rclass)
14347 /* GPRs can handle reg + small constant, all other addresses need to use
14348 the scratch register. */
14349 case GENERAL_REGS:
14350 case BASE_REGS:
14351 if (GET_CODE (addr) == AND)
14353 and_op2 = XEXP (addr, 1);
14354 addr = XEXP (addr, 0);
14357 if (GET_CODE (addr) == PRE_MODIFY)
14359 scratch_or_premodify = XEXP (addr, 0);
14360 gcc_assert (REG_P (scratch_or_premodify));
14361 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14362 addr = XEXP (addr, 1);
14365 if (GET_CODE (addr) == PLUS
14366 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14367 || and_op2 != NULL_RTX))
14369 addr_op1 = XEXP (addr, 0);
14370 addr_op2 = XEXP (addr, 1);
14371 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14373 if (!REG_P (addr_op2)
14374 && (GET_CODE (addr_op2) != CONST_INT
14375 || !satisfies_constraint_I (addr_op2)))
14377 if (TARGET_DEBUG_ADDR)
14379 fprintf (stderr,
14380 "\nMove plus addr to register %s, mode = %s: ",
14381 rs6000_reg_names[REGNO (scratch)],
14382 GET_MODE_NAME (mode));
14383 debug_rtx (addr_op2);
14385 rs6000_emit_move (scratch, addr_op2, Pmode);
14386 addr_op2 = scratch;
14389 emit_insn (gen_rtx_SET (VOIDmode,
14390 scratch_or_premodify,
14391 gen_rtx_PLUS (Pmode,
14392 addr_op1,
14393 addr_op2)));
14395 addr = scratch_or_premodify;
14396 scratch_or_premodify = scratch;
14398 else if (!legitimate_indirect_address_p (addr, false)
14399 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14401 if (TARGET_DEBUG_ADDR)
14403 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14404 rs6000_reg_names[REGNO (scratch_or_premodify)],
14405 GET_MODE_NAME (mode));
14406 debug_rtx (addr);
14408 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14409 addr = scratch_or_premodify;
14410 scratch_or_premodify = scratch;
14412 break;
14414 /* Float/Altivec registers can only handle reg+reg addressing. Move
14415 other addresses into a scratch register. */
14416 case FLOAT_REGS:
14417 case VSX_REGS:
14418 case ALTIVEC_REGS:
14420 /* With float regs, we need to handle the AND ourselves, since we can't
14421 use the Altivec instruction with an implicit AND -16. Allow scalar
14422 loads to float registers to use reg+offset even if VSX. */
14423 if (GET_CODE (addr) == AND
14424 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14425 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14426 || INTVAL (XEXP (addr, 1)) != -16
14427 || !VECTOR_MEM_ALTIVEC_P (mode)))
14429 and_op2 = XEXP (addr, 1);
14430 addr = XEXP (addr, 0);
14433 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14434 as the address later. */
14435 if (GET_CODE (addr) == PRE_MODIFY
14436 && (!VECTOR_MEM_VSX_P (mode)
14437 || and_op2 != NULL_RTX
14438 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14440 scratch_or_premodify = XEXP (addr, 0);
14441 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14442 false));
14443 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14444 addr = XEXP (addr, 1);
14447 if (legitimate_indirect_address_p (addr, false) /* reg */
14448 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14449 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14450 || (GET_CODE (addr) == AND /* Altivec memory */
14451 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14452 && INTVAL (XEXP (addr, 1)) == -16
14453 && VECTOR_MEM_ALTIVEC_P (mode))
14454 || (rclass == FLOAT_REGS /* legacy float mem */
14455 && GET_MODE_SIZE (mode) == 8
14456 && and_op2 == NULL_RTX
14457 && scratch_or_premodify == scratch
14458 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14461 else if (GET_CODE (addr) == PLUS)
14463 addr_op1 = XEXP (addr, 0);
14464 addr_op2 = XEXP (addr, 1);
14465 gcc_assert (REG_P (addr_op1));
14467 if (TARGET_DEBUG_ADDR)
14469 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14470 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14471 debug_rtx (addr_op2);
14473 rs6000_emit_move (scratch, addr_op2, Pmode);
14474 emit_insn (gen_rtx_SET (VOIDmode,
14475 scratch_or_premodify,
14476 gen_rtx_PLUS (Pmode,
14477 addr_op1,
14478 scratch)));
14479 addr = scratch_or_premodify;
14480 scratch_or_premodify = scratch;
14483 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14484 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14486 if (TARGET_DEBUG_ADDR)
14488 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14489 rs6000_reg_names[REGNO (scratch_or_premodify)],
14490 GET_MODE_NAME (mode));
14491 debug_rtx (addr);
14494 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14495 addr = scratch_or_premodify;
14496 scratch_or_premodify = scratch;
14499 else
14500 gcc_unreachable ();
14502 break;
14504 default:
14505 gcc_unreachable ();
14508 /* If the original address involved a pre-modify that we couldn't use the VSX
14509 memory instruction with update, and we haven't taken care of already,
14510 store the address in the pre-modify register and use that as the
14511 address. */
14512 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14514 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14515 addr = scratch_or_premodify;
14518 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14519 memory instruction, recreate the AND now, including the clobber which is
14520 generated by the general ANDSI3/ANDDI3 patterns for the
14521 andi. instruction. */
14522 if (and_op2 != NULL_RTX)
14524 if (! legitimate_indirect_address_p (addr, false))
14526 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14527 addr = scratch;
14530 if (TARGET_DEBUG_ADDR)
14532 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14533 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14534 debug_rtx (and_op2);
14537 and_rtx = gen_rtx_SET (VOIDmode,
14538 scratch,
14539 gen_rtx_AND (Pmode,
14540 addr,
14541 and_op2));
14543 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14544 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14545 gen_rtvec (2, and_rtx, cc_clobber)));
14546 addr = scratch;
14549 /* Adjust the address if it changed. */
14550 if (addr != XEXP (mem, 0))
14552 mem = change_address (mem, mode, addr);
14553 if (TARGET_DEBUG_ADDR)
14554 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14557 /* Now create the move. */
14558 if (store_p)
14559 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14560 else
14561 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14563 return;
14566 /* Convert reloads involving 64-bit gprs and misaligned offset
14567 addressing to use indirect addressing. */
14569 void
14570 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
14572 int regno = true_regnum (reg);
14573 enum reg_class rclass;
14574 rtx addr;
14575 rtx scratch_or_premodify = scratch;
14577 if (TARGET_DEBUG_ADDR)
14579 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
14580 store_p ? "store" : "load");
14581 fprintf (stderr, "reg:\n");
14582 debug_rtx (reg);
14583 fprintf (stderr, "mem:\n");
14584 debug_rtx (mem);
14585 fprintf (stderr, "scratch:\n");
14586 debug_rtx (scratch);
14589 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14590 gcc_assert (GET_CODE (mem) == MEM);
14591 rclass = REGNO_REG_CLASS (regno);
14592 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
14593 addr = XEXP (mem, 0);
14595 if (GET_CODE (addr) == PRE_MODIFY)
14597 scratch_or_premodify = XEXP (addr, 0);
14598 gcc_assert (REG_P (scratch_or_premodify));
14599 addr = XEXP (addr, 1);
14601 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14603 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14605 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
14607 /* Now create the move. */
14608 if (store_p)
14609 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14610 else
14611 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14613 return;
14616 /* Allocate a 64-bit stack slot to be used for copying SDmode
14617 values through if this function has any SDmode references. */
14619 static void
14620 rs6000_alloc_sdmode_stack_slot (void)
14622 tree t;
14623 basic_block bb;
14624 gimple_stmt_iterator gsi;
14626 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14628 FOR_EACH_BB (bb)
14629 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14631 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14632 if (ret)
14634 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14635 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14636 SDmode, 0);
14637 return;
14641 /* Check for any SDmode parameters of the function. */
14642 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14644 if (TREE_TYPE (t) == error_mark_node)
14645 continue;
14647 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14648 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14650 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14651 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14652 SDmode, 0);
14653 return;
14658 static void
14659 rs6000_instantiate_decls (void)
14661 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14662 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14665 /* Given an rtx X being reloaded into a reg required to be
14666 in class CLASS, return the class of reg to actually use.
14667 In general this is just CLASS; but on some machines
14668 in some cases it is preferable to use a more restrictive class.
14670 On the RS/6000, we have to return NO_REGS when we want to reload a
14671 floating-point CONST_DOUBLE to force it to be copied to memory.
14673 We also don't want to reload integer values into floating-point
14674 registers if we can at all help it. In fact, this can
14675 cause reload to die, if it tries to generate a reload of CTR
14676 into a FP register and discovers it doesn't have the memory location
14677 required.
14679 ??? Would it be a good idea to have reload do the converse, that is
14680 try to reload floating modes into FP registers if possible?
14683 static enum reg_class
14684 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14686 enum machine_mode mode = GET_MODE (x);
14688 if (VECTOR_UNIT_VSX_P (mode)
14689 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14690 return rclass;
14692 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14693 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14694 && easy_vector_constant (x, mode))
14695 return ALTIVEC_REGS;
14697 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14698 return NO_REGS;
14700 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14701 return GENERAL_REGS;
14703 /* For VSX, prefer the traditional registers for 64-bit values because we can
14704 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14705 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14706 prefer Altivec loads.. */
14707 if (rclass == VSX_REGS)
14709 if (GET_MODE_SIZE (mode) <= 8)
14710 return FLOAT_REGS;
14712 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14713 return ALTIVEC_REGS;
14715 return rclass;
14718 return rclass;
14721 /* Debug version of rs6000_preferred_reload_class. */
14722 static enum reg_class
14723 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14725 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14727 fprintf (stderr,
14728 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14729 "mode = %s, x:\n",
14730 reg_class_names[ret], reg_class_names[rclass],
14731 GET_MODE_NAME (GET_MODE (x)));
14732 debug_rtx (x);
14734 return ret;
14737 /* If we are copying between FP or AltiVec registers and anything else, we need
14738 a memory location. The exception is when we are targeting ppc64 and the
14739 move to/from fpr to gpr instructions are available. Also, under VSX, you
14740 can copy vector registers from the FP register set to the Altivec register
14741 set and vice versa. */
14743 static bool
14744 rs6000_secondary_memory_needed (enum reg_class class1,
14745 enum reg_class class2,
14746 enum machine_mode mode)
14748 if (class1 == class2)
14749 return false;
14751 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14752 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14753 between these classes. But we need memory for other things that can go in
14754 FLOAT_REGS like SFmode. */
14755 if (TARGET_VSX
14756 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14757 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14758 || class1 == FLOAT_REGS))
14759 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14760 && class2 != FLOAT_REGS);
14762 if (class1 == VSX_REGS || class2 == VSX_REGS)
14763 return true;
14765 if (class1 == FLOAT_REGS
14766 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14767 || ((mode != DFmode)
14768 && (mode != DDmode)
14769 && (mode != DImode))))
14770 return true;
14772 if (class2 == FLOAT_REGS
14773 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14774 || ((mode != DFmode)
14775 && (mode != DDmode)
14776 && (mode != DImode))))
14777 return true;
14779 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14780 return true;
14782 return false;
14785 /* Debug version of rs6000_secondary_memory_needed. */
14786 static bool
14787 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14788 enum reg_class class2,
14789 enum machine_mode mode)
14791 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14793 fprintf (stderr,
14794 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14795 "class2 = %s, mode = %s\n",
14796 ret ? "true" : "false", reg_class_names[class1],
14797 reg_class_names[class2], GET_MODE_NAME (mode));
14799 return ret;
14802 /* Return the register class of a scratch register needed to copy IN into
14803 or out of a register in RCLASS in MODE. If it can be done directly,
14804 NO_REGS is returned. */
14806 static enum reg_class
14807 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14808 rtx in)
14810 int regno;
14812 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14813 #if TARGET_MACHO
14814 && MACHOPIC_INDIRECT
14815 #endif
14818 /* We cannot copy a symbolic operand directly into anything
14819 other than BASE_REGS for TARGET_ELF. So indicate that a
14820 register from BASE_REGS is needed as an intermediate
14821 register.
14823 On Darwin, pic addresses require a load from memory, which
14824 needs a base register. */
14825 if (rclass != BASE_REGS
14826 && (GET_CODE (in) == SYMBOL_REF
14827 || GET_CODE (in) == HIGH
14828 || GET_CODE (in) == LABEL_REF
14829 || GET_CODE (in) == CONST))
14830 return BASE_REGS;
14833 if (GET_CODE (in) == REG)
14835 regno = REGNO (in);
14836 if (regno >= FIRST_PSEUDO_REGISTER)
14838 regno = true_regnum (in);
14839 if (regno >= FIRST_PSEUDO_REGISTER)
14840 regno = -1;
14843 else if (GET_CODE (in) == SUBREG)
14845 regno = true_regnum (in);
14846 if (regno >= FIRST_PSEUDO_REGISTER)
14847 regno = -1;
14849 else
14850 regno = -1;
14852 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14853 into anything. */
14854 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14855 || (regno >= 0 && INT_REGNO_P (regno)))
14856 return NO_REGS;
14858 /* Constants, memory, and FP registers can go into FP registers. */
14859 if ((regno == -1 || FP_REGNO_P (regno))
14860 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14861 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14863 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14864 VSX. */
14865 if (TARGET_VSX
14866 && (regno == -1 || VSX_REGNO_P (regno))
14867 && VSX_REG_CLASS_P (rclass))
14868 return NO_REGS;
14870 /* Memory, and AltiVec registers can go into AltiVec registers. */
14871 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14872 && rclass == ALTIVEC_REGS)
14873 return NO_REGS;
14875 /* We can copy among the CR registers. */
14876 if ((rclass == CR_REGS || rclass == CR0_REGS)
14877 && regno >= 0 && CR_REGNO_P (regno))
14878 return NO_REGS;
14880 /* Otherwise, we need GENERAL_REGS. */
14881 return GENERAL_REGS;
14884 /* Debug version of rs6000_secondary_reload_class. */
14885 static enum reg_class
14886 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14887 enum machine_mode mode, rtx in)
14889 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14890 fprintf (stderr,
14891 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14892 "mode = %s, input rtx:\n",
14893 reg_class_names[ret], reg_class_names[rclass],
14894 GET_MODE_NAME (mode));
14895 debug_rtx (in);
14897 return ret;
14900 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14902 static bool
14903 rs6000_cannot_change_mode_class (enum machine_mode from,
14904 enum machine_mode to,
14905 enum reg_class rclass)
14907 unsigned from_size = GET_MODE_SIZE (from);
14908 unsigned to_size = GET_MODE_SIZE (to);
14910 if (from_size != to_size)
14912 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14913 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14914 && reg_classes_intersect_p (xclass, rclass));
14917 if (TARGET_E500_DOUBLE
14918 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14919 || (((to) == TFmode) + ((from) == TFmode)) == 1
14920 || (((to) == DDmode) + ((from) == DDmode)) == 1
14921 || (((to) == TDmode) + ((from) == TDmode)) == 1
14922 || (((to) == DImode) + ((from) == DImode)) == 1))
14923 return true;
14925 /* Since the VSX register set includes traditional floating point registers
14926 and altivec registers, just check for the size being different instead of
14927 trying to check whether the modes are vector modes. Otherwise it won't
14928 allow say DF and DI to change classes. */
14929 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14930 return (from_size != 8 && from_size != 16);
14932 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14933 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14934 return true;
14936 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14937 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14938 return true;
14940 return false;
14943 /* Debug version of rs6000_cannot_change_mode_class. */
14944 static bool
14945 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14946 enum machine_mode to,
14947 enum reg_class rclass)
14949 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14951 fprintf (stderr,
14952 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14953 "to = %s, rclass = %s\n",
14954 ret ? "true" : "false",
14955 GET_MODE_NAME (from), GET_MODE_NAME (to),
14956 reg_class_names[rclass]);
14958 return ret;
14961 /* Given a comparison operation, return the bit number in CCR to test. We
14962 know this is a valid comparison.
14964 SCC_P is 1 if this is for an scc. That means that %D will have been
14965 used instead of %C, so the bits will be in different places.
14967 Return -1 if OP isn't a valid comparison for some reason. */
14970 ccr_bit (rtx op, int scc_p)
14972 enum rtx_code code = GET_CODE (op);
14973 enum machine_mode cc_mode;
14974 int cc_regnum;
14975 int base_bit;
14976 rtx reg;
14978 if (!COMPARISON_P (op))
14979 return -1;
14981 reg = XEXP (op, 0);
14983 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14985 cc_mode = GET_MODE (reg);
14986 cc_regnum = REGNO (reg);
14987 base_bit = 4 * (cc_regnum - CR0_REGNO);
14989 validate_condition_mode (code, cc_mode);
14991 /* When generating a sCOND operation, only positive conditions are
14992 allowed. */
14993 gcc_assert (!scc_p
14994 || code == EQ || code == GT || code == LT || code == UNORDERED
14995 || code == GTU || code == LTU);
14997 switch (code)
14999 case NE:
15000 return scc_p ? base_bit + 3 : base_bit + 2;
15001 case EQ:
15002 return base_bit + 2;
15003 case GT: case GTU: case UNLE:
15004 return base_bit + 1;
15005 case LT: case LTU: case UNGE:
15006 return base_bit;
15007 case ORDERED: case UNORDERED:
15008 return base_bit + 3;
15010 case GE: case GEU:
15011 /* If scc, we will have done a cror to put the bit in the
15012 unordered position. So test that bit. For integer, this is ! LT
15013 unless this is an scc insn. */
15014 return scc_p ? base_bit + 3 : base_bit;
15016 case LE: case LEU:
15017 return scc_p ? base_bit + 3 : base_bit + 1;
15019 default:
15020 gcc_unreachable ();
15024 /* Return the GOT register. */
15027 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15029 /* The second flow pass currently (June 1999) can't update
15030 regs_ever_live without disturbing other parts of the compiler, so
15031 update it here to make the prolog/epilogue code happy. */
15032 if (!can_create_pseudo_p ()
15033 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15034 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15036 crtl->uses_pic_offset_table = 1;
15038 return pic_offset_table_rtx;
15041 static rs6000_stack_t stack_info;
15043 /* Function to init struct machine_function.
15044 This will be called, via a pointer variable,
15045 from push_function_context. */
15047 static struct machine_function *
15048 rs6000_init_machine_status (void)
15050 stack_info.reload_completed = 0;
15051 return ggc_alloc_cleared_machine_function ();
15054 /* These macros test for integers and extract the low-order bits. */
15055 #define INT_P(X) \
15056 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15057 && GET_MODE (X) == VOIDmode)
15059 #define INT_LOWPART(X) \
15060 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15063 extract_MB (rtx op)
15065 int i;
15066 unsigned long val = INT_LOWPART (op);
15068 /* If the high bit is zero, the value is the first 1 bit we find
15069 from the left. */
15070 if ((val & 0x80000000) == 0)
15072 gcc_assert (val & 0xffffffff);
15074 i = 1;
15075 while (((val <<= 1) & 0x80000000) == 0)
15076 ++i;
15077 return i;
15080 /* If the high bit is set and the low bit is not, or the mask is all
15081 1's, the value is zero. */
15082 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15083 return 0;
15085 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15086 from the right. */
15087 i = 31;
15088 while (((val >>= 1) & 1) != 0)
15089 --i;
15091 return i;
15095 extract_ME (rtx op)
15097 int i;
15098 unsigned long val = INT_LOWPART (op);
15100 /* If the low bit is zero, the value is the first 1 bit we find from
15101 the right. */
15102 if ((val & 1) == 0)
15104 gcc_assert (val & 0xffffffff);
15106 i = 30;
15107 while (((val >>= 1) & 1) == 0)
15108 --i;
15110 return i;
15113 /* If the low bit is set and the high bit is not, or the mask is all
15114 1's, the value is 31. */
15115 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15116 return 31;
15118 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15119 from the left. */
15120 i = 0;
15121 while (((val <<= 1) & 0x80000000) != 0)
15122 ++i;
15124 return i;
15127 /* Locate some local-dynamic symbol still in use by this function
15128 so that we can print its name in some tls_ld pattern. */
15130 static const char *
15131 rs6000_get_some_local_dynamic_name (void)
15133 rtx insn;
15135 if (cfun->machine->some_ld_name)
15136 return cfun->machine->some_ld_name;
15138 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15139 if (INSN_P (insn)
15140 && for_each_rtx (&PATTERN (insn),
15141 rs6000_get_some_local_dynamic_name_1, 0))
15142 return cfun->machine->some_ld_name;
15144 gcc_unreachable ();
15147 /* Helper function for rs6000_get_some_local_dynamic_name. */
15149 static int
15150 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15152 rtx x = *px;
15154 if (GET_CODE (x) == SYMBOL_REF)
15156 const char *str = XSTR (x, 0);
15157 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15159 cfun->machine->some_ld_name = str;
15160 return 1;
15164 return 0;
15167 /* Write out a function code label. */
15169 void
15170 rs6000_output_function_entry (FILE *file, const char *fname)
15172 if (fname[0] != '.')
15174 switch (DEFAULT_ABI)
15176 default:
15177 gcc_unreachable ();
15179 case ABI_AIX:
15180 if (DOT_SYMBOLS)
15181 putc ('.', file);
15182 else
15183 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15184 break;
15186 case ABI_V4:
15187 case ABI_DARWIN:
15188 break;
15192 RS6000_OUTPUT_BASENAME (file, fname);
15195 /* Print an operand. Recognize special options, documented below. */
15197 #if TARGET_ELF
15198 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15199 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15200 #else
15201 #define SMALL_DATA_RELOC "sda21"
15202 #define SMALL_DATA_REG 0
15203 #endif
15205 void
15206 print_operand (FILE *file, rtx x, int code)
15208 int i;
15209 HOST_WIDE_INT val;
15210 unsigned HOST_WIDE_INT uval;
15212 switch (code)
15214 case '.':
15215 /* Write out an instruction after the call which may be replaced
15216 with glue code by the loader. This depends on the AIX version. */
15217 asm_fprintf (file, RS6000_CALL_GLUE);
15218 return;
15220 /* %a is output_address. */
15222 case 'A':
15223 /* If X is a constant integer whose low-order 5 bits are zero,
15224 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15225 in the AIX assembler where "sri" with a zero shift count
15226 writes a trash instruction. */
15227 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15228 putc ('l', file);
15229 else
15230 putc ('r', file);
15231 return;
15233 case 'b':
15234 /* If constant, low-order 16 bits of constant, unsigned.
15235 Otherwise, write normally. */
15236 if (INT_P (x))
15237 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15238 else
15239 print_operand (file, x, 0);
15240 return;
15242 case 'B':
15243 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15244 for 64-bit mask direction. */
15245 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15246 return;
15248 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15249 output_operand. */
15251 case 'c':
15252 /* X is a CR register. Print the number of the GT bit of the CR. */
15253 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15254 output_operand_lossage ("invalid %%c value");
15255 else
15256 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15257 return;
15259 case 'D':
15260 /* Like 'J' but get to the GT bit only. */
15261 gcc_assert (GET_CODE (x) == REG);
15263 /* Bit 1 is GT bit. */
15264 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15266 /* Add one for shift count in rlinm for scc. */
15267 fprintf (file, "%d", i + 1);
15268 return;
15270 case 'E':
15271 /* X is a CR register. Print the number of the EQ bit of the CR */
15272 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15273 output_operand_lossage ("invalid %%E value");
15274 else
15275 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15276 return;
15278 case 'f':
15279 /* X is a CR register. Print the shift count needed to move it
15280 to the high-order four bits. */
15281 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15282 output_operand_lossage ("invalid %%f value");
15283 else
15284 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15285 return;
15287 case 'F':
15288 /* Similar, but print the count for the rotate in the opposite
15289 direction. */
15290 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15291 output_operand_lossage ("invalid %%F value");
15292 else
15293 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15294 return;
15296 case 'G':
15297 /* X is a constant integer. If it is negative, print "m",
15298 otherwise print "z". This is to make an aze or ame insn. */
15299 if (GET_CODE (x) != CONST_INT)
15300 output_operand_lossage ("invalid %%G value");
15301 else if (INTVAL (x) >= 0)
15302 putc ('z', file);
15303 else
15304 putc ('m', file);
15305 return;
15307 case 'h':
15308 /* If constant, output low-order five bits. Otherwise, write
15309 normally. */
15310 if (INT_P (x))
15311 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15312 else
15313 print_operand (file, x, 0);
15314 return;
15316 case 'H':
15317 /* If constant, output low-order six bits. Otherwise, write
15318 normally. */
15319 if (INT_P (x))
15320 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15321 else
15322 print_operand (file, x, 0);
15323 return;
15325 case 'I':
15326 /* Print `i' if this is a constant, else nothing. */
15327 if (INT_P (x))
15328 putc ('i', file);
15329 return;
15331 case 'j':
15332 /* Write the bit number in CCR for jump. */
15333 i = ccr_bit (x, 0);
15334 if (i == -1)
15335 output_operand_lossage ("invalid %%j code");
15336 else
15337 fprintf (file, "%d", i);
15338 return;
15340 case 'J':
15341 /* Similar, but add one for shift count in rlinm for scc and pass
15342 scc flag to `ccr_bit'. */
15343 i = ccr_bit (x, 1);
15344 if (i == -1)
15345 output_operand_lossage ("invalid %%J code");
15346 else
15347 /* If we want bit 31, write a shift count of zero, not 32. */
15348 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15349 return;
15351 case 'k':
15352 /* X must be a constant. Write the 1's complement of the
15353 constant. */
15354 if (! INT_P (x))
15355 output_operand_lossage ("invalid %%k value");
15356 else
15357 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15358 return;
15360 case 'K':
15361 /* X must be a symbolic constant on ELF. Write an
15362 expression suitable for an 'addi' that adds in the low 16
15363 bits of the MEM. */
15364 if (GET_CODE (x) == CONST)
15366 if (GET_CODE (XEXP (x, 0)) != PLUS
15367 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15368 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15369 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15370 output_operand_lossage ("invalid %%K value");
15372 print_operand_address (file, x);
15373 fputs ("@l", file);
15374 return;
15376 /* %l is output_asm_label. */
15378 case 'L':
15379 /* Write second word of DImode or DFmode reference. Works on register
15380 or non-indexed memory only. */
15381 if (GET_CODE (x) == REG)
15382 fputs (reg_names[REGNO (x) + 1], file);
15383 else if (GET_CODE (x) == MEM)
15385 /* Handle possible auto-increment. Since it is pre-increment and
15386 we have already done it, we can just use an offset of word. */
15387 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15388 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15389 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15390 UNITS_PER_WORD));
15391 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15392 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15393 UNITS_PER_WORD));
15394 else
15395 output_address (XEXP (adjust_address_nv (x, SImode,
15396 UNITS_PER_WORD),
15397 0));
15399 if (small_data_operand (x, GET_MODE (x)))
15400 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15401 reg_names[SMALL_DATA_REG]);
15403 return;
15405 case 'm':
15406 /* MB value for a mask operand. */
15407 if (! mask_operand (x, SImode))
15408 output_operand_lossage ("invalid %%m value");
15410 fprintf (file, "%d", extract_MB (x));
15411 return;
15413 case 'M':
15414 /* ME value for a mask operand. */
15415 if (! mask_operand (x, SImode))
15416 output_operand_lossage ("invalid %%M value");
15418 fprintf (file, "%d", extract_ME (x));
15419 return;
15421 /* %n outputs the negative of its operand. */
15423 case 'N':
15424 /* Write the number of elements in the vector times 4. */
15425 if (GET_CODE (x) != PARALLEL)
15426 output_operand_lossage ("invalid %%N value");
15427 else
15428 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15429 return;
15431 case 'O':
15432 /* Similar, but subtract 1 first. */
15433 if (GET_CODE (x) != PARALLEL)
15434 output_operand_lossage ("invalid %%O value");
15435 else
15436 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15437 return;
15439 case 'p':
15440 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15441 if (! INT_P (x)
15442 || INT_LOWPART (x) < 0
15443 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15444 output_operand_lossage ("invalid %%p value");
15445 else
15446 fprintf (file, "%d", i);
15447 return;
15449 case 'P':
15450 /* The operand must be an indirect memory reference. The result
15451 is the register name. */
15452 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15453 || REGNO (XEXP (x, 0)) >= 32)
15454 output_operand_lossage ("invalid %%P value");
15455 else
15456 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15457 return;
15459 case 'q':
15460 /* This outputs the logical code corresponding to a boolean
15461 expression. The expression may have one or both operands
15462 negated (if one, only the first one). For condition register
15463 logical operations, it will also treat the negated
15464 CR codes as NOTs, but not handle NOTs of them. */
15466 const char *const *t = 0;
15467 const char *s;
15468 enum rtx_code code = GET_CODE (x);
15469 static const char * const tbl[3][3] = {
15470 { "and", "andc", "nor" },
15471 { "or", "orc", "nand" },
15472 { "xor", "eqv", "xor" } };
15474 if (code == AND)
15475 t = tbl[0];
15476 else if (code == IOR)
15477 t = tbl[1];
15478 else if (code == XOR)
15479 t = tbl[2];
15480 else
15481 output_operand_lossage ("invalid %%q value");
15483 if (GET_CODE (XEXP (x, 0)) != NOT)
15484 s = t[0];
15485 else
15487 if (GET_CODE (XEXP (x, 1)) == NOT)
15488 s = t[2];
15489 else
15490 s = t[1];
15493 fputs (s, file);
15495 return;
15497 case 'Q':
15498 if (TARGET_MFCRF)
15499 fputc (',', file);
15500 /* FALLTHRU */
15501 else
15502 return;
15504 case 'R':
15505 /* X is a CR register. Print the mask for `mtcrf'. */
15506 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15507 output_operand_lossage ("invalid %%R value");
15508 else
15509 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15510 return;
15512 case 's':
15513 /* Low 5 bits of 32 - value */
15514 if (! INT_P (x))
15515 output_operand_lossage ("invalid %%s value");
15516 else
15517 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15518 return;
15520 case 'S':
15521 /* PowerPC64 mask position. All 0's is excluded.
15522 CONST_INT 32-bit mask is considered sign-extended so any
15523 transition must occur within the CONST_INT, not on the boundary. */
15524 if (! mask64_operand (x, DImode))
15525 output_operand_lossage ("invalid %%S value");
15527 uval = INT_LOWPART (x);
15529 if (uval & 1) /* Clear Left */
15531 #if HOST_BITS_PER_WIDE_INT > 64
15532 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15533 #endif
15534 i = 64;
15536 else /* Clear Right */
15538 uval = ~uval;
15539 #if HOST_BITS_PER_WIDE_INT > 64
15540 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15541 #endif
15542 i = 63;
15544 while (uval != 0)
15545 --i, uval >>= 1;
15546 gcc_assert (i >= 0);
15547 fprintf (file, "%d", i);
15548 return;
15550 case 't':
15551 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15552 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15554 /* Bit 3 is OV bit. */
15555 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15557 /* If we want bit 31, write a shift count of zero, not 32. */
15558 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15559 return;
15561 case 'T':
15562 /* Print the symbolic name of a branch target register. */
15563 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15564 && REGNO (x) != CTR_REGNO))
15565 output_operand_lossage ("invalid %%T value");
15566 else if (REGNO (x) == LR_REGNO)
15567 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15568 else
15569 fputs ("ctr", file);
15570 return;
15572 case 'u':
15573 /* High-order 16 bits of constant for use in unsigned operand. */
15574 if (! INT_P (x))
15575 output_operand_lossage ("invalid %%u value");
15576 else
15577 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15578 (INT_LOWPART (x) >> 16) & 0xffff);
15579 return;
15581 case 'v':
15582 /* High-order 16 bits of constant for use in signed operand. */
15583 if (! INT_P (x))
15584 output_operand_lossage ("invalid %%v value");
15585 else
15586 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15587 (INT_LOWPART (x) >> 16) & 0xffff);
15588 return;
15590 case 'U':
15591 /* Print `u' if this has an auto-increment or auto-decrement. */
15592 if (GET_CODE (x) == MEM
15593 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15594 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15595 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15596 putc ('u', file);
15597 return;
15599 case 'V':
15600 /* Print the trap code for this operand. */
15601 switch (GET_CODE (x))
15603 case EQ:
15604 fputs ("eq", file); /* 4 */
15605 break;
15606 case NE:
15607 fputs ("ne", file); /* 24 */
15608 break;
15609 case LT:
15610 fputs ("lt", file); /* 16 */
15611 break;
15612 case LE:
15613 fputs ("le", file); /* 20 */
15614 break;
15615 case GT:
15616 fputs ("gt", file); /* 8 */
15617 break;
15618 case GE:
15619 fputs ("ge", file); /* 12 */
15620 break;
15621 case LTU:
15622 fputs ("llt", file); /* 2 */
15623 break;
15624 case LEU:
15625 fputs ("lle", file); /* 6 */
15626 break;
15627 case GTU:
15628 fputs ("lgt", file); /* 1 */
15629 break;
15630 case GEU:
15631 fputs ("lge", file); /* 5 */
15632 break;
15633 default:
15634 gcc_unreachable ();
15636 break;
15638 case 'w':
15639 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15640 normally. */
15641 if (INT_P (x))
15642 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15643 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15644 else
15645 print_operand (file, x, 0);
15646 return;
15648 case 'W':
15649 /* MB value for a PowerPC64 rldic operand. */
15650 val = (GET_CODE (x) == CONST_INT
15651 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15653 if (val < 0)
15654 i = -1;
15655 else
15656 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15657 if ((val <<= 1) < 0)
15658 break;
15660 #if HOST_BITS_PER_WIDE_INT == 32
15661 if (GET_CODE (x) == CONST_INT && i >= 0)
15662 i += 32; /* zero-extend high-part was all 0's */
15663 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15665 val = CONST_DOUBLE_LOW (x);
15667 gcc_assert (val);
15668 if (val < 0)
15669 --i;
15670 else
15671 for ( ; i < 64; i++)
15672 if ((val <<= 1) < 0)
15673 break;
15675 #endif
15677 fprintf (file, "%d", i + 1);
15678 return;
15680 case 'x':
15681 /* X is a FPR or Altivec register used in a VSX context. */
15682 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15683 output_operand_lossage ("invalid %%x value");
15684 else
15686 int reg = REGNO (x);
15687 int vsx_reg = (FP_REGNO_P (reg)
15688 ? reg - 32
15689 : reg - FIRST_ALTIVEC_REGNO + 32);
15691 #ifdef TARGET_REGNAMES
15692 if (TARGET_REGNAMES)
15693 fprintf (file, "%%vs%d", vsx_reg);
15694 else
15695 #endif
15696 fprintf (file, "%d", vsx_reg);
15698 return;
15700 case 'X':
15701 if (GET_CODE (x) == MEM
15702 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15703 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15704 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15705 putc ('x', file);
15706 return;
15708 case 'Y':
15709 /* Like 'L', for third word of TImode */
15710 if (GET_CODE (x) == REG)
15711 fputs (reg_names[REGNO (x) + 2], file);
15712 else if (GET_CODE (x) == MEM)
15714 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15715 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15716 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15717 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15718 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15719 else
15720 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15721 if (small_data_operand (x, GET_MODE (x)))
15722 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15723 reg_names[SMALL_DATA_REG]);
15725 return;
15727 case 'z':
15728 /* X is a SYMBOL_REF. Write out the name preceded by a
15729 period and without any trailing data in brackets. Used for function
15730 names. If we are configured for System V (or the embedded ABI) on
15731 the PowerPC, do not emit the period, since those systems do not use
15732 TOCs and the like. */
15733 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15735 /* Mark the decl as referenced so that cgraph will output the
15736 function. */
15737 if (SYMBOL_REF_DECL (x))
15738 mark_decl_referenced (SYMBOL_REF_DECL (x));
15740 /* For macho, check to see if we need a stub. */
15741 if (TARGET_MACHO)
15743 const char *name = XSTR (x, 0);
15744 #if TARGET_MACHO
15745 if (darwin_emit_branch_islands
15746 && MACHOPIC_INDIRECT
15747 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15748 name = machopic_indirection_name (x, /*stub_p=*/true);
15749 #endif
15750 assemble_name (file, name);
15752 else if (!DOT_SYMBOLS)
15753 assemble_name (file, XSTR (x, 0));
15754 else
15755 rs6000_output_function_entry (file, XSTR (x, 0));
15756 return;
15758 case 'Z':
15759 /* Like 'L', for last word of TImode. */
15760 if (GET_CODE (x) == REG)
15761 fputs (reg_names[REGNO (x) + 3], file);
15762 else if (GET_CODE (x) == MEM)
15764 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15765 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15766 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15767 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15768 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15769 else
15770 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15771 if (small_data_operand (x, GET_MODE (x)))
15772 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15773 reg_names[SMALL_DATA_REG]);
15775 return;
15777 /* Print AltiVec or SPE memory operand. */
15778 case 'y':
15780 rtx tmp;
15782 gcc_assert (GET_CODE (x) == MEM);
15784 tmp = XEXP (x, 0);
15786 /* Ugly hack because %y is overloaded. */
15787 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15788 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15789 || GET_MODE (x) == TFmode
15790 || GET_MODE (x) == TImode))
15792 /* Handle [reg]. */
15793 if (GET_CODE (tmp) == REG)
15795 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15796 break;
15798 /* Handle [reg+UIMM]. */
15799 else if (GET_CODE (tmp) == PLUS &&
15800 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15802 int x;
15804 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15806 x = INTVAL (XEXP (tmp, 1));
15807 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15808 break;
15811 /* Fall through. Must be [reg+reg]. */
15813 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15814 && GET_CODE (tmp) == AND
15815 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15816 && INTVAL (XEXP (tmp, 1)) == -16)
15817 tmp = XEXP (tmp, 0);
15818 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15819 && GET_CODE (tmp) == PRE_MODIFY)
15820 tmp = XEXP (tmp, 1);
15821 if (GET_CODE (tmp) == REG)
15822 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15823 else
15825 if (!GET_CODE (tmp) == PLUS
15826 || !REG_P (XEXP (tmp, 0))
15827 || !REG_P (XEXP (tmp, 1)))
15829 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15830 break;
15833 if (REGNO (XEXP (tmp, 0)) == 0)
15834 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15835 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15836 else
15837 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15838 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15840 break;
15843 case 0:
15844 if (GET_CODE (x) == REG)
15845 fprintf (file, "%s", reg_names[REGNO (x)]);
15846 else if (GET_CODE (x) == MEM)
15848 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15849 know the width from the mode. */
15850 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15851 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15852 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15853 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15854 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15855 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15856 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15857 output_address (XEXP (XEXP (x, 0), 1));
15858 else
15859 output_address (XEXP (x, 0));
15861 else
15863 if (toc_relative_expr_p (x))
15864 /* This hack along with a corresponding hack in
15865 rs6000_output_addr_const_extra arranges to output addends
15866 where the assembler expects to find them. eg.
15867 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
15868 without this hack would be output as "x@toc+4". We
15869 want "x+4@toc". */
15870 output_addr_const (file, tocrel_base);
15871 else
15872 output_addr_const (file, x);
15874 return;
15876 case '&':
15877 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15878 return;
15880 default:
15881 output_operand_lossage ("invalid %%xn code");
15885 /* Print the address of an operand. */
15887 void
15888 print_operand_address (FILE *file, rtx x)
15890 if (GET_CODE (x) == REG)
15891 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15892 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15893 || GET_CODE (x) == LABEL_REF)
15895 output_addr_const (file, x);
15896 if (small_data_operand (x, GET_MODE (x)))
15897 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15898 reg_names[SMALL_DATA_REG]);
15899 else
15900 gcc_assert (!TARGET_TOC);
15902 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15904 gcc_assert (REG_P (XEXP (x, 0)));
15905 if (REGNO (XEXP (x, 0)) == 0)
15906 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15907 reg_names[ REGNO (XEXP (x, 0)) ]);
15908 else
15909 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15910 reg_names[ REGNO (XEXP (x, 1)) ]);
15912 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15913 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15914 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15915 #if TARGET_MACHO
15916 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15917 && CONSTANT_P (XEXP (x, 1)))
15919 fprintf (file, "lo16(");
15920 output_addr_const (file, XEXP (x, 1));
15921 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15923 #endif
15924 else if (legitimate_constant_pool_address_p (x, QImode, true))
15926 /* This hack along with a corresponding hack in
15927 rs6000_output_addr_const_extra arranges to output addends
15928 where the assembler expects to find them. eg.
15929 (lo_sum (reg 9)
15930 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15931 without this hack would be output as "x@toc+8@l(9)". We
15932 want "x+8@toc@l(9)". */
15933 output_addr_const (file, tocrel_base);
15934 if (GET_CODE (x) == LO_SUM)
15935 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15936 else
15937 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15939 #if TARGET_ELF
15940 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15941 && CONSTANT_P (XEXP (x, 1)))
15943 output_addr_const (file, XEXP (x, 1));
15944 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15946 #endif
15947 else
15948 gcc_unreachable ();
15951 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
15953 static bool
15954 rs6000_output_addr_const_extra (FILE *file, rtx x)
15956 if (GET_CODE (x) == UNSPEC)
15957 switch (XINT (x, 1))
15959 case UNSPEC_TOCREL:
15960 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
15961 output_addr_const (file, XVECEXP (x, 0, 0));
15962 if (x == tocrel_base && tocrel_offset != const0_rtx)
15964 if (INTVAL (tocrel_offset) >= 0)
15965 fprintf (file, "+");
15966 output_addr_const (file, tocrel_offset);
15968 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15970 putc ('-', file);
15971 assemble_name (file, toc_label_name);
15973 else if (TARGET_ELF)
15974 fputs ("@toc", file);
15975 return true;
15977 #if TARGET_MACHO
15978 case UNSPEC_MACHOPIC_OFFSET:
15979 output_addr_const (file, XVECEXP (x, 0, 0));
15980 putc ('-', file);
15981 machopic_output_function_base_name (file);
15982 return true;
15983 #endif
15985 return false;
15988 /* Target hook for assembling integer objects. The PowerPC version has
15989 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15990 is defined. It also needs to handle DI-mode objects on 64-bit
15991 targets. */
15993 static bool
15994 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15996 #ifdef RELOCATABLE_NEEDS_FIXUP
15997 /* Special handling for SI values. */
15998 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16000 static int recurse = 0;
16002 /* For -mrelocatable, we mark all addresses that need to be fixed up
16003 in the .fixup section. */
16004 if (TARGET_RELOCATABLE
16005 && in_section != toc_section
16006 && in_section != text_section
16007 && !unlikely_text_section_p (in_section)
16008 && !recurse
16009 && GET_CODE (x) != CONST_INT
16010 && GET_CODE (x) != CONST_DOUBLE
16011 && CONSTANT_P (x))
16013 char buf[256];
16015 recurse = 1;
16016 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16017 fixuplabelno++;
16018 ASM_OUTPUT_LABEL (asm_out_file, buf);
16019 fprintf (asm_out_file, "\t.long\t(");
16020 output_addr_const (asm_out_file, x);
16021 fprintf (asm_out_file, ")@fixup\n");
16022 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16023 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16024 fprintf (asm_out_file, "\t.long\t");
16025 assemble_name (asm_out_file, buf);
16026 fprintf (asm_out_file, "\n\t.previous\n");
16027 recurse = 0;
16028 return true;
16030 /* Remove initial .'s to turn a -mcall-aixdesc function
16031 address into the address of the descriptor, not the function
16032 itself. */
16033 else if (GET_CODE (x) == SYMBOL_REF
16034 && XSTR (x, 0)[0] == '.'
16035 && DEFAULT_ABI == ABI_AIX)
16037 const char *name = XSTR (x, 0);
16038 while (*name == '.')
16039 name++;
16041 fprintf (asm_out_file, "\t.long\t%s\n", name);
16042 return true;
16045 #endif /* RELOCATABLE_NEEDS_FIXUP */
16046 return default_assemble_integer (x, size, aligned_p);
16049 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
16050 /* Emit an assembler directive to set symbol visibility for DECL to
16051 VISIBILITY_TYPE. */
16053 static void
16054 rs6000_assemble_visibility (tree decl, int vis)
16056 /* Functions need to have their entry point symbol visibility set as
16057 well as their descriptor symbol visibility. */
16058 if (DEFAULT_ABI == ABI_AIX
16059 && DOT_SYMBOLS
16060 && TREE_CODE (decl) == FUNCTION_DECL)
16062 static const char * const visibility_types[] = {
16063 NULL, "internal", "hidden", "protected"
16066 const char *name, *type;
16068 name = ((* targetm.strip_name_encoding)
16069 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16070 type = visibility_types[vis];
16072 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16073 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16075 else
16076 default_assemble_visibility (decl, vis);
16078 #endif
16080 enum rtx_code
16081 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16083 /* Reversal of FP compares takes care -- an ordered compare
16084 becomes an unordered compare and vice versa. */
16085 if (mode == CCFPmode
16086 && (!flag_finite_math_only
16087 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16088 || code == UNEQ || code == LTGT))
16089 return reverse_condition_maybe_unordered (code);
16090 else
16091 return reverse_condition (code);
16094 /* Generate a compare for CODE. Return a brand-new rtx that
16095 represents the result of the compare. */
16097 static rtx
16098 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16100 enum machine_mode comp_mode;
16101 rtx compare_result;
16102 enum rtx_code code = GET_CODE (cmp);
16103 rtx op0 = XEXP (cmp, 0);
16104 rtx op1 = XEXP (cmp, 1);
16106 if (FLOAT_MODE_P (mode))
16107 comp_mode = CCFPmode;
16108 else if (code == GTU || code == LTU
16109 || code == GEU || code == LEU)
16110 comp_mode = CCUNSmode;
16111 else if ((code == EQ || code == NE)
16112 && GET_CODE (op0) == SUBREG
16113 && GET_CODE (op1) == SUBREG
16114 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16115 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16116 /* These are unsigned values, perhaps there will be a later
16117 ordering compare that can be shared with this one.
16118 Unfortunately we cannot detect the signedness of the operands
16119 for non-subregs. */
16120 comp_mode = CCUNSmode;
16121 else
16122 comp_mode = CCmode;
16124 /* First, the compare. */
16125 compare_result = gen_reg_rtx (comp_mode);
16127 /* E500 FP compare instructions on the GPRs. Yuck! */
16128 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16129 && FLOAT_MODE_P (mode))
16131 rtx cmp, or_result, compare_result2;
16132 enum machine_mode op_mode = GET_MODE (op0);
16134 if (op_mode == VOIDmode)
16135 op_mode = GET_MODE (op1);
16137 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16138 This explains the following mess. */
16140 switch (code)
16142 case EQ: case UNEQ: case NE: case LTGT:
16143 switch (op_mode)
16145 case SFmode:
16146 cmp = (flag_finite_math_only && !flag_trapping_math)
16147 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16148 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16149 break;
16151 case DFmode:
16152 cmp = (flag_finite_math_only && !flag_trapping_math)
16153 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16154 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16155 break;
16157 case TFmode:
16158 cmp = (flag_finite_math_only && !flag_trapping_math)
16159 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16160 : gen_cmptfeq_gpr (compare_result, op0, op1);
16161 break;
16163 default:
16164 gcc_unreachable ();
16166 break;
16168 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16169 switch (op_mode)
16171 case SFmode:
16172 cmp = (flag_finite_math_only && !flag_trapping_math)
16173 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16174 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16175 break;
16177 case DFmode:
16178 cmp = (flag_finite_math_only && !flag_trapping_math)
16179 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16180 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16181 break;
16183 case TFmode:
16184 cmp = (flag_finite_math_only && !flag_trapping_math)
16185 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16186 : gen_cmptfgt_gpr (compare_result, op0, op1);
16187 break;
16189 default:
16190 gcc_unreachable ();
16192 break;
16194 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16195 switch (op_mode)
16197 case SFmode:
16198 cmp = (flag_finite_math_only && !flag_trapping_math)
16199 ? gen_tstsflt_gpr (compare_result, op0, op1)
16200 : gen_cmpsflt_gpr (compare_result, op0, op1);
16201 break;
16203 case DFmode:
16204 cmp = (flag_finite_math_only && !flag_trapping_math)
16205 ? gen_tstdflt_gpr (compare_result, op0, op1)
16206 : gen_cmpdflt_gpr (compare_result, op0, op1);
16207 break;
16209 case TFmode:
16210 cmp = (flag_finite_math_only && !flag_trapping_math)
16211 ? gen_tsttflt_gpr (compare_result, op0, op1)
16212 : gen_cmptflt_gpr (compare_result, op0, op1);
16213 break;
16215 default:
16216 gcc_unreachable ();
16218 break;
16219 default:
16220 gcc_unreachable ();
16223 /* Synthesize LE and GE from LT/GT || EQ. */
16224 if (code == LE || code == GE || code == LEU || code == GEU)
16226 emit_insn (cmp);
16228 switch (code)
16230 case LE: code = LT; break;
16231 case GE: code = GT; break;
16232 case LEU: code = LT; break;
16233 case GEU: code = GT; break;
16234 default: gcc_unreachable ();
16237 compare_result2 = gen_reg_rtx (CCFPmode);
16239 /* Do the EQ. */
16240 switch (op_mode)
16242 case SFmode:
16243 cmp = (flag_finite_math_only && !flag_trapping_math)
16244 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16245 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16246 break;
16248 case DFmode:
16249 cmp = (flag_finite_math_only && !flag_trapping_math)
16250 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16251 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16252 break;
16254 case TFmode:
16255 cmp = (flag_finite_math_only && !flag_trapping_math)
16256 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16257 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16258 break;
16260 default:
16261 gcc_unreachable ();
16263 emit_insn (cmp);
16265 /* OR them together. */
16266 or_result = gen_reg_rtx (CCFPmode);
16267 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16268 compare_result2);
16269 compare_result = or_result;
16270 code = EQ;
16272 else
16274 if (code == NE || code == LTGT)
16275 code = NE;
16276 else
16277 code = EQ;
16280 emit_insn (cmp);
16282 else
16284 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16285 CLOBBERs to match cmptf_internal2 pattern. */
16286 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16287 && GET_MODE (op0) == TFmode
16288 && !TARGET_IEEEQUAD
16289 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16290 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16291 gen_rtvec (10,
16292 gen_rtx_SET (VOIDmode,
16293 compare_result,
16294 gen_rtx_COMPARE (comp_mode, op0, op1)),
16295 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16296 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16297 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16298 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16299 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16300 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16301 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16302 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16303 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16304 else if (GET_CODE (op1) == UNSPEC
16305 && XINT (op1, 1) == UNSPEC_SP_TEST)
16307 rtx op1b = XVECEXP (op1, 0, 0);
16308 comp_mode = CCEQmode;
16309 compare_result = gen_reg_rtx (CCEQmode);
16310 if (TARGET_64BIT)
16311 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16312 else
16313 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16315 else
16316 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16317 gen_rtx_COMPARE (comp_mode, op0, op1)));
16320 /* Some kinds of FP comparisons need an OR operation;
16321 under flag_finite_math_only we don't bother. */
16322 if (FLOAT_MODE_P (mode)
16323 && !flag_finite_math_only
16324 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16325 && (code == LE || code == GE
16326 || code == UNEQ || code == LTGT
16327 || code == UNGT || code == UNLT))
16329 enum rtx_code or1, or2;
16330 rtx or1_rtx, or2_rtx, compare2_rtx;
16331 rtx or_result = gen_reg_rtx (CCEQmode);
16333 switch (code)
16335 case LE: or1 = LT; or2 = EQ; break;
16336 case GE: or1 = GT; or2 = EQ; break;
16337 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16338 case LTGT: or1 = LT; or2 = GT; break;
16339 case UNGT: or1 = UNORDERED; or2 = GT; break;
16340 case UNLT: or1 = UNORDERED; or2 = LT; break;
16341 default: gcc_unreachable ();
16343 validate_condition_mode (or1, comp_mode);
16344 validate_condition_mode (or2, comp_mode);
16345 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16346 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16347 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16348 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16349 const_true_rtx);
16350 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16352 compare_result = or_result;
16353 code = EQ;
16356 validate_condition_mode (code, GET_MODE (compare_result));
16358 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16362 /* Emit the RTL for an sISEL pattern. */
16364 void
16365 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16367 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16370 void
16371 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16373 rtx condition_rtx;
16374 enum machine_mode op_mode;
16375 enum rtx_code cond_code;
16376 rtx result = operands[0];
16378 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16380 rs6000_emit_sISEL (mode, operands);
16381 return;
16384 condition_rtx = rs6000_generate_compare (operands[1], mode);
16385 cond_code = GET_CODE (condition_rtx);
16387 if (FLOAT_MODE_P (mode)
16388 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16390 rtx t;
16392 PUT_MODE (condition_rtx, SImode);
16393 t = XEXP (condition_rtx, 0);
16395 gcc_assert (cond_code == NE || cond_code == EQ);
16397 if (cond_code == NE)
16398 emit_insn (gen_e500_flip_gt_bit (t, t));
16400 emit_insn (gen_move_from_CR_gt_bit (result, t));
16401 return;
16404 if (cond_code == NE
16405 || cond_code == GE || cond_code == LE
16406 || cond_code == GEU || cond_code == LEU
16407 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16409 rtx not_result = gen_reg_rtx (CCEQmode);
16410 rtx not_op, rev_cond_rtx;
16411 enum machine_mode cc_mode;
16413 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16415 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16416 SImode, XEXP (condition_rtx, 0), const0_rtx);
16417 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16418 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16419 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16422 op_mode = GET_MODE (XEXP (operands[1], 0));
16423 if (op_mode == VOIDmode)
16424 op_mode = GET_MODE (XEXP (operands[1], 1));
16426 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16428 PUT_MODE (condition_rtx, DImode);
16429 convert_move (result, condition_rtx, 0);
16431 else
16433 PUT_MODE (condition_rtx, SImode);
16434 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16438 /* Emit a branch of kind CODE to location LOC. */
16440 void
16441 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16443 rtx condition_rtx, loc_ref;
16445 condition_rtx = rs6000_generate_compare (operands[0], mode);
16446 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16447 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16448 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16449 loc_ref, pc_rtx)));
16452 /* Return the string to output a conditional branch to LABEL, which is
16453 the operand number of the label, or -1 if the branch is really a
16454 conditional return.
16456 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16457 condition code register and its mode specifies what kind of
16458 comparison we made.
16460 REVERSED is nonzero if we should reverse the sense of the comparison.
16462 INSN is the insn. */
16464 char *
16465 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16467 static char string[64];
16468 enum rtx_code code = GET_CODE (op);
16469 rtx cc_reg = XEXP (op, 0);
16470 enum machine_mode mode = GET_MODE (cc_reg);
16471 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16472 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16473 int really_reversed = reversed ^ need_longbranch;
16474 char *s = string;
16475 const char *ccode;
16476 const char *pred;
16477 rtx note;
16479 validate_condition_mode (code, mode);
16481 /* Work out which way this really branches. We could use
16482 reverse_condition_maybe_unordered here always but this
16483 makes the resulting assembler clearer. */
16484 if (really_reversed)
16486 /* Reversal of FP compares takes care -- an ordered compare
16487 becomes an unordered compare and vice versa. */
16488 if (mode == CCFPmode)
16489 code = reverse_condition_maybe_unordered (code);
16490 else
16491 code = reverse_condition (code);
16494 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16496 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16497 to the GT bit. */
16498 switch (code)
16500 case EQ:
16501 /* Opposite of GT. */
16502 code = GT;
16503 break;
16505 case NE:
16506 code = UNLE;
16507 break;
16509 default:
16510 gcc_unreachable ();
16514 switch (code)
16516 /* Not all of these are actually distinct opcodes, but
16517 we distinguish them for clarity of the resulting assembler. */
16518 case NE: case LTGT:
16519 ccode = "ne"; break;
16520 case EQ: case UNEQ:
16521 ccode = "eq"; break;
16522 case GE: case GEU:
16523 ccode = "ge"; break;
16524 case GT: case GTU: case UNGT:
16525 ccode = "gt"; break;
16526 case LE: case LEU:
16527 ccode = "le"; break;
16528 case LT: case LTU: case UNLT:
16529 ccode = "lt"; break;
16530 case UNORDERED: ccode = "un"; break;
16531 case ORDERED: ccode = "nu"; break;
16532 case UNGE: ccode = "nl"; break;
16533 case UNLE: ccode = "ng"; break;
16534 default:
16535 gcc_unreachable ();
16538 /* Maybe we have a guess as to how likely the branch is.
16539 The old mnemonics don't have a way to specify this information. */
16540 pred = "";
16541 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16542 if (note != NULL_RTX)
16544 /* PROB is the difference from 50%. */
16545 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16547 /* Only hint for highly probable/improbable branches on newer
16548 cpus as static prediction overrides processor dynamic
16549 prediction. For older cpus we may as well always hint, but
16550 assume not taken for branches that are very close to 50% as a
16551 mispredicted taken branch is more expensive than a
16552 mispredicted not-taken branch. */
16553 if (rs6000_always_hint
16554 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16555 && br_prob_note_reliable_p (note)))
16557 if (abs (prob) > REG_BR_PROB_BASE / 20
16558 && ((prob > 0) ^ need_longbranch))
16559 pred = "+";
16560 else
16561 pred = "-";
16565 if (label == NULL)
16566 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16567 else
16568 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16570 /* We need to escape any '%' characters in the reg_names string.
16571 Assume they'd only be the first character.... */
16572 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16573 *s++ = '%';
16574 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16576 if (label != NULL)
16578 /* If the branch distance was too far, we may have to use an
16579 unconditional branch to go the distance. */
16580 if (need_longbranch)
16581 s += sprintf (s, ",$+8\n\tb %s", label);
16582 else
16583 s += sprintf (s, ",%s", label);
16586 return string;
16589 /* Return the string to flip the GT bit on a CR. */
16590 char *
16591 output_e500_flip_gt_bit (rtx dst, rtx src)
16593 static char string[64];
16594 int a, b;
16596 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16597 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16599 /* GT bit. */
16600 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16601 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16603 sprintf (string, "crnot %d,%d", a, b);
16604 return string;
16607 /* Return insn for VSX or Altivec comparisons. */
16609 static rtx
16610 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16612 rtx mask;
16613 enum machine_mode mode = GET_MODE (op0);
16615 switch (code)
16617 default:
16618 break;
16620 case GE:
16621 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16622 return NULL_RTX;
16624 case EQ:
16625 case GT:
16626 case GTU:
16627 mask = gen_reg_rtx (mode);
16628 emit_insn (gen_rtx_SET (VOIDmode,
16629 mask,
16630 gen_rtx_fmt_ee (code, mode, op0, op1)));
16631 return mask;
16634 return NULL_RTX;
16637 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16638 DMODE is expected destination mode. This is a recursive function. */
16640 static rtx
16641 rs6000_emit_vector_compare (enum rtx_code rcode,
16642 rtx op0, rtx op1,
16643 enum machine_mode dmode)
16645 rtx mask;
16646 bool swap_operands = false;
16647 bool try_again = false;
16649 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16650 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16652 /* See if the comparison works as is. */
16653 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16654 if (mask)
16655 return mask;
16657 switch (rcode)
16659 case LT:
16660 rcode = GT;
16661 swap_operands = true;
16662 try_again = true;
16663 break;
16664 case LTU:
16665 rcode = GTU;
16666 swap_operands = true;
16667 try_again = true;
16668 break;
16669 case NE:
16670 case UNLE:
16671 case UNLT:
16672 case UNGE:
16673 case UNGT:
16674 /* Invert condition and try again.
16675 e.g., A != B becomes ~(A==B). */
16677 enum rtx_code rev_code;
16678 enum insn_code nor_code;
16679 rtx mask2;
16681 rev_code = reverse_condition_maybe_unordered (rcode);
16682 if (rev_code == UNKNOWN)
16683 return NULL_RTX;
16685 nor_code = optab_handler (one_cmpl_optab, dmode);
16686 if (nor_code == CODE_FOR_nothing)
16687 return NULL_RTX;
16689 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16690 if (!mask2)
16691 return NULL_RTX;
16693 mask = gen_reg_rtx (dmode);
16694 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16695 return mask;
16697 break;
16698 case GE:
16699 case GEU:
16700 case LE:
16701 case LEU:
16702 /* Try GT/GTU/LT/LTU OR EQ */
16704 rtx c_rtx, eq_rtx;
16705 enum insn_code ior_code;
16706 enum rtx_code new_code;
16708 switch (rcode)
16710 case GE:
16711 new_code = GT;
16712 break;
16714 case GEU:
16715 new_code = GTU;
16716 break;
16718 case LE:
16719 new_code = LT;
16720 break;
16722 case LEU:
16723 new_code = LTU;
16724 break;
16726 default:
16727 gcc_unreachable ();
16730 ior_code = optab_handler (ior_optab, dmode);
16731 if (ior_code == CODE_FOR_nothing)
16732 return NULL_RTX;
16734 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16735 if (!c_rtx)
16736 return NULL_RTX;
16738 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16739 if (!eq_rtx)
16740 return NULL_RTX;
16742 mask = gen_reg_rtx (dmode);
16743 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16744 return mask;
16746 break;
16747 default:
16748 return NULL_RTX;
16751 if (try_again)
16753 if (swap_operands)
16755 rtx tmp;
16756 tmp = op0;
16757 op0 = op1;
16758 op1 = tmp;
16761 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16762 if (mask)
16763 return mask;
16766 /* You only get two chances. */
16767 return NULL_RTX;
16770 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16771 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16772 operands for the relation operation COND. */
16775 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16776 rtx cond, rtx cc_op0, rtx cc_op1)
16778 enum machine_mode dest_mode = GET_MODE (dest);
16779 enum machine_mode mask_mode = GET_MODE (cc_op0);
16780 enum rtx_code rcode = GET_CODE (cond);
16781 enum machine_mode cc_mode = CCmode;
16782 rtx mask;
16783 rtx cond2;
16784 rtx tmp;
16785 bool invert_move = false;
16787 if (VECTOR_UNIT_NONE_P (dest_mode))
16788 return 0;
16790 gcc_assert (GET_MODE_SIZE (dest_mode) == GET_MODE_SIZE (mask_mode)
16791 && GET_MODE_NUNITS (dest_mode) == GET_MODE_NUNITS (mask_mode));
16793 switch (rcode)
16795 /* Swap operands if we can, and fall back to doing the operation as
16796 specified, and doing a NOR to invert the test. */
16797 case NE:
16798 case UNLE:
16799 case UNLT:
16800 case UNGE:
16801 case UNGT:
16802 /* Invert condition and try again.
16803 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16804 invert_move = true;
16805 rcode = reverse_condition_maybe_unordered (rcode);
16806 if (rcode == UNKNOWN)
16807 return 0;
16808 break;
16810 /* Mark unsigned tests with CCUNSmode. */
16811 case GTU:
16812 case GEU:
16813 case LTU:
16814 case LEU:
16815 cc_mode = CCUNSmode;
16816 break;
16818 default:
16819 break;
16822 /* Get the vector mask for the given relational operations. */
16823 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, mask_mode);
16825 if (!mask)
16826 return 0;
16828 if (invert_move)
16830 tmp = op_true;
16831 op_true = op_false;
16832 op_false = tmp;
16835 cond2 = gen_rtx_fmt_ee (NE, cc_mode, gen_lowpart (dest_mode, mask),
16836 CONST0_RTX (dest_mode));
16837 emit_insn (gen_rtx_SET (VOIDmode,
16838 dest,
16839 gen_rtx_IF_THEN_ELSE (dest_mode,
16840 cond2,
16841 op_true,
16842 op_false)));
16843 return 1;
16846 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16847 operands of the last comparison is nonzero/true, FALSE_COND if it
16848 is zero/false. Return 0 if the hardware has no such operation. */
16851 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16853 enum rtx_code code = GET_CODE (op);
16854 rtx op0 = XEXP (op, 0);
16855 rtx op1 = XEXP (op, 1);
16856 REAL_VALUE_TYPE c1;
16857 enum machine_mode compare_mode = GET_MODE (op0);
16858 enum machine_mode result_mode = GET_MODE (dest);
16859 rtx temp;
16860 bool is_against_zero;
16862 /* These modes should always match. */
16863 if (GET_MODE (op1) != compare_mode
16864 /* In the isel case however, we can use a compare immediate, so
16865 op1 may be a small constant. */
16866 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16867 return 0;
16868 if (GET_MODE (true_cond) != result_mode)
16869 return 0;
16870 if (GET_MODE (false_cond) != result_mode)
16871 return 0;
16873 /* First, work out if the hardware can do this at all, or
16874 if it's too slow.... */
16875 if (!FLOAT_MODE_P (compare_mode))
16877 if (TARGET_ISEL)
16878 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16879 return 0;
16881 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16882 && SCALAR_FLOAT_MODE_P (compare_mode))
16883 return 0;
16885 is_against_zero = op1 == CONST0_RTX (compare_mode);
16887 /* A floating-point subtract might overflow, underflow, or produce
16888 an inexact result, thus changing the floating-point flags, so it
16889 can't be generated if we care about that. It's safe if one side
16890 of the construct is zero, since then no subtract will be
16891 generated. */
16892 if (SCALAR_FLOAT_MODE_P (compare_mode)
16893 && flag_trapping_math && ! is_against_zero)
16894 return 0;
16896 /* Eliminate half of the comparisons by switching operands, this
16897 makes the remaining code simpler. */
16898 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16899 || code == LTGT || code == LT || code == UNLE)
16901 code = reverse_condition_maybe_unordered (code);
16902 temp = true_cond;
16903 true_cond = false_cond;
16904 false_cond = temp;
16907 /* UNEQ and LTGT take four instructions for a comparison with zero,
16908 it'll probably be faster to use a branch here too. */
16909 if (code == UNEQ && HONOR_NANS (compare_mode))
16910 return 0;
16912 if (GET_CODE (op1) == CONST_DOUBLE)
16913 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16915 /* We're going to try to implement comparisons by performing
16916 a subtract, then comparing against zero. Unfortunately,
16917 Inf - Inf is NaN which is not zero, and so if we don't
16918 know that the operand is finite and the comparison
16919 would treat EQ different to UNORDERED, we can't do it. */
16920 if (HONOR_INFINITIES (compare_mode)
16921 && code != GT && code != UNGE
16922 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16923 /* Constructs of the form (a OP b ? a : b) are safe. */
16924 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16925 || (! rtx_equal_p (op0, true_cond)
16926 && ! rtx_equal_p (op1, true_cond))))
16927 return 0;
16929 /* At this point we know we can use fsel. */
16931 /* Reduce the comparison to a comparison against zero. */
16932 if (! is_against_zero)
16934 temp = gen_reg_rtx (compare_mode);
16935 emit_insn (gen_rtx_SET (VOIDmode, temp,
16936 gen_rtx_MINUS (compare_mode, op0, op1)));
16937 op0 = temp;
16938 op1 = CONST0_RTX (compare_mode);
16941 /* If we don't care about NaNs we can reduce some of the comparisons
16942 down to faster ones. */
16943 if (! HONOR_NANS (compare_mode))
16944 switch (code)
16946 case GT:
16947 code = LE;
16948 temp = true_cond;
16949 true_cond = false_cond;
16950 false_cond = temp;
16951 break;
16952 case UNGE:
16953 code = GE;
16954 break;
16955 case UNEQ:
16956 code = EQ;
16957 break;
16958 default:
16959 break;
16962 /* Now, reduce everything down to a GE. */
16963 switch (code)
16965 case GE:
16966 break;
16968 case LE:
16969 temp = gen_reg_rtx (compare_mode);
16970 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16971 op0 = temp;
16972 break;
16974 case ORDERED:
16975 temp = gen_reg_rtx (compare_mode);
16976 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16977 op0 = temp;
16978 break;
16980 case EQ:
16981 temp = gen_reg_rtx (compare_mode);
16982 emit_insn (gen_rtx_SET (VOIDmode, temp,
16983 gen_rtx_NEG (compare_mode,
16984 gen_rtx_ABS (compare_mode, op0))));
16985 op0 = temp;
16986 break;
16988 case UNGE:
16989 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16990 temp = gen_reg_rtx (result_mode);
16991 emit_insn (gen_rtx_SET (VOIDmode, temp,
16992 gen_rtx_IF_THEN_ELSE (result_mode,
16993 gen_rtx_GE (VOIDmode,
16994 op0, op1),
16995 true_cond, false_cond)));
16996 false_cond = true_cond;
16997 true_cond = temp;
16999 temp = gen_reg_rtx (compare_mode);
17000 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17001 op0 = temp;
17002 break;
17004 case GT:
17005 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17006 temp = gen_reg_rtx (result_mode);
17007 emit_insn (gen_rtx_SET (VOIDmode, temp,
17008 gen_rtx_IF_THEN_ELSE (result_mode,
17009 gen_rtx_GE (VOIDmode,
17010 op0, op1),
17011 true_cond, false_cond)));
17012 true_cond = false_cond;
17013 false_cond = temp;
17015 temp = gen_reg_rtx (compare_mode);
17016 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17017 op0 = temp;
17018 break;
17020 default:
17021 gcc_unreachable ();
17024 emit_insn (gen_rtx_SET (VOIDmode, dest,
17025 gen_rtx_IF_THEN_ELSE (result_mode,
17026 gen_rtx_GE (VOIDmode,
17027 op0, op1),
17028 true_cond, false_cond)));
17029 return 1;
17032 /* Same as above, but for ints (isel). */
17034 static int
17035 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17037 rtx condition_rtx, cr;
17038 enum machine_mode mode = GET_MODE (dest);
17039 enum rtx_code cond_code;
17040 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17041 bool signedp;
17043 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17044 return 0;
17046 /* We still have to do the compare, because isel doesn't do a
17047 compare, it just looks at the CRx bits set by a previous compare
17048 instruction. */
17049 condition_rtx = rs6000_generate_compare (op, mode);
17050 cond_code = GET_CODE (condition_rtx);
17051 cr = XEXP (condition_rtx, 0);
17052 signedp = GET_MODE (cr) == CCmode;
17054 isel_func = (mode == SImode
17055 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17056 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17058 switch (cond_code)
17060 case LT: case GT: case LTU: case GTU: case EQ:
17061 /* isel handles these directly. */
17062 break;
17064 default:
17065 /* We need to swap the sense of the comparison. */
17067 rtx t = true_cond;
17068 true_cond = false_cond;
17069 false_cond = t;
17070 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17072 break;
17075 false_cond = force_reg (mode, false_cond);
17076 if (true_cond != const0_rtx)
17077 true_cond = force_reg (mode, true_cond);
17079 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17081 return 1;
17084 const char *
17085 output_isel (rtx *operands)
17087 enum rtx_code code;
17089 code = GET_CODE (operands[1]);
17091 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17093 gcc_assert (GET_CODE (operands[2]) == REG
17094 && GET_CODE (operands[3]) == REG);
17095 PUT_CODE (operands[1], reverse_condition (code));
17096 return "isel %0,%3,%2,%j1";
17099 return "isel %0,%2,%3,%j1";
17102 void
17103 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17105 enum machine_mode mode = GET_MODE (op0);
17106 enum rtx_code c;
17107 rtx target;
17109 /* VSX/altivec have direct min/max insns. */
17110 if ((code == SMAX || code == SMIN)
17111 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17112 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17114 emit_insn (gen_rtx_SET (VOIDmode,
17115 dest,
17116 gen_rtx_fmt_ee (code, mode, op0, op1)));
17117 return;
17120 if (code == SMAX || code == SMIN)
17121 c = GE;
17122 else
17123 c = GEU;
17125 if (code == SMAX || code == UMAX)
17126 target = emit_conditional_move (dest, c, op0, op1, mode,
17127 op0, op1, mode, 0);
17128 else
17129 target = emit_conditional_move (dest, c, op0, op1, mode,
17130 op1, op0, mode, 0);
17131 gcc_assert (target);
17132 if (target != dest)
17133 emit_move_insn (dest, target);
17136 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17137 COND is true. Mark the jump as unlikely to be taken. */
17139 static void
17140 emit_unlikely_jump (rtx cond, rtx label)
17142 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17143 rtx x;
17145 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17146 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17147 add_reg_note (x, REG_BR_PROB, very_unlikely);
17150 /* A subroutine of the atomic operation splitters. Emit a load-locked
17151 instruction in MODE. */
17153 static void
17154 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17156 rtx (*fn) (rtx, rtx) = NULL;
17158 switch (mode)
17160 case SImode:
17161 fn = gen_load_lockedsi;
17162 break;
17163 case DImode:
17164 fn = gen_load_lockeddi;
17165 break;
17166 default:
17167 gcc_unreachable ();
17169 emit_insn (fn (reg, mem));
17172 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17173 instruction in MODE. */
17175 static void
17176 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17178 rtx (*fn) (rtx, rtx, rtx) = NULL;
17180 switch (mode)
17182 case SImode:
17183 fn = gen_store_conditionalsi;
17184 break;
17185 case DImode:
17186 fn = gen_store_conditionaldi;
17187 break;
17188 default:
17189 gcc_unreachable ();
17192 /* Emit sync before stwcx. to address PPC405 Erratum. */
17193 if (PPC405_ERRATUM77)
17194 emit_insn (gen_hwsync ());
17196 emit_insn (fn (res, mem, val));
17199 /* Expand barriers before and after a load_locked/store_cond sequence. */
17201 static void
17202 rs6000_pre_atomic_barrier (enum memmodel model)
17204 switch (model)
17206 case MEMMODEL_RELAXED:
17207 case MEMMODEL_CONSUME:
17208 case MEMMODEL_ACQUIRE:
17209 break;
17210 case MEMMODEL_RELEASE:
17211 case MEMMODEL_ACQ_REL:
17212 emit_insn (gen_lwsync ());
17213 break;
17214 case MEMMODEL_SEQ_CST:
17215 emit_insn (gen_hwsync ());
17216 break;
17217 default:
17218 gcc_unreachable ();
17222 static void
17223 rs6000_post_atomic_barrier (enum memmodel model)
17225 switch (model)
17227 case MEMMODEL_RELAXED:
17228 case MEMMODEL_CONSUME:
17229 case MEMMODEL_RELEASE:
17230 break;
17231 case MEMMODEL_ACQUIRE:
17232 case MEMMODEL_ACQ_REL:
17233 case MEMMODEL_SEQ_CST:
17234 emit_insn (gen_isync ());
17235 break;
17236 default:
17237 gcc_unreachable ();
17241 /* A subroutine of the various atomic expanders. For sub-word operations,
17242 we must adjust things to operate on SImode. Given the original MEM,
17243 return a new aligned memory. Also build and return the quantities by
17244 which to shift and mask. */
17246 static rtx
17247 rs6000_adjust_atomic_subword (rtx orig_mem, rtx *pshift, rtx *pmask)
17249 rtx addr, align, shift, mask, mem;
17250 HOST_WIDE_INT shift_mask;
17251 enum machine_mode mode = GET_MODE (orig_mem);
17253 /* For smaller modes, we have to implement this via SImode. */
17254 shift_mask = (mode == QImode ? 0x18 : 0x10);
17256 addr = XEXP (orig_mem, 0);
17257 addr = force_reg (GET_MODE (addr), addr);
17259 /* Aligned memory containing subword. Generate a new memory. We
17260 do not want any of the existing MEM_ATTR data, as we're now
17261 accessing memory outside the original object. */
17262 align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-4),
17263 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17264 mem = gen_rtx_MEM (SImode, align);
17265 MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
17266 if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER)
17267 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
17269 /* Shift amount for subword relative to aligned word. */
17270 shift = gen_reg_rtx (SImode);
17271 addr = gen_lowpart (SImode, addr);
17272 emit_insn (gen_rlwinm (shift, addr, GEN_INT (3), GEN_INT (shift_mask)));
17273 shift = expand_simple_binop (SImode, XOR, shift, GEN_INT (shift_mask),
17274 shift, 1, OPTAB_LIB_WIDEN);
17275 *pshift = shift;
17277 /* Mask for insertion. */
17278 mask = expand_simple_binop (SImode, ASHIFT, GEN_INT (GET_MODE_MASK (mode)),
17279 shift, NULL_RTX, 1, OPTAB_LIB_WIDEN);
17280 *pmask = mask;
17282 return mem;
17285 /* A subroutine of the various atomic expanders. For sub-word operands,
17286 combine OLDVAL and NEWVAL via MASK. Returns a new pseduo. */
17288 static rtx
17289 rs6000_mask_atomic_subword (rtx oldval, rtx newval, rtx mask)
17291 rtx x;
17293 x = gen_reg_rtx (SImode);
17294 emit_insn (gen_rtx_SET (VOIDmode, x,
17295 gen_rtx_AND (SImode,
17296 gen_rtx_NOT (SImode, mask),
17297 oldval)));
17299 x = expand_simple_binop (SImode, IOR, newval, x, x, 1, OPTAB_LIB_WIDEN);
17301 return x;
17304 /* A subroutine of the various atomic expanders. For sub-word operands,
17305 extract WIDE to NARROW via SHIFT. */
17307 static void
17308 rs6000_finish_atomic_subword (rtx narrow, rtx wide, rtx shift)
17310 wide = expand_simple_binop (SImode, LSHIFTRT, wide, shift,
17311 wide, 1, OPTAB_LIB_WIDEN);
17312 emit_move_insn (narrow, gen_lowpart (GET_MODE (narrow), wide));
17315 /* Expand an atomic compare and swap operation. */
17317 void
17318 rs6000_expand_atomic_compare_and_swap (rtx operands[])
17320 rtx boolval, retval, mem, oldval, newval, cond;
17321 rtx label1, label2, x, mask, shift;
17322 enum machine_mode mode;
17323 enum memmodel mod_s, mod_f;
17324 bool is_weak;
17326 boolval = operands[0];
17327 retval = operands[1];
17328 mem = operands[2];
17329 oldval = operands[3];
17330 newval = operands[4];
17331 is_weak = (INTVAL (operands[5]) != 0);
17332 mod_s = (enum memmodel) INTVAL (operands[6]);
17333 mod_f = (enum memmodel) INTVAL (operands[7]);
17334 mode = GET_MODE (mem);
17336 mask = shift = NULL_RTX;
17337 if (mode == QImode || mode == HImode)
17339 mem = rs6000_adjust_atomic_subword (mem, &shift, &mask);
17341 /* Shift and mask OLDVAL into position with the word. */
17342 oldval = convert_modes (SImode, mode, oldval, 1);
17343 oldval = expand_simple_binop (SImode, ASHIFT, oldval, shift,
17344 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17346 /* Shift and mask NEWVAL into position within the word. */
17347 newval = convert_modes (SImode, mode, newval, 1);
17348 newval = expand_simple_binop (SImode, ASHIFT, newval, shift,
17349 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17351 /* Prepare to adjust the return value. */
17352 retval = gen_reg_rtx (SImode);
17353 mode = SImode;
17356 rs6000_pre_atomic_barrier (mod_s);
17358 emit_move_insn (boolval, const0_rtx);
17360 label1 = NULL_RTX;
17361 if (!is_weak)
17363 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17364 emit_label (XEXP (label1, 0));
17366 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17368 emit_load_locked (mode, retval, mem);
17370 x = retval;
17371 if (mask)
17373 x = expand_simple_binop (SImode, AND, retval, mask,
17374 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17377 x = gen_rtx_NE (VOIDmode, x, oldval);
17378 x = rs6000_generate_compare (x, mode);
17379 emit_unlikely_jump (x, label2);
17381 x = newval;
17382 if (mask)
17383 x = rs6000_mask_atomic_subword (retval, newval, mask);
17385 cond = gen_reg_rtx (CCmode);
17386 emit_store_conditional (mode, cond, mem, x);
17388 if (is_weak)
17390 /* ??? It's either this or an unlikely jump over (set bool 1). */
17391 x = gen_rtx_EQ (SImode, cond, const0_rtx);
17392 emit_insn (gen_rtx_SET (VOIDmode, boolval, x));
17394 else
17396 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17397 emit_unlikely_jump (x, label1);
17398 emit_move_insn (boolval, const1_rtx);
17401 if (mod_f != MEMMODEL_RELAXED)
17402 emit_label (XEXP (label2, 0));
17404 rs6000_post_atomic_barrier (mod_s);
17406 if (mod_f == MEMMODEL_RELAXED)
17407 emit_label (XEXP (label2, 0));
17409 if (shift)
17410 rs6000_finish_atomic_subword (operands[1], retval, shift);
17413 /* Expand an atomic exchange operation. */
17415 void
17416 rs6000_expand_atomic_exchange (rtx operands[])
17418 rtx retval, mem, val, cond;
17419 enum machine_mode mode;
17420 enum memmodel model;
17421 rtx label, x, mask, shift;
17423 retval = operands[0];
17424 mem = operands[1];
17425 val = operands[2];
17426 model = (enum memmodel) INTVAL (operands[3]);
17427 mode = GET_MODE (mem);
17429 mask = shift = NULL_RTX;
17430 if (mode == QImode || mode == HImode)
17432 mem = rs6000_adjust_atomic_subword (mem, &shift, &mask);
17434 /* Shift and mask VAL into position with the word. */
17435 val = convert_modes (SImode, mode, val, 1);
17436 val = expand_simple_binop (SImode, ASHIFT, val, shift,
17437 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17439 /* Prepare to adjust the return value. */
17440 retval = gen_reg_rtx (SImode);
17441 mode = SImode;
17444 rs6000_pre_atomic_barrier (model);
17446 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17447 emit_label (XEXP (label, 0));
17449 emit_load_locked (mode, retval, mem);
17451 x = val;
17452 if (mask)
17453 x = rs6000_mask_atomic_subword (retval, val, mask);
17455 cond = gen_reg_rtx (CCmode);
17456 emit_store_conditional (mode, cond, mem, x);
17458 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17459 emit_unlikely_jump (x, label);
17461 rs6000_post_atomic_barrier (model);
17463 if (shift)
17464 rs6000_finish_atomic_subword (operands[0], retval, shift);
17467 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17468 to perform. MEM is the memory on which to operate. VAL is the second
17469 operand of the binary operator. BEFORE and AFTER are optional locations to
17470 return the value of MEM either before of after the operation. MODEL_RTX
17471 is a CONST_INT containing the memory model to use. */
17473 void
17474 rs6000_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
17475 rtx orig_before, rtx orig_after, rtx model_rtx)
17477 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
17478 enum machine_mode mode = GET_MODE (mem);
17479 rtx label, x, cond, mask, shift;
17480 rtx before = orig_before, after = orig_after;
17482 mask = shift = NULL_RTX;
17483 if (mode == QImode || mode == HImode)
17485 mem = rs6000_adjust_atomic_subword (mem, &shift, &mask);
17487 /* Shift and mask VAL into position with the word. */
17488 val = convert_modes (SImode, mode, val, 1);
17489 val = expand_simple_binop (SImode, ASHIFT, val, shift,
17490 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17492 switch (code)
17494 case IOR:
17495 case XOR:
17496 /* We've already zero-extended VAL. That is sufficient to
17497 make certain that it does not affect other bits. */
17498 mask = NULL;
17499 break;
17501 case AND:
17502 /* If we make certain that all of the other bits in VAL are
17503 set, that will be sufficient to not affect other bits. */
17504 x = gen_rtx_NOT (SImode, mask);
17505 x = gen_rtx_IOR (SImode, x, val);
17506 emit_insn (gen_rtx_SET (VOIDmode, val, x));
17507 mask = NULL;
17508 break;
17510 case NOT:
17511 case PLUS:
17512 case MINUS:
17513 /* These will all affect bits outside the field and need
17514 adjustment via MASK within the loop. */
17515 break;
17517 default:
17518 gcc_unreachable ();
17521 /* Prepare to adjust the return value. */
17522 before = gen_reg_rtx (SImode);
17523 if (after)
17524 after = gen_reg_rtx (SImode);
17525 mode = SImode;
17528 rs6000_pre_atomic_barrier (model);
17530 label = gen_label_rtx ();
17531 emit_label (label);
17532 label = gen_rtx_LABEL_REF (VOIDmode, label);
17534 if (before == NULL_RTX)
17535 before = gen_reg_rtx (mode);
17537 emit_load_locked (mode, before, mem);
17539 if (code == NOT)
17541 x = expand_simple_binop (mode, AND, before, val,
17542 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17543 after = expand_simple_unop (mode, NOT, x, after, 1);
17545 else
17547 after = expand_simple_binop (mode, code, before, val,
17548 after, 1, OPTAB_LIB_WIDEN);
17551 x = after;
17552 if (mask)
17554 x = expand_simple_binop (SImode, AND, after, mask,
17555 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17556 x = rs6000_mask_atomic_subword (before, x, mask);
17559 cond = gen_reg_rtx (CCmode);
17560 emit_store_conditional (mode, cond, mem, x);
17562 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17563 emit_unlikely_jump (x, label);
17565 rs6000_post_atomic_barrier (model);
17567 if (shift)
17569 if (orig_before)
17570 rs6000_finish_atomic_subword (orig_before, before, shift);
17571 if (orig_after)
17572 rs6000_finish_atomic_subword (orig_after, after, shift);
17574 else if (orig_after && after != orig_after)
17575 emit_move_insn (orig_after, after);
17578 /* Emit instructions to move SRC to DST. Called by splitters for
17579 multi-register moves. It will emit at most one instruction for
17580 each register that is accessed; that is, it won't emit li/lis pairs
17581 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17582 register. */
17584 void
17585 rs6000_split_multireg_move (rtx dst, rtx src)
17587 /* The register number of the first register being moved. */
17588 int reg;
17589 /* The mode that is to be moved. */
17590 enum machine_mode mode;
17591 /* The mode that the move is being done in, and its size. */
17592 enum machine_mode reg_mode;
17593 int reg_mode_size;
17594 /* The number of registers that will be moved. */
17595 int nregs;
17597 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17598 mode = GET_MODE (dst);
17599 nregs = hard_regno_nregs[reg][mode];
17600 if (FP_REGNO_P (reg))
17601 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17602 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17603 else if (ALTIVEC_REGNO_P (reg))
17604 reg_mode = V16QImode;
17605 else if (TARGET_E500_DOUBLE && mode == TFmode)
17606 reg_mode = DFmode;
17607 else
17608 reg_mode = word_mode;
17609 reg_mode_size = GET_MODE_SIZE (reg_mode);
17611 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17613 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17615 /* Move register range backwards, if we might have destructive
17616 overlap. */
17617 int i;
17618 for (i = nregs - 1; i >= 0; i--)
17619 emit_insn (gen_rtx_SET (VOIDmode,
17620 simplify_gen_subreg (reg_mode, dst, mode,
17621 i * reg_mode_size),
17622 simplify_gen_subreg (reg_mode, src, mode,
17623 i * reg_mode_size)));
17625 else
17627 int i;
17628 int j = -1;
17629 bool used_update = false;
17630 rtx restore_basereg = NULL_RTX;
17632 if (MEM_P (src) && INT_REGNO_P (reg))
17634 rtx breg;
17636 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17637 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17639 rtx delta_rtx;
17640 breg = XEXP (XEXP (src, 0), 0);
17641 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17642 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17643 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17644 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17645 src = replace_equiv_address (src, breg);
17647 else if (! rs6000_offsettable_memref_p (src))
17649 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17651 rtx basereg = XEXP (XEXP (src, 0), 0);
17652 if (TARGET_UPDATE)
17654 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17655 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17656 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17657 used_update = true;
17659 else
17660 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17661 XEXP (XEXP (src, 0), 1)));
17662 src = replace_equiv_address (src, basereg);
17664 else
17666 rtx basereg = gen_rtx_REG (Pmode, reg);
17667 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17668 src = replace_equiv_address (src, basereg);
17672 breg = XEXP (src, 0);
17673 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17674 breg = XEXP (breg, 0);
17676 /* If the base register we are using to address memory is
17677 also a destination reg, then change that register last. */
17678 if (REG_P (breg)
17679 && REGNO (breg) >= REGNO (dst)
17680 && REGNO (breg) < REGNO (dst) + nregs)
17681 j = REGNO (breg) - REGNO (dst);
17683 else if (MEM_P (dst) && INT_REGNO_P (reg))
17685 rtx breg;
17687 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17688 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17690 rtx delta_rtx;
17691 breg = XEXP (XEXP (dst, 0), 0);
17692 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17693 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17694 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17696 /* We have to update the breg before doing the store.
17697 Use store with update, if available. */
17699 if (TARGET_UPDATE)
17701 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17702 emit_insn (TARGET_32BIT
17703 ? (TARGET_POWERPC64
17704 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17705 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17706 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17707 used_update = true;
17709 else
17710 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17711 dst = replace_equiv_address (dst, breg);
17713 else if (!rs6000_offsettable_memref_p (dst)
17714 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17716 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17718 rtx basereg = XEXP (XEXP (dst, 0), 0);
17719 if (TARGET_UPDATE)
17721 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17722 emit_insn (gen_rtx_SET (VOIDmode,
17723 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17724 used_update = true;
17726 else
17727 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17728 XEXP (XEXP (dst, 0), 1)));
17729 dst = replace_equiv_address (dst, basereg);
17731 else
17733 rtx basereg = XEXP (XEXP (dst, 0), 0);
17734 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17735 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17736 && REG_P (basereg)
17737 && REG_P (offsetreg)
17738 && REGNO (basereg) != REGNO (offsetreg));
17739 if (REGNO (basereg) == 0)
17741 rtx tmp = offsetreg;
17742 offsetreg = basereg;
17743 basereg = tmp;
17745 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17746 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17747 dst = replace_equiv_address (dst, basereg);
17750 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17751 gcc_assert (rs6000_offsettable_memref_p (dst));
17754 for (i = 0; i < nregs; i++)
17756 /* Calculate index to next subword. */
17757 ++j;
17758 if (j == nregs)
17759 j = 0;
17761 /* If compiler already emitted move of first word by
17762 store with update, no need to do anything. */
17763 if (j == 0 && used_update)
17764 continue;
17766 emit_insn (gen_rtx_SET (VOIDmode,
17767 simplify_gen_subreg (reg_mode, dst, mode,
17768 j * reg_mode_size),
17769 simplify_gen_subreg (reg_mode, src, mode,
17770 j * reg_mode_size)));
17772 if (restore_basereg != NULL_RTX)
17773 emit_insn (restore_basereg);
17778 /* This page contains routines that are used to determine what the
17779 function prologue and epilogue code will do and write them out. */
17781 /* Return the first fixed-point register that is required to be
17782 saved. 32 if none. */
17785 first_reg_to_save (void)
17787 int first_reg;
17789 /* Find lowest numbered live register. */
17790 for (first_reg = 13; first_reg <= 31; first_reg++)
17791 if (df_regs_ever_live_p (first_reg)
17792 && (! call_used_regs[first_reg]
17793 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17794 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17795 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17796 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17797 break;
17799 #if TARGET_MACHO
17800 if (flag_pic
17801 && crtl->uses_pic_offset_table
17802 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17803 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17804 #endif
17806 return first_reg;
17809 /* Similar, for FP regs. */
17812 first_fp_reg_to_save (void)
17814 int first_reg;
17816 /* Find lowest numbered live register. */
17817 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17818 if (df_regs_ever_live_p (first_reg))
17819 break;
17821 return first_reg;
17824 /* Similar, for AltiVec regs. */
17826 static int
17827 first_altivec_reg_to_save (void)
17829 int i;
17831 /* Stack frame remains as is unless we are in AltiVec ABI. */
17832 if (! TARGET_ALTIVEC_ABI)
17833 return LAST_ALTIVEC_REGNO + 1;
17835 /* On Darwin, the unwind routines are compiled without
17836 TARGET_ALTIVEC, and use save_world to save/restore the
17837 altivec registers when necessary. */
17838 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17839 && ! TARGET_ALTIVEC)
17840 return FIRST_ALTIVEC_REGNO + 20;
17842 /* Find lowest numbered live register. */
17843 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17844 if (df_regs_ever_live_p (i))
17845 break;
17847 return i;
17850 /* Return a 32-bit mask of the AltiVec registers we need to set in
17851 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17852 the 32-bit word is 0. */
17854 static unsigned int
17855 compute_vrsave_mask (void)
17857 unsigned int i, mask = 0;
17859 /* On Darwin, the unwind routines are compiled without
17860 TARGET_ALTIVEC, and use save_world to save/restore the
17861 call-saved altivec registers when necessary. */
17862 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17863 && ! TARGET_ALTIVEC)
17864 mask |= 0xFFF;
17866 /* First, find out if we use _any_ altivec registers. */
17867 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17868 if (df_regs_ever_live_p (i))
17869 mask |= ALTIVEC_REG_BIT (i);
17871 if (mask == 0)
17872 return mask;
17874 /* Next, remove the argument registers from the set. These must
17875 be in the VRSAVE mask set by the caller, so we don't need to add
17876 them in again. More importantly, the mask we compute here is
17877 used to generate CLOBBERs in the set_vrsave insn, and we do not
17878 wish the argument registers to die. */
17879 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17880 mask &= ~ALTIVEC_REG_BIT (i);
17882 /* Similarly, remove the return value from the set. */
17884 bool yes = false;
17885 diddle_return_value (is_altivec_return_reg, &yes);
17886 if (yes)
17887 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17890 return mask;
17893 /* For a very restricted set of circumstances, we can cut down the
17894 size of prologues/epilogues by calling our own save/restore-the-world
17895 routines. */
17897 static void
17898 compute_save_world_info (rs6000_stack_t *info_ptr)
17900 info_ptr->world_save_p = 1;
17901 info_ptr->world_save_p
17902 = (WORLD_SAVE_P (info_ptr)
17903 && DEFAULT_ABI == ABI_DARWIN
17904 && !cfun->has_nonlocal_label
17905 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17906 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17907 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17908 && info_ptr->cr_save_p);
17910 /* This will not work in conjunction with sibcalls. Make sure there
17911 are none. (This check is expensive, but seldom executed.) */
17912 if (WORLD_SAVE_P (info_ptr))
17914 rtx insn;
17915 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17916 if ( GET_CODE (insn) == CALL_INSN
17917 && SIBLING_CALL_P (insn))
17919 info_ptr->world_save_p = 0;
17920 break;
17924 if (WORLD_SAVE_P (info_ptr))
17926 /* Even if we're not touching VRsave, make sure there's room on the
17927 stack for it, if it looks like we're calling SAVE_WORLD, which
17928 will attempt to save it. */
17929 info_ptr->vrsave_size = 4;
17931 /* If we are going to save the world, we need to save the link register too. */
17932 info_ptr->lr_save_p = 1;
17934 /* "Save" the VRsave register too if we're saving the world. */
17935 if (info_ptr->vrsave_mask == 0)
17936 info_ptr->vrsave_mask = compute_vrsave_mask ();
17938 /* Because the Darwin register save/restore routines only handle
17939 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17940 check. */
17941 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17942 && (info_ptr->first_altivec_reg_save
17943 >= FIRST_SAVED_ALTIVEC_REGNO));
17945 return;
17949 static void
17950 is_altivec_return_reg (rtx reg, void *xyes)
17952 bool *yes = (bool *) xyes;
17953 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17954 *yes = true;
17958 /* Determine the strategy for savings/restoring registers. */
17960 enum {
17961 SAVRES_MULTIPLE = 0x1,
17962 SAVE_INLINE_FPRS = 0x2,
17963 SAVE_INLINE_GPRS = 0x4,
17964 REST_INLINE_FPRS = 0x8,
17965 REST_INLINE_GPRS = 0x10,
17966 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
17967 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
17968 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
17971 static int
17972 rs6000_savres_strategy (rs6000_stack_t *info,
17973 bool using_static_chain_p)
17975 int strategy = 0;
17977 if (TARGET_MULTIPLE
17978 && !TARGET_POWERPC64
17979 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
17980 && info->first_gp_reg_save < 31
17981 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
17982 strategy |= SAVRES_MULTIPLE;
17984 if (crtl->calls_eh_return
17985 || cfun->machine->ra_need_lr
17986 || info->total_size > 32767)
17987 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
17988 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
17990 if (info->first_fp_reg_save == 64
17991 || FP_SAVE_INLINE (info->first_fp_reg_save)
17992 /* The out-of-line FP routines use double-precision stores;
17993 we can't use those routines if we don't have such stores. */
17994 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
17995 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
17996 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
17998 if (info->first_gp_reg_save == 32
17999 || GP_SAVE_INLINE (info->first_gp_reg_save)
18000 || !((strategy & SAVRES_MULTIPLE)
18001 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18002 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18004 /* Don't bother to try to save things out-of-line if r11 is occupied
18005 by the static chain. It would require too much fiddling and the
18006 static chain is rarely used anyway. FPRs are saved w.r.t the stack
18007 pointer on Darwin. */
18008 if (using_static_chain_p)
18009 strategy |= (DEFAULT_ABI == ABI_DARWIN ? 0 : SAVE_INLINE_FPRS)
18010 | SAVE_INLINE_GPRS;
18012 /* If we are going to use store multiple, then don't even bother
18013 with the out-of-line routines, since the store-multiple
18014 instruction will always be smaller. */
18015 if ((strategy & SAVRES_MULTIPLE))
18016 strategy |= SAVE_INLINE_GPRS;
18018 /* The situation is more complicated with load multiple. We'd
18019 prefer to use the out-of-line routines for restores, since the
18020 "exit" out-of-line routines can handle the restore of LR and the
18021 frame teardown. However if doesn't make sense to use the
18022 out-of-line routine if that is the only reason we'd need to save
18023 LR, and we can't use the "exit" out-of-line gpr restore if we
18024 have saved some fprs; In those cases it is advantageous to use
18025 load multiple when available. */
18026 if ((strategy & SAVRES_MULTIPLE)
18027 && (!info->lr_save_p
18028 || info->first_fp_reg_save != 64))
18029 strategy |= REST_INLINE_GPRS;
18031 /* We can only use load multiple or the out-of-line routines to
18032 restore if we've used store multiple or out-of-line routines
18033 in the prologue, i.e. if we've saved all the registers from
18034 first_gp_reg_save. Otherwise, we risk loading garbage. */
18035 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18036 strategy |= REST_INLINE_GPRS;
18038 /* Saving CR interferes with the exit routines used on the SPE, so
18039 just punt here. */
18040 if (TARGET_SPE_ABI
18041 && info->spe_64bit_regs_used
18042 && info->cr_save_p)
18043 strategy |= REST_INLINE_GPRS;
18045 #ifdef POWERPC_LINUX
18046 if (TARGET_64BIT)
18048 if (!(strategy & SAVE_INLINE_FPRS))
18049 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18050 else if (!(strategy & SAVE_INLINE_GPRS)
18051 && info->first_fp_reg_save == 64)
18052 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18054 #else
18055 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18056 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18057 #endif
18058 if (TARGET_MACHO && !(strategy & SAVE_INLINE_FPRS))
18059 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18061 return strategy;
18064 /* Calculate the stack information for the current function. This is
18065 complicated by having two separate calling sequences, the AIX calling
18066 sequence and the V.4 calling sequence.
18068 AIX (and Darwin/Mac OS X) stack frames look like:
18069 32-bit 64-bit
18070 SP----> +---------------------------------------+
18071 | back chain to caller | 0 0
18072 +---------------------------------------+
18073 | saved CR | 4 8 (8-11)
18074 +---------------------------------------+
18075 | saved LR | 8 16
18076 +---------------------------------------+
18077 | reserved for compilers | 12 24
18078 +---------------------------------------+
18079 | reserved for binders | 16 32
18080 +---------------------------------------+
18081 | saved TOC pointer | 20 40
18082 +---------------------------------------+
18083 | Parameter save area (P) | 24 48
18084 +---------------------------------------+
18085 | Alloca space (A) | 24+P etc.
18086 +---------------------------------------+
18087 | Local variable space (L) | 24+P+A
18088 +---------------------------------------+
18089 | Float/int conversion temporary (X) | 24+P+A+L
18090 +---------------------------------------+
18091 | Save area for AltiVec registers (W) | 24+P+A+L+X
18092 +---------------------------------------+
18093 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18094 +---------------------------------------+
18095 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18096 +---------------------------------------+
18097 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18098 +---------------------------------------+
18099 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18100 +---------------------------------------+
18101 old SP->| back chain to caller's caller |
18102 +---------------------------------------+
18104 The required alignment for AIX configurations is two words (i.e., 8
18105 or 16 bytes).
18108 V.4 stack frames look like:
18110 SP----> +---------------------------------------+
18111 | back chain to caller | 0
18112 +---------------------------------------+
18113 | caller's saved LR | 4
18114 +---------------------------------------+
18115 | Parameter save area (P) | 8
18116 +---------------------------------------+
18117 | Alloca space (A) | 8+P
18118 +---------------------------------------+
18119 | Varargs save area (V) | 8+P+A
18120 +---------------------------------------+
18121 | Local variable space (L) | 8+P+A+V
18122 +---------------------------------------+
18123 | Float/int conversion temporary (X) | 8+P+A+V+L
18124 +---------------------------------------+
18125 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18126 +---------------------------------------+
18127 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18128 +---------------------------------------+
18129 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18130 +---------------------------------------+
18131 | SPE: area for 64-bit GP registers |
18132 +---------------------------------------+
18133 | SPE alignment padding |
18134 +---------------------------------------+
18135 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18136 +---------------------------------------+
18137 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18138 +---------------------------------------+
18139 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18140 +---------------------------------------+
18141 old SP->| back chain to caller's caller |
18142 +---------------------------------------+
18144 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18145 given. (But note below and in sysv4.h that we require only 8 and
18146 may round up the size of our stack frame anyways. The historical
18147 reason is early versions of powerpc-linux which didn't properly
18148 align the stack at program startup. A happy side-effect is that
18149 -mno-eabi libraries can be used with -meabi programs.)
18151 The EABI configuration defaults to the V.4 layout. However,
18152 the stack alignment requirements may differ. If -mno-eabi is not
18153 given, the required stack alignment is 8 bytes; if -mno-eabi is
18154 given, the required alignment is 16 bytes. (But see V.4 comment
18155 above.) */
18157 #ifndef ABI_STACK_BOUNDARY
18158 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18159 #endif
18161 static rs6000_stack_t *
18162 rs6000_stack_info (void)
18164 rs6000_stack_t *info_ptr = &stack_info;
18165 int reg_size = TARGET_32BIT ? 4 : 8;
18166 int ehrd_size;
18167 int save_align;
18168 int first_gp;
18169 HOST_WIDE_INT non_fixed_size;
18170 bool using_static_chain_p;
18172 if (reload_completed && info_ptr->reload_completed)
18173 return info_ptr;
18175 memset (info_ptr, 0, sizeof (*info_ptr));
18176 info_ptr->reload_completed = reload_completed;
18178 if (TARGET_SPE)
18180 /* Cache value so we don't rescan instruction chain over and over. */
18181 if (cfun->machine->insn_chain_scanned_p == 0)
18182 cfun->machine->insn_chain_scanned_p
18183 = spe_func_has_64bit_regs_p () + 1;
18184 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18187 /* Select which calling sequence. */
18188 info_ptr->abi = DEFAULT_ABI;
18190 /* Calculate which registers need to be saved & save area size. */
18191 info_ptr->first_gp_reg_save = first_reg_to_save ();
18192 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18193 even if it currently looks like we won't. Reload may need it to
18194 get at a constant; if so, it will have already created a constant
18195 pool entry for it. */
18196 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18197 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18198 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18199 && crtl->uses_const_pool
18200 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18201 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18202 else
18203 first_gp = info_ptr->first_gp_reg_save;
18205 info_ptr->gp_size = reg_size * (32 - first_gp);
18207 /* For the SPE, we have an additional upper 32-bits on each GPR.
18208 Ideally we should save the entire 64-bits only when the upper
18209 half is used in SIMD instructions. Since we only record
18210 registers live (not the size they are used in), this proves
18211 difficult because we'd have to traverse the instruction chain at
18212 the right time, taking reload into account. This is a real pain,
18213 so we opt to save the GPRs in 64-bits always if but one register
18214 gets used in 64-bits. Otherwise, all the registers in the frame
18215 get saved in 32-bits.
18217 So... since when we save all GPRs (except the SP) in 64-bits, the
18218 traditional GP save area will be empty. */
18219 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18220 info_ptr->gp_size = 0;
18222 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18223 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18225 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18226 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18227 - info_ptr->first_altivec_reg_save);
18229 /* Does this function call anything? */
18230 info_ptr->calls_p = (! current_function_is_leaf
18231 || cfun->machine->ra_needs_full_frame);
18233 /* Determine if we need to save the condition code registers. */
18234 if (df_regs_ever_live_p (CR2_REGNO)
18235 || df_regs_ever_live_p (CR3_REGNO)
18236 || df_regs_ever_live_p (CR4_REGNO))
18238 info_ptr->cr_save_p = 1;
18239 if (DEFAULT_ABI == ABI_V4)
18240 info_ptr->cr_size = reg_size;
18243 /* If the current function calls __builtin_eh_return, then we need
18244 to allocate stack space for registers that will hold data for
18245 the exception handler. */
18246 if (crtl->calls_eh_return)
18248 unsigned int i;
18249 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18250 continue;
18252 /* SPE saves EH registers in 64-bits. */
18253 ehrd_size = i * (TARGET_SPE_ABI
18254 && info_ptr->spe_64bit_regs_used != 0
18255 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18257 else
18258 ehrd_size = 0;
18260 /* Determine various sizes. */
18261 info_ptr->reg_size = reg_size;
18262 info_ptr->fixed_size = RS6000_SAVE_AREA;
18263 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18264 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18265 TARGET_ALTIVEC ? 16 : 8);
18266 if (FRAME_GROWS_DOWNWARD)
18267 info_ptr->vars_size
18268 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18269 + info_ptr->parm_size,
18270 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18271 - (info_ptr->fixed_size + info_ptr->vars_size
18272 + info_ptr->parm_size);
18274 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18275 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18276 else
18277 info_ptr->spe_gp_size = 0;
18279 if (TARGET_ALTIVEC_ABI)
18280 info_ptr->vrsave_mask = compute_vrsave_mask ();
18281 else
18282 info_ptr->vrsave_mask = 0;
18284 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18285 info_ptr->vrsave_size = 4;
18286 else
18287 info_ptr->vrsave_size = 0;
18289 compute_save_world_info (info_ptr);
18291 /* Calculate the offsets. */
18292 switch (DEFAULT_ABI)
18294 case ABI_NONE:
18295 default:
18296 gcc_unreachable ();
18298 case ABI_AIX:
18299 case ABI_DARWIN:
18300 info_ptr->fp_save_offset = - info_ptr->fp_size;
18301 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18303 if (TARGET_ALTIVEC_ABI)
18305 info_ptr->vrsave_save_offset
18306 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18308 /* Align stack so vector save area is on a quadword boundary.
18309 The padding goes above the vectors. */
18310 if (info_ptr->altivec_size != 0)
18311 info_ptr->altivec_padding_size
18312 = info_ptr->vrsave_save_offset & 0xF;
18313 else
18314 info_ptr->altivec_padding_size = 0;
18316 info_ptr->altivec_save_offset
18317 = info_ptr->vrsave_save_offset
18318 - info_ptr->altivec_padding_size
18319 - info_ptr->altivec_size;
18320 gcc_assert (info_ptr->altivec_size == 0
18321 || info_ptr->altivec_save_offset % 16 == 0);
18323 /* Adjust for AltiVec case. */
18324 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18326 else
18327 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18328 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18329 info_ptr->lr_save_offset = 2*reg_size;
18330 break;
18332 case ABI_V4:
18333 info_ptr->fp_save_offset = - info_ptr->fp_size;
18334 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18335 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18337 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18339 /* Align stack so SPE GPR save area is aligned on a
18340 double-word boundary. */
18341 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18342 info_ptr->spe_padding_size
18343 = 8 - (-info_ptr->cr_save_offset % 8);
18344 else
18345 info_ptr->spe_padding_size = 0;
18347 info_ptr->spe_gp_save_offset
18348 = info_ptr->cr_save_offset
18349 - info_ptr->spe_padding_size
18350 - info_ptr->spe_gp_size;
18352 /* Adjust for SPE case. */
18353 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18355 else if (TARGET_ALTIVEC_ABI)
18357 info_ptr->vrsave_save_offset
18358 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18360 /* Align stack so vector save area is on a quadword boundary. */
18361 if (info_ptr->altivec_size != 0)
18362 info_ptr->altivec_padding_size
18363 = 16 - (-info_ptr->vrsave_save_offset % 16);
18364 else
18365 info_ptr->altivec_padding_size = 0;
18367 info_ptr->altivec_save_offset
18368 = info_ptr->vrsave_save_offset
18369 - info_ptr->altivec_padding_size
18370 - info_ptr->altivec_size;
18372 /* Adjust for AltiVec case. */
18373 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18375 else
18376 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18377 info_ptr->ehrd_offset -= ehrd_size;
18378 info_ptr->lr_save_offset = reg_size;
18379 break;
18382 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18383 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18384 + info_ptr->gp_size
18385 + info_ptr->altivec_size
18386 + info_ptr->altivec_padding_size
18387 + info_ptr->spe_gp_size
18388 + info_ptr->spe_padding_size
18389 + ehrd_size
18390 + info_ptr->cr_size
18391 + info_ptr->vrsave_size,
18392 save_align);
18394 non_fixed_size = (info_ptr->vars_size
18395 + info_ptr->parm_size
18396 + info_ptr->save_size);
18398 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18399 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18401 /* Determine if we need to save the link register. */
18402 if (info_ptr->calls_p
18403 || (DEFAULT_ABI == ABI_AIX
18404 && crtl->profile
18405 && !TARGET_PROFILE_KERNEL)
18406 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18407 #ifdef TARGET_RELOCATABLE
18408 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18409 #endif
18410 || rs6000_ra_ever_killed ())
18411 info_ptr->lr_save_p = 1;
18413 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18414 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18415 && call_used_regs[STATIC_CHAIN_REGNUM]);
18416 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18417 using_static_chain_p);
18419 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18420 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18421 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18422 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18423 info_ptr->lr_save_p = 1;
18425 if (info_ptr->lr_save_p)
18426 df_set_regs_ever_live (LR_REGNO, true);
18428 /* Determine if we need to allocate any stack frame:
18430 For AIX we need to push the stack if a frame pointer is needed
18431 (because the stack might be dynamically adjusted), if we are
18432 debugging, if we make calls, or if the sum of fp_save, gp_save,
18433 and local variables are more than the space needed to save all
18434 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18435 + 18*8 = 288 (GPR13 reserved).
18437 For V.4 we don't have the stack cushion that AIX uses, but assume
18438 that the debugger can handle stackless frames. */
18440 if (info_ptr->calls_p)
18441 info_ptr->push_p = 1;
18443 else if (DEFAULT_ABI == ABI_V4)
18444 info_ptr->push_p = non_fixed_size != 0;
18446 else if (frame_pointer_needed)
18447 info_ptr->push_p = 1;
18449 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18450 info_ptr->push_p = 1;
18452 else
18453 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18455 /* Zero offsets if we're not saving those registers. */
18456 if (info_ptr->fp_size == 0)
18457 info_ptr->fp_save_offset = 0;
18459 if (info_ptr->gp_size == 0)
18460 info_ptr->gp_save_offset = 0;
18462 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18463 info_ptr->altivec_save_offset = 0;
18465 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18466 info_ptr->vrsave_save_offset = 0;
18468 if (! TARGET_SPE_ABI
18469 || info_ptr->spe_64bit_regs_used == 0
18470 || info_ptr->spe_gp_size == 0)
18471 info_ptr->spe_gp_save_offset = 0;
18473 if (! info_ptr->lr_save_p)
18474 info_ptr->lr_save_offset = 0;
18476 if (! info_ptr->cr_save_p)
18477 info_ptr->cr_save_offset = 0;
18479 return info_ptr;
18482 /* Return true if the current function uses any GPRs in 64-bit SIMD
18483 mode. */
18485 static bool
18486 spe_func_has_64bit_regs_p (void)
18488 rtx insns, insn;
18490 /* Functions that save and restore all the call-saved registers will
18491 need to save/restore the registers in 64-bits. */
18492 if (crtl->calls_eh_return
18493 || cfun->calls_setjmp
18494 || crtl->has_nonlocal_goto)
18495 return true;
18497 insns = get_insns ();
18499 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18501 if (INSN_P (insn))
18503 rtx i;
18505 /* FIXME: This should be implemented with attributes...
18507 (set_attr "spe64" "true")....then,
18508 if (get_spe64(insn)) return true;
18510 It's the only reliable way to do the stuff below. */
18512 i = PATTERN (insn);
18513 if (GET_CODE (i) == SET)
18515 enum machine_mode mode = GET_MODE (SET_SRC (i));
18517 if (SPE_VECTOR_MODE (mode))
18518 return true;
18519 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18520 return true;
18525 return false;
18528 static void
18529 debug_stack_info (rs6000_stack_t *info)
18531 const char *abi_string;
18533 if (! info)
18534 info = rs6000_stack_info ();
18536 fprintf (stderr, "\nStack information for function %s:\n",
18537 ((current_function_decl && DECL_NAME (current_function_decl))
18538 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18539 : "<unknown>"));
18541 switch (info->abi)
18543 default: abi_string = "Unknown"; break;
18544 case ABI_NONE: abi_string = "NONE"; break;
18545 case ABI_AIX: abi_string = "AIX"; break;
18546 case ABI_DARWIN: abi_string = "Darwin"; break;
18547 case ABI_V4: abi_string = "V.4"; break;
18550 fprintf (stderr, "\tABI = %5s\n", abi_string);
18552 if (TARGET_ALTIVEC_ABI)
18553 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18555 if (TARGET_SPE_ABI)
18556 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18558 if (info->first_gp_reg_save != 32)
18559 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18561 if (info->first_fp_reg_save != 64)
18562 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18564 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18565 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18566 info->first_altivec_reg_save);
18568 if (info->lr_save_p)
18569 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18571 if (info->cr_save_p)
18572 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18574 if (info->vrsave_mask)
18575 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18577 if (info->push_p)
18578 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18580 if (info->calls_p)
18581 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18583 if (info->gp_save_offset)
18584 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18586 if (info->fp_save_offset)
18587 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18589 if (info->altivec_save_offset)
18590 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18591 info->altivec_save_offset);
18593 if (info->spe_gp_save_offset)
18594 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18595 info->spe_gp_save_offset);
18597 if (info->vrsave_save_offset)
18598 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18599 info->vrsave_save_offset);
18601 if (info->lr_save_offset)
18602 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18604 if (info->cr_save_offset)
18605 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18607 if (info->varargs_save_offset)
18608 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18610 if (info->total_size)
18611 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18612 info->total_size);
18614 if (info->vars_size)
18615 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18616 info->vars_size);
18618 if (info->parm_size)
18619 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18621 if (info->fixed_size)
18622 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18624 if (info->gp_size)
18625 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18627 if (info->spe_gp_size)
18628 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18630 if (info->fp_size)
18631 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18633 if (info->altivec_size)
18634 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18636 if (info->vrsave_size)
18637 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18639 if (info->altivec_padding_size)
18640 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18641 info->altivec_padding_size);
18643 if (info->spe_padding_size)
18644 fprintf (stderr, "\tspe_padding_size = %5d\n",
18645 info->spe_padding_size);
18647 if (info->cr_size)
18648 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18650 if (info->save_size)
18651 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18653 if (info->reg_size != 4)
18654 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18656 fprintf (stderr, "\tsave-strategy = %04x\n", info->savres_strategy);
18658 fprintf (stderr, "\n");
18662 rs6000_return_addr (int count, rtx frame)
18664 /* Currently we don't optimize very well between prolog and body
18665 code and for PIC code the code can be actually quite bad, so
18666 don't try to be too clever here. */
18667 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18669 cfun->machine->ra_needs_full_frame = 1;
18671 return
18672 gen_rtx_MEM
18673 (Pmode,
18674 memory_address
18675 (Pmode,
18676 plus_constant (copy_to_reg
18677 (gen_rtx_MEM (Pmode,
18678 memory_address (Pmode, frame))),
18679 RETURN_ADDRESS_OFFSET)));
18682 cfun->machine->ra_need_lr = 1;
18683 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18686 /* Say whether a function is a candidate for sibcall handling or not. */
18688 static bool
18689 rs6000_function_ok_for_sibcall (tree decl, tree exp)
18691 tree fntype;
18693 if (decl)
18694 fntype = TREE_TYPE (decl);
18695 else
18696 fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
18698 /* We can't do it if the called function has more vector parameters
18699 than the current function; there's nowhere to put the VRsave code. */
18700 if (TARGET_ALTIVEC_ABI
18701 && TARGET_ALTIVEC_VRSAVE
18702 && !(decl && decl == current_function_decl))
18704 function_args_iterator args_iter;
18705 tree type;
18706 int nvreg = 0;
18708 /* Functions with vector parameters are required to have a
18709 prototype, so the argument type info must be available
18710 here. */
18711 FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
18712 if (TREE_CODE (type) == VECTOR_TYPE
18713 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18714 nvreg++;
18716 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
18717 if (TREE_CODE (type) == VECTOR_TYPE
18718 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
18719 nvreg--;
18721 if (nvreg > 0)
18722 return false;
18725 /* Under the AIX ABI we can't allow calls to non-local functions,
18726 because the callee may have a different TOC pointer to the
18727 caller and there's no way to ensure we restore the TOC when we
18728 return. With the secure-plt SYSV ABI we can't make non-local
18729 calls when -fpic/PIC because the plt call stubs use r30. */
18730 if (DEFAULT_ABI == ABI_DARWIN
18731 || (DEFAULT_ABI == ABI_AIX
18732 && decl
18733 && !DECL_EXTERNAL (decl)
18734 && (*targetm.binds_local_p) (decl))
18735 || (DEFAULT_ABI == ABI_V4
18736 && (!TARGET_SECURE_PLT
18737 || !flag_pic
18738 || (decl
18739 && (*targetm.binds_local_p) (decl)))))
18741 tree attr_list = TYPE_ATTRIBUTES (fntype);
18743 if (!lookup_attribute ("longcall", attr_list)
18744 || lookup_attribute ("shortcall", attr_list))
18745 return true;
18748 return false;
18751 /* NULL if INSN insn is valid within a low-overhead loop.
18752 Otherwise return why doloop cannot be applied.
18753 PowerPC uses the COUNT register for branch on table instructions. */
18755 static const char *
18756 rs6000_invalid_within_doloop (const_rtx insn)
18758 if (CALL_P (insn))
18759 return "Function call in the loop.";
18761 if (JUMP_P (insn)
18762 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18763 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18764 return "Computed branch in the loop.";
18766 return NULL;
18769 static int
18770 rs6000_ra_ever_killed (void)
18772 rtx top;
18773 rtx reg;
18774 rtx insn;
18776 if (cfun->is_thunk)
18777 return 0;
18779 if (cfun->machine->lr_save_state)
18780 return cfun->machine->lr_save_state - 1;
18782 /* regs_ever_live has LR marked as used if any sibcalls are present,
18783 but this should not force saving and restoring in the
18784 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18785 clobbers LR, so that is inappropriate. */
18787 /* Also, the prologue can generate a store into LR that
18788 doesn't really count, like this:
18790 move LR->R0
18791 bcl to set PIC register
18792 move LR->R31
18793 move R0->LR
18795 When we're called from the epilogue, we need to avoid counting
18796 this as a store. */
18798 push_topmost_sequence ();
18799 top = get_insns ();
18800 pop_topmost_sequence ();
18801 reg = gen_rtx_REG (Pmode, LR_REGNO);
18803 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18805 if (INSN_P (insn))
18807 if (CALL_P (insn))
18809 if (!SIBLING_CALL_P (insn))
18810 return 1;
18812 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18813 return 1;
18814 else if (set_of (reg, insn) != NULL_RTX
18815 && !prologue_epilogue_contains (insn))
18816 return 1;
18819 return 0;
18822 /* Emit instructions needed to load the TOC register.
18823 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18824 a constant pool; or for SVR4 -fpic. */
18826 void
18827 rs6000_emit_load_toc_table (int fromprolog)
18829 rtx dest;
18830 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18832 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18834 char buf[30];
18835 rtx lab, tmp1, tmp2, got;
18837 lab = gen_label_rtx ();
18838 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18839 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18840 if (flag_pic == 2)
18841 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18842 else
18843 got = rs6000_got_sym ();
18844 tmp1 = tmp2 = dest;
18845 if (!fromprolog)
18847 tmp1 = gen_reg_rtx (Pmode);
18848 tmp2 = gen_reg_rtx (Pmode);
18850 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18851 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18852 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18853 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18855 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18857 emit_insn (gen_load_toc_v4_pic_si ());
18858 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18860 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18862 char buf[30];
18863 rtx temp0 = (fromprolog
18864 ? gen_rtx_REG (Pmode, 0)
18865 : gen_reg_rtx (Pmode));
18867 if (fromprolog)
18869 rtx symF, symL;
18871 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18872 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18874 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18875 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18877 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18878 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18879 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18881 else
18883 rtx tocsym, lab;
18885 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18886 lab = gen_label_rtx ();
18887 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18888 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18889 if (TARGET_LINK_STACK)
18890 emit_insn (gen_addsi3 (dest, dest, GEN_INT (4)));
18891 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18893 emit_insn (gen_addsi3 (dest, temp0, dest));
18895 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18897 /* This is for AIX code running in non-PIC ELF32. */
18898 char buf[30];
18899 rtx realsym;
18900 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18901 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18903 emit_insn (gen_elf_high (dest, realsym));
18904 emit_insn (gen_elf_low (dest, dest, realsym));
18906 else
18908 gcc_assert (DEFAULT_ABI == ABI_AIX);
18910 if (TARGET_32BIT)
18911 emit_insn (gen_load_toc_aix_si (dest));
18912 else
18913 emit_insn (gen_load_toc_aix_di (dest));
18917 /* Emit instructions to restore the link register after determining where
18918 its value has been stored. */
18920 void
18921 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18923 rs6000_stack_t *info = rs6000_stack_info ();
18924 rtx operands[2];
18926 operands[0] = source;
18927 operands[1] = scratch;
18929 if (info->lr_save_p)
18931 rtx frame_rtx = stack_pointer_rtx;
18932 HOST_WIDE_INT sp_offset = 0;
18933 rtx tmp;
18935 if (frame_pointer_needed
18936 || cfun->calls_alloca
18937 || info->total_size > 32767)
18939 tmp = gen_frame_mem (Pmode, frame_rtx);
18940 emit_move_insn (operands[1], tmp);
18941 frame_rtx = operands[1];
18943 else if (info->push_p)
18944 sp_offset = info->total_size;
18946 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18947 tmp = gen_frame_mem (Pmode, tmp);
18948 emit_move_insn (tmp, operands[0]);
18950 else
18951 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18953 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18954 state of lr_save_p so any change from here on would be a bug. In
18955 particular, stop rs6000_ra_ever_killed from considering the SET
18956 of lr we may have added just above. */
18957 cfun->machine->lr_save_state = info->lr_save_p + 1;
18960 static GTY(()) alias_set_type set = -1;
18962 alias_set_type
18963 get_TOC_alias_set (void)
18965 if (set == -1)
18966 set = new_alias_set ();
18967 return set;
18970 /* This returns nonzero if the current function uses the TOC. This is
18971 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18972 is generated by the ABI_V4 load_toc_* patterns. */
18973 #if TARGET_ELF
18974 static int
18975 uses_TOC (void)
18977 rtx insn;
18979 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18980 if (INSN_P (insn))
18982 rtx pat = PATTERN (insn);
18983 int i;
18985 if (GET_CODE (pat) == PARALLEL)
18986 for (i = 0; i < XVECLEN (pat, 0); i++)
18988 rtx sub = XVECEXP (pat, 0, i);
18989 if (GET_CODE (sub) == USE)
18991 sub = XEXP (sub, 0);
18992 if (GET_CODE (sub) == UNSPEC
18993 && XINT (sub, 1) == UNSPEC_TOC)
18994 return 1;
18998 return 0;
19000 #endif
19003 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19005 rtx tocrel, tocreg;
19007 if (TARGET_DEBUG_ADDR)
19009 if (GET_CODE (symbol) == SYMBOL_REF)
19010 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19011 XSTR (symbol, 0));
19012 else
19014 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19015 GET_RTX_NAME (GET_CODE (symbol)));
19016 debug_rtx (symbol);
19020 if (!can_create_pseudo_p ())
19021 df_set_regs_ever_live (TOC_REGISTER, true);
19023 tocrel = gen_rtx_CONST (Pmode,
19024 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19025 UNSPEC_TOCREL));
19026 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19027 if (TARGET_CMODEL != CMODEL_SMALL)
19029 rtx hi = gen_rtx_CONST (Pmode,
19030 gen_rtx_PLUS (Pmode, tocreg,
19031 gen_rtx_HIGH (Pmode, tocrel)));
19032 if (largetoc_reg != NULL)
19034 emit_move_insn (largetoc_reg, hi);
19035 hi = largetoc_reg;
19037 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19039 else
19040 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19043 /* Issue assembly directives that create a reference to the given DWARF
19044 FRAME_TABLE_LABEL from the current function section. */
19045 void
19046 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19048 fprintf (asm_out_file, "\t.ref %s\n",
19049 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19052 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19053 and the change to the stack pointer. */
19055 static void
19056 rs6000_emit_stack_tie (void)
19058 rtx mem = gen_frame_mem (BLKmode,
19059 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19061 emit_insn (gen_stack_tie (mem));
19064 /* Emit the correct code for allocating stack space, as insns.
19065 If COPY_REG, make sure a copy of the old frame is left there.
19066 The generated code may use hard register 0 as a temporary. */
19068 static void
19069 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19071 rtx insn;
19072 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19073 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19074 rtx todec = gen_int_mode (-size, Pmode);
19075 rtx par, set, mem;
19077 if (INTVAL (todec) != -size)
19079 warning (0, "stack frame too large");
19080 emit_insn (gen_trap ());
19081 return;
19084 if (crtl->limit_stack)
19086 if (REG_P (stack_limit_rtx)
19087 && REGNO (stack_limit_rtx) > 1
19088 && REGNO (stack_limit_rtx) <= 31)
19090 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19091 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19092 const0_rtx));
19094 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19095 && TARGET_32BIT
19096 && DEFAULT_ABI == ABI_V4)
19098 rtx toload = gen_rtx_CONST (VOIDmode,
19099 gen_rtx_PLUS (Pmode,
19100 stack_limit_rtx,
19101 GEN_INT (size)));
19103 emit_insn (gen_elf_high (tmp_reg, toload));
19104 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19105 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19106 const0_rtx));
19108 else
19109 warning (0, "stack limit expression is not supported");
19112 if (copy_reg)
19113 emit_move_insn (copy_reg, stack_reg);
19115 if (size > 32767)
19117 /* Need a note here so that try_split doesn't get confused. */
19118 if (get_last_insn () == NULL_RTX)
19119 emit_note (NOTE_INSN_DELETED);
19120 insn = emit_move_insn (tmp_reg, todec);
19121 try_split (PATTERN (insn), insn, 0);
19122 todec = tmp_reg;
19125 insn = emit_insn (TARGET_32BIT
19126 ? gen_movsi_update_stack (stack_reg, stack_reg,
19127 todec, stack_reg)
19128 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19129 todec, stack_reg));
19130 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19131 it now and set the alias set/attributes. The above gen_*_update
19132 calls will generate a PARALLEL with the MEM set being the first
19133 operation. */
19134 par = PATTERN (insn);
19135 gcc_assert (GET_CODE (par) == PARALLEL);
19136 set = XVECEXP (par, 0, 0);
19137 gcc_assert (GET_CODE (set) == SET);
19138 mem = SET_DEST (set);
19139 gcc_assert (MEM_P (mem));
19140 MEM_NOTRAP_P (mem) = 1;
19141 set_mem_alias_set (mem, get_frame_alias_set ());
19143 RTX_FRAME_RELATED_P (insn) = 1;
19144 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19145 gen_rtx_SET (VOIDmode, stack_reg,
19146 gen_rtx_PLUS (Pmode, stack_reg,
19147 GEN_INT (-size))));
19150 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19152 #if PROBE_INTERVAL > 32768
19153 #error Cannot use indexed addressing mode for stack probing
19154 #endif
19156 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19157 inclusive. These are offsets from the current stack pointer. */
19159 static void
19160 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19162 /* See if we have a constant small number of probes to generate. If so,
19163 that's the easy case. */
19164 if (first + size <= 32768)
19166 HOST_WIDE_INT i;
19168 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19169 it exceeds SIZE. If only one probe is needed, this will not
19170 generate any code. Then probe at FIRST + SIZE. */
19171 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19172 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19174 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19177 /* Otherwise, do the same as above, but in a loop. Note that we must be
19178 extra careful with variables wrapping around because we might be at
19179 the very top (or the very bottom) of the address space and we have
19180 to be able to handle this case properly; in particular, we use an
19181 equality test for the loop condition. */
19182 else
19184 HOST_WIDE_INT rounded_size;
19185 rtx r12 = gen_rtx_REG (Pmode, 12);
19186 rtx r0 = gen_rtx_REG (Pmode, 0);
19188 /* Sanity check for the addressing mode we're going to use. */
19189 gcc_assert (first <= 32768);
19191 /* Step 1: round SIZE to the previous multiple of the interval. */
19193 rounded_size = size & -PROBE_INTERVAL;
19196 /* Step 2: compute initial and final value of the loop counter. */
19198 /* TEST_ADDR = SP + FIRST. */
19199 emit_insn (gen_rtx_SET (VOIDmode, r12,
19200 plus_constant (stack_pointer_rtx, -first)));
19202 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19203 if (rounded_size > 32768)
19205 emit_move_insn (r0, GEN_INT (-rounded_size));
19206 emit_insn (gen_rtx_SET (VOIDmode, r0,
19207 gen_rtx_PLUS (Pmode, r12, r0)));
19209 else
19210 emit_insn (gen_rtx_SET (VOIDmode, r0,
19211 plus_constant (r12, -rounded_size)));
19214 /* Step 3: the loop
19216 while (TEST_ADDR != LAST_ADDR)
19218 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19219 probe at TEST_ADDR
19222 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19223 until it is equal to ROUNDED_SIZE. */
19225 if (TARGET_64BIT)
19226 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19227 else
19228 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19231 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19232 that SIZE is equal to ROUNDED_SIZE. */
19234 if (size != rounded_size)
19235 emit_stack_probe (plus_constant (r12, rounded_size - size));
19239 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19240 absolute addresses. */
19242 const char *
19243 output_probe_stack_range (rtx reg1, rtx reg2)
19245 static int labelno = 0;
19246 char loop_lab[32], end_lab[32];
19247 rtx xops[2];
19249 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19250 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19252 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19254 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19255 xops[0] = reg1;
19256 xops[1] = reg2;
19257 if (TARGET_64BIT)
19258 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19259 else
19260 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19262 fputs ("\tbeq 0,", asm_out_file);
19263 assemble_name_raw (asm_out_file, end_lab);
19264 fputc ('\n', asm_out_file);
19266 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19267 xops[1] = GEN_INT (-PROBE_INTERVAL);
19268 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19270 /* Probe at TEST_ADDR and branch. */
19271 xops[1] = gen_rtx_REG (Pmode, 0);
19272 output_asm_insn ("{st|stw} %1,0(%0)", xops);
19273 fprintf (asm_out_file, "\tb ");
19274 assemble_name_raw (asm_out_file, loop_lab);
19275 fputc ('\n', asm_out_file);
19277 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19279 return "";
19282 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19283 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19284 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19285 deduce these equivalences by itself so it wasn't necessary to hold
19286 its hand so much. */
19288 static rtx
19289 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19290 rtx reg2, rtx rreg)
19292 rtx real, temp;
19294 /* copy_rtx will not make unique copies of registers, so we need to
19295 ensure we don't have unwanted sharing here. */
19296 if (reg == reg2)
19297 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19299 if (reg == rreg)
19300 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19302 real = copy_rtx (PATTERN (insn));
19304 if (reg2 != NULL_RTX)
19305 real = replace_rtx (real, reg2, rreg);
19307 real = replace_rtx (real, reg,
19308 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19309 STACK_POINTER_REGNUM),
19310 GEN_INT (val)));
19312 /* We expect that 'real' is either a SET or a PARALLEL containing
19313 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19314 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19316 if (GET_CODE (real) == SET)
19318 rtx set = real;
19320 temp = simplify_rtx (SET_SRC (set));
19321 if (temp)
19322 SET_SRC (set) = temp;
19323 temp = simplify_rtx (SET_DEST (set));
19324 if (temp)
19325 SET_DEST (set) = temp;
19326 if (GET_CODE (SET_DEST (set)) == MEM)
19328 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19329 if (temp)
19330 XEXP (SET_DEST (set), 0) = temp;
19333 else
19335 int i;
19337 gcc_assert (GET_CODE (real) == PARALLEL);
19338 for (i = 0; i < XVECLEN (real, 0); i++)
19339 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19341 rtx set = XVECEXP (real, 0, i);
19343 temp = simplify_rtx (SET_SRC (set));
19344 if (temp)
19345 SET_SRC (set) = temp;
19346 temp = simplify_rtx (SET_DEST (set));
19347 if (temp)
19348 SET_DEST (set) = temp;
19349 if (GET_CODE (SET_DEST (set)) == MEM)
19351 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19352 if (temp)
19353 XEXP (SET_DEST (set), 0) = temp;
19355 RTX_FRAME_RELATED_P (set) = 1;
19359 RTX_FRAME_RELATED_P (insn) = 1;
19360 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19362 return insn;
19365 /* Returns an insn that has a vrsave set operation with the
19366 appropriate CLOBBERs. */
19368 static rtx
19369 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19371 int nclobs, i;
19372 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19373 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19375 clobs[0]
19376 = gen_rtx_SET (VOIDmode,
19377 vrsave,
19378 gen_rtx_UNSPEC_VOLATILE (SImode,
19379 gen_rtvec (2, reg, vrsave),
19380 UNSPECV_SET_VRSAVE));
19382 nclobs = 1;
19384 /* We need to clobber the registers in the mask so the scheduler
19385 does not move sets to VRSAVE before sets of AltiVec registers.
19387 However, if the function receives nonlocal gotos, reload will set
19388 all call saved registers live. We will end up with:
19390 (set (reg 999) (mem))
19391 (parallel [ (set (reg vrsave) (unspec blah))
19392 (clobber (reg 999))])
19394 The clobber will cause the store into reg 999 to be dead, and
19395 flow will attempt to delete an epilogue insn. In this case, we
19396 need an unspec use/set of the register. */
19398 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19399 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19401 if (!epiloguep || call_used_regs [i])
19402 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19403 gen_rtx_REG (V4SImode, i));
19404 else
19406 rtx reg = gen_rtx_REG (V4SImode, i);
19408 clobs[nclobs++]
19409 = gen_rtx_SET (VOIDmode,
19410 reg,
19411 gen_rtx_UNSPEC (V4SImode,
19412 gen_rtvec (1, reg), 27));
19416 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19418 for (i = 0; i < nclobs; ++i)
19419 XVECEXP (insn, 0, i) = clobs[i];
19421 return insn;
19424 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19425 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19427 static rtx
19428 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19429 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19431 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19432 rtx replacea, replaceb;
19434 int_rtx = GEN_INT (offset);
19436 /* Some cases that need register indexed addressing. */
19437 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19438 || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
19439 || (TARGET_E500_DOUBLE && mode == DFmode)
19440 || (TARGET_SPE_ABI
19441 && SPE_VECTOR_MODE (mode)
19442 && !SPE_CONST_OFFSET_OK (offset)))
19444 /* Whomever calls us must make sure r11 is available in the
19445 flow path of instructions in the prologue. */
19446 offset_rtx = gen_rtx_REG (Pmode, 11);
19447 emit_move_insn (offset_rtx, int_rtx);
19449 replacea = offset_rtx;
19450 replaceb = int_rtx;
19452 else
19454 offset_rtx = int_rtx;
19455 replacea = NULL_RTX;
19456 replaceb = NULL_RTX;
19459 reg = gen_rtx_REG (mode, regno);
19460 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19461 mem = gen_frame_mem (mode, addr);
19463 insn = emit_move_insn (mem, reg);
19465 return rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19468 /* Emit an offset memory reference suitable for a frame store, while
19469 converting to a valid addressing mode. */
19471 static rtx
19472 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19474 rtx int_rtx, offset_rtx;
19476 int_rtx = GEN_INT (offset);
19478 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19479 || (TARGET_E500_DOUBLE && mode == DFmode))
19481 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19482 emit_move_insn (offset_rtx, int_rtx);
19484 else
19485 offset_rtx = int_rtx;
19487 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19490 /* Look for user-defined global regs. We should not save and restore these,
19491 and cannot use stmw/lmw if there are any in its range. */
19493 static bool
19494 no_global_regs_above (int first, bool gpr)
19496 int i;
19497 int last = gpr ? 32 : 64;
19498 for (i = first; i < last; i++)
19499 if (global_regs[i])
19500 return false;
19501 return true;
19504 #ifndef TARGET_FIX_AND_CONTINUE
19505 #define TARGET_FIX_AND_CONTINUE 0
19506 #endif
19508 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19509 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19510 #define LAST_SAVRES_REGISTER 31
19511 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19513 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19515 /* Temporary holding space for an out-of-line register save/restore
19516 routine name. */
19517 static char savres_routine_name[30];
19519 /* Return the name for an out-of-line register save/restore routine.
19520 We are saving/restoring GPRs if GPR is true. */
19522 static char *
19523 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19524 bool savep, bool gpr, bool lr)
19526 const char *prefix = "";
19527 const char *suffix = "";
19529 /* Different targets are supposed to define
19530 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19531 routine name could be defined with:
19533 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19535 This is a nice idea in practice, but in reality, things are
19536 complicated in several ways:
19538 - ELF targets have save/restore routines for GPRs.
19540 - SPE targets use different prefixes for 32/64-bit registers, and
19541 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19543 - PPC64 ELF targets have routines for save/restore of GPRs that
19544 differ in what they do with the link register, so having a set
19545 prefix doesn't work. (We only use one of the save routines at
19546 the moment, though.)
19548 - PPC32 elf targets have "exit" versions of the restore routines
19549 that restore the link register and can save some extra space.
19550 These require an extra suffix. (There are also "tail" versions
19551 of the restore routines and "GOT" versions of the save routines,
19552 but we don't generate those at present. Same problems apply,
19553 though.)
19555 We deal with all this by synthesizing our own prefix/suffix and
19556 using that for the simple sprintf call shown above. */
19557 if (TARGET_SPE)
19559 /* No floating point saves on the SPE. */
19560 gcc_assert (gpr);
19562 if (savep)
19563 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19564 else
19565 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19567 if (lr)
19568 suffix = "_x";
19570 else if (DEFAULT_ABI == ABI_V4)
19572 if (TARGET_64BIT)
19573 goto aix_names;
19575 if (gpr)
19576 prefix = savep ? "_savegpr_" : "_restgpr_";
19577 else
19578 prefix = savep ? "_savefpr_" : "_restfpr_";
19580 if (lr)
19581 suffix = "_x";
19583 else if (DEFAULT_ABI == ABI_AIX)
19585 #ifndef POWERPC_LINUX
19586 /* No out-of-line save/restore routines for GPRs on AIX. */
19587 gcc_assert (!TARGET_AIX || !gpr);
19588 #endif
19590 aix_names:
19591 if (gpr)
19592 prefix = (savep
19593 ? (lr ? "_savegpr0_" : "_savegpr1_")
19594 : (lr ? "_restgpr0_" : "_restgpr1_"));
19595 #ifdef POWERPC_LINUX
19596 else if (lr)
19597 prefix = (savep ? "_savefpr_" : "_restfpr_");
19598 #endif
19599 else
19601 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19602 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19606 if (DEFAULT_ABI == ABI_DARWIN)
19608 /* The Darwin approach is (slightly) different, in order to be
19609 compatible with code generated by the system toolchain. There is a
19610 single symbol for the start of save sequence, and the code here
19611 embeds an offset into that code on the basis of the first register
19612 to be saved. */
19613 prefix = savep ? "save" : "rest" ;
19614 if (gpr)
19615 sprintf (savres_routine_name, "*%sGPR%s%s%.0d ; %s r%d-r31",
19616 prefix, (lr ? "x" : ""), (regno == 13 ? "" : "+"),
19617 (regno-13) * 4, prefix, regno);
19618 else
19619 sprintf (savres_routine_name, "*%sFP%s%.0d ; %s f%d-f31",
19620 prefix, (regno == 14 ? "" : "+"), (regno-14) * 4, prefix, regno);
19622 else
19623 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19625 return savres_routine_name;
19628 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19629 We are saving/restoring GPRs if GPR is true. */
19631 static rtx
19632 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19633 bool gpr, bool lr)
19635 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19636 rtx sym;
19637 int select = ((savep ? 1 : 0) << 2
19638 | ((TARGET_SPE_ABI
19639 /* On the SPE, we never have any FPRs, but we do have
19640 32/64-bit versions of the routines. */
19641 ? (info->spe_64bit_regs_used ? 1 : 0)
19642 : (gpr ? 1 : 0)) << 1)
19643 | (lr ? 1: 0));
19645 /* Don't generate bogus routine names. */
19646 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19647 && regno <= LAST_SAVRES_REGISTER);
19649 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19651 if (sym == NULL)
19653 char *name;
19655 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19657 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19658 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19659 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19662 return sym;
19665 /* Emit a sequence of insns, including a stack tie if needed, for
19666 resetting the stack pointer. If SAVRES is true, then don't reset the
19667 stack pointer, but move the base of the frame into r11 for use by
19668 out-of-line register restore routines. */
19670 static rtx
19671 rs6000_emit_stack_reset (rs6000_stack_t *info,
19672 rtx sp_reg_rtx, rtx frame_reg_rtx,
19673 int sp_offset, bool savres)
19675 /* This blockage is needed so that sched doesn't decide to move
19676 the sp change before the register restores. */
19677 if (DEFAULT_ABI == ABI_V4
19678 || (TARGET_SPE_ABI
19679 && info->spe_64bit_regs_used != 0
19680 && info->first_gp_reg_save != 32))
19681 rs6000_emit_stack_tie ();
19683 if (frame_reg_rtx != sp_reg_rtx)
19685 if (sp_offset != 0)
19687 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19688 rtx insn = emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19689 GEN_INT (sp_offset)));
19690 if (!savres)
19691 return insn;
19693 else if (!savres)
19694 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19696 else if (sp_offset != 0)
19698 /* If we are restoring registers out-of-line, we will be using the
19699 "exit" variants of the restore routines, which will reset the
19700 stack for us. But we do need to point r11 into the right place
19701 for those routines. */
19702 rtx dest_reg = (savres
19703 ? gen_rtx_REG (Pmode, 11)
19704 : sp_reg_rtx);
19706 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19707 GEN_INT (sp_offset)));
19708 if (!savres)
19709 return insn;
19711 return NULL_RTX;
19714 /* Construct a parallel rtx describing the effect of a call to an
19715 out-of-line register save/restore routine, and emit the insn
19716 or jump_insn as appropriate. */
19718 static rtx
19719 rs6000_emit_savres_rtx (rs6000_stack_t *info,
19720 rtx frame_reg_rtx, int save_area_offset,
19721 enum machine_mode reg_mode,
19722 bool savep, bool gpr, bool lr)
19724 int i;
19725 int offset, start_reg, end_reg, n_regs, use_reg;
19726 int reg_size = GET_MODE_SIZE (reg_mode);
19727 rtx sym;
19728 rtvec p;
19729 rtx par, insn;
19731 offset = 0;
19732 start_reg = (gpr
19733 ? info->first_gp_reg_save
19734 : info->first_fp_reg_save);
19735 end_reg = gpr ? 32 : 64;
19736 n_regs = end_reg - start_reg;
19737 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19739 if (!savep && lr)
19740 RTVEC_ELT (p, offset++) = ret_rtx;
19742 RTVEC_ELT (p, offset++)
19743 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
19745 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19746 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19747 use_reg = DEFAULT_ABI == ABI_AIX ? (gpr && !lr ? 12 : 1)
19748 : DEFAULT_ABI == ABI_DARWIN && !gpr ? 1
19749 : 11;
19750 RTVEC_ELT (p, offset++)
19751 = gen_rtx_USE (VOIDmode,
19752 gen_rtx_REG (Pmode, use_reg));
19754 for (i = 0; i < end_reg - start_reg; i++)
19756 rtx addr, reg, mem;
19757 reg = gen_rtx_REG (reg_mode, start_reg + i);
19758 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19759 GEN_INT (save_area_offset + reg_size*i));
19760 mem = gen_frame_mem (reg_mode, addr);
19762 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19763 savep ? mem : reg,
19764 savep ? reg : mem);
19767 if (savep && lr)
19769 rtx addr, reg, mem;
19770 reg = gen_rtx_REG (Pmode, 0);
19771 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19772 GEN_INT (info->lr_save_offset));
19773 mem = gen_frame_mem (Pmode, addr);
19774 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19777 par = gen_rtx_PARALLEL (VOIDmode, p);
19779 if (!savep && lr)
19781 insn = emit_jump_insn (par);
19782 JUMP_LABEL (insn) = ret_rtx;
19784 else
19785 insn = emit_insn (par);
19786 return insn;
19789 /* Determine whether the gp REG is really used. */
19791 static bool
19792 rs6000_reg_live_or_pic_offset_p (int reg)
19794 /* If the function calls eh_return, claim used all the registers that would
19795 be checked for liveness otherwise. This is required for the PIC offset
19796 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19797 register allocation purposes in this case. */
19799 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19800 && (!call_used_regs[reg]
19801 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19802 && !TARGET_SINGLE_PIC_BASE
19803 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19804 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19805 && !TARGET_SINGLE_PIC_BASE
19806 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19807 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19810 /* Emit function prologue as insns. */
19812 void
19813 rs6000_emit_prologue (void)
19815 rs6000_stack_t *info = rs6000_stack_info ();
19816 enum machine_mode reg_mode = Pmode;
19817 int reg_size = TARGET_32BIT ? 4 : 8;
19818 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19819 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19820 rtx frame_reg_rtx = sp_reg_rtx;
19821 rtx cr_save_rtx = NULL_RTX;
19822 rtx insn;
19823 int strategy;
19824 int saving_FPRs_inline;
19825 int saving_GPRs_inline;
19826 int using_store_multiple;
19827 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19828 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19829 && call_used_regs[STATIC_CHAIN_REGNUM]);
19830 HOST_WIDE_INT sp_offset = 0;
19832 if (flag_stack_usage_info)
19833 current_function_static_stack_size = info->total_size;
19835 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19836 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19838 if (TARGET_FIX_AND_CONTINUE)
19840 /* gdb on darwin arranges to forward a function from the old
19841 address by modifying the first 5 instructions of the function
19842 to branch to the overriding function. This is necessary to
19843 permit function pointers that point to the old function to
19844 actually forward to the new function. */
19845 emit_insn (gen_nop ());
19846 emit_insn (gen_nop ());
19847 emit_insn (gen_nop ());
19848 emit_insn (gen_nop ());
19849 emit_insn (gen_nop ());
19852 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19854 reg_mode = V2SImode;
19855 reg_size = 8;
19858 strategy = info->savres_strategy;
19859 using_store_multiple = strategy & SAVRES_MULTIPLE;
19860 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19861 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19863 /* For V.4, update stack before we do any saving and set back pointer. */
19864 if (! WORLD_SAVE_P (info)
19865 && info->push_p
19866 && (DEFAULT_ABI == ABI_V4
19867 || crtl->calls_eh_return))
19869 bool need_r11 = (TARGET_SPE
19870 ? (!saving_GPRs_inline
19871 && info->spe_64bit_regs_used == 0)
19872 : (!saving_FPRs_inline || !saving_GPRs_inline));
19873 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19875 if (info->total_size < 32767)
19876 sp_offset = info->total_size;
19877 else if (need_r11)
19878 frame_reg_rtx = copy_reg;
19879 else if (info->cr_save_p
19880 || info->lr_save_p
19881 || info->first_fp_reg_save < 64
19882 || info->first_gp_reg_save < 32
19883 || info->altivec_size != 0
19884 || info->vrsave_mask != 0
19885 || crtl->calls_eh_return)
19887 copy_reg = frame_ptr_rtx;
19888 frame_reg_rtx = copy_reg;
19890 else
19892 /* The prologue won't be saving any regs so there is no need
19893 to set up a frame register to access any frame save area.
19894 We also won't be using sp_offset anywhere below, but set
19895 the correct value anyway to protect against future
19896 changes to this function. */
19897 sp_offset = info->total_size;
19899 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19900 if (frame_reg_rtx != sp_reg_rtx)
19901 rs6000_emit_stack_tie ();
19904 /* Handle world saves specially here. */
19905 if (WORLD_SAVE_P (info))
19907 int i, j, sz;
19908 rtx treg;
19909 rtvec p;
19910 rtx reg0;
19912 /* save_world expects lr in r0. */
19913 reg0 = gen_rtx_REG (Pmode, 0);
19914 if (info->lr_save_p)
19916 insn = emit_move_insn (reg0,
19917 gen_rtx_REG (Pmode, LR_REGNO));
19918 RTX_FRAME_RELATED_P (insn) = 1;
19921 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19922 assumptions about the offsets of various bits of the stack
19923 frame. */
19924 gcc_assert (info->gp_save_offset == -220
19925 && info->fp_save_offset == -144
19926 && info->lr_save_offset == 8
19927 && info->cr_save_offset == 4
19928 && info->push_p
19929 && info->lr_save_p
19930 && (!crtl->calls_eh_return
19931 || info->ehrd_offset == -432)
19932 && info->vrsave_save_offset == -224
19933 && info->altivec_save_offset == -416);
19935 treg = gen_rtx_REG (SImode, 11);
19936 emit_move_insn (treg, GEN_INT (-info->total_size));
19938 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19939 in R11. It also clobbers R12, so beware! */
19941 /* Preserve CR2 for save_world prologues */
19942 sz = 5;
19943 sz += 32 - info->first_gp_reg_save;
19944 sz += 64 - info->first_fp_reg_save;
19945 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19946 p = rtvec_alloc (sz);
19947 j = 0;
19948 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19949 gen_rtx_REG (SImode,
19950 LR_REGNO));
19951 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19952 gen_rtx_SYMBOL_REF (Pmode,
19953 "*save_world"));
19954 /* We do floats first so that the instruction pattern matches
19955 properly. */
19956 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19958 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19959 ? DFmode : SFmode),
19960 info->first_fp_reg_save + i);
19961 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19962 GEN_INT (info->fp_save_offset
19963 + sp_offset + 8 * i));
19964 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19965 ? DFmode : SFmode), addr);
19967 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19969 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19971 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19972 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19973 GEN_INT (info->altivec_save_offset
19974 + sp_offset + 16 * i));
19975 rtx mem = gen_frame_mem (V4SImode, addr);
19977 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19979 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19981 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19982 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19983 GEN_INT (info->gp_save_offset
19984 + sp_offset + reg_size * i));
19985 rtx mem = gen_frame_mem (reg_mode, addr);
19987 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19991 /* CR register traditionally saved as CR2. */
19992 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19993 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19994 GEN_INT (info->cr_save_offset
19995 + sp_offset));
19996 rtx mem = gen_frame_mem (reg_mode, addr);
19998 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20000 /* Explain about use of R0. */
20001 if (info->lr_save_p)
20003 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20004 GEN_INT (info->lr_save_offset
20005 + sp_offset));
20006 rtx mem = gen_frame_mem (reg_mode, addr);
20008 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20010 /* Explain what happens to the stack pointer. */
20012 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20013 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20016 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20017 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20018 treg, GEN_INT (-info->total_size));
20019 sp_offset = info->total_size;
20022 /* If we use the link register, get it into r0. */
20023 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20025 rtx addr, reg, mem;
20027 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20028 gen_rtx_REG (Pmode, LR_REGNO));
20029 RTX_FRAME_RELATED_P (insn) = 1;
20031 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20032 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20034 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20035 GEN_INT (info->lr_save_offset + sp_offset));
20036 reg = gen_rtx_REG (Pmode, 0);
20037 mem = gen_rtx_MEM (Pmode, addr);
20038 /* This should not be of rs6000_sr_alias_set, because of
20039 __builtin_return_address. */
20041 insn = emit_move_insn (mem, reg);
20042 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20043 NULL_RTX, NULL_RTX);
20047 /* If we need to save CR, put it into r12 or r11. */
20048 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20050 rtx set;
20052 cr_save_rtx
20053 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20054 ? 11 : 12);
20055 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20056 RTX_FRAME_RELATED_P (insn) = 1;
20057 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20058 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20059 But that's OK. All we have to do is specify that _one_ condition
20060 code register is saved in this stack slot. The thrower's epilogue
20061 will then restore all the call-saved registers.
20062 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20063 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20064 gen_rtx_REG (SImode, CR2_REGNO));
20065 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20068 /* Do any required saving of fpr's. If only one or two to save, do
20069 it ourselves. Otherwise, call function. */
20070 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20072 int i;
20073 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20074 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20075 && ! call_used_regs[info->first_fp_reg_save+i]))
20076 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20077 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20078 ? DFmode : SFmode,
20079 info->first_fp_reg_save + i,
20080 info->fp_save_offset + sp_offset + 8 * i,
20081 info->total_size);
20083 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20085 insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
20086 info->fp_save_offset + sp_offset,
20087 DFmode,
20088 /*savep=*/true, /*gpr=*/false,
20089 /*lr=*/((strategy
20090 & SAVE_NOINLINE_FPRS_SAVES_LR)
20091 != 0));
20092 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20093 NULL_RTX, NULL_RTX);
20096 /* Save GPRs. This is done as a PARALLEL if we are using
20097 the store-multiple instructions. */
20098 if (!WORLD_SAVE_P (info)
20099 && TARGET_SPE_ABI
20100 && info->spe_64bit_regs_used != 0
20101 && info->first_gp_reg_save != 32)
20103 int i;
20104 rtx spe_save_area_ptr;
20106 /* Determine whether we can address all of the registers that need
20107 to be saved with an offset from the stack pointer that fits in
20108 the small const field for SPE memory instructions. */
20109 int spe_regs_addressable_via_sp
20110 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20111 + (32 - info->first_gp_reg_save - 1) * reg_size)
20112 && saving_GPRs_inline);
20113 int spe_offset;
20115 if (spe_regs_addressable_via_sp)
20117 spe_save_area_ptr = frame_reg_rtx;
20118 spe_offset = info->spe_gp_save_offset + sp_offset;
20120 else
20122 /* Make r11 point to the start of the SPE save area. We need
20123 to be careful here if r11 is holding the static chain. If
20124 it is, then temporarily save it in r0. We would use r0 as
20125 our base register here, but using r0 as a base register in
20126 loads and stores means something different from what we
20127 would like. */
20128 int ool_adjust = (saving_GPRs_inline
20130 : (info->first_gp_reg_save
20131 - (FIRST_SAVRES_REGISTER+1))*8);
20132 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20133 + sp_offset - ool_adjust);
20135 if (using_static_chain_p)
20137 rtx r0 = gen_rtx_REG (Pmode, 0);
20138 gcc_assert (info->first_gp_reg_save > 11);
20140 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20143 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20144 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20145 frame_reg_rtx,
20146 GEN_INT (offset)));
20147 /* We need to make sure the move to r11 gets noted for
20148 properly outputting unwind information. */
20149 if (!saving_GPRs_inline)
20150 rs6000_frame_related (insn, frame_reg_rtx, offset,
20151 NULL_RTX, NULL_RTX);
20152 spe_offset = 0;
20155 if (saving_GPRs_inline)
20157 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20158 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20160 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20161 rtx offset, addr, mem;
20163 /* We're doing all this to ensure that the offset fits into
20164 the immediate offset of 'evstdd'. */
20165 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20167 offset = GEN_INT (reg_size * i + spe_offset);
20168 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20169 mem = gen_rtx_MEM (V2SImode, addr);
20171 insn = emit_move_insn (mem, reg);
20173 rs6000_frame_related (insn, spe_save_area_ptr,
20174 info->spe_gp_save_offset
20175 + sp_offset + reg_size * i,
20176 offset, const0_rtx);
20179 else
20181 insn = rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20182 0, reg_mode,
20183 /*savep=*/true, /*gpr=*/true,
20184 /*lr=*/false);
20185 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20186 NULL_RTX, NULL_RTX);
20190 /* Move the static chain pointer back. */
20191 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20192 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20194 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20196 if (DEFAULT_ABI == ABI_DARWIN)
20198 rtx dest_reg = gen_rtx_REG (reg_mode, 11);
20199 if (info->first_fp_reg_save == 64)
20200 /* we only need a copy, no fprs were saved. */
20201 emit_move_insn (dest_reg, frame_reg_rtx);
20202 else
20204 rtx offset = GEN_INT (sp_offset
20205 + (-8 * (64-info->first_fp_reg_save)));
20206 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20209 /* Need to adjust r11 (r12) if we saved any FPRs. */
20210 else if (info->first_fp_reg_save != 64)
20212 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20213 ? 12 : 11);
20214 rtx offset = GEN_INT (sp_offset
20215 + (-8 * (64-info->first_fp_reg_save)));
20216 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20219 insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
20220 info->gp_save_offset + sp_offset,
20221 reg_mode,
20222 /*savep=*/true, /*gpr=*/true,
20223 /*lr=*/((strategy
20224 & SAVE_NOINLINE_GPRS_SAVES_LR)
20225 != 0));
20226 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20227 NULL_RTX, NULL_RTX);
20229 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20231 rtvec p;
20232 int i;
20233 p = rtvec_alloc (32 - info->first_gp_reg_save);
20234 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20236 rtx addr, reg, mem;
20237 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20238 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20239 GEN_INT (info->gp_save_offset
20240 + sp_offset
20241 + reg_size * i));
20242 mem = gen_frame_mem (reg_mode, addr);
20244 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20246 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20247 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20248 NULL_RTX, NULL_RTX);
20250 else if (!WORLD_SAVE_P (info))
20252 int i;
20253 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20254 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20256 rtx addr, reg, mem;
20257 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20259 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20260 GEN_INT (info->gp_save_offset
20261 + sp_offset
20262 + reg_size * i));
20263 mem = gen_frame_mem (reg_mode, addr);
20265 insn = emit_move_insn (mem, reg);
20266 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20267 NULL_RTX, NULL_RTX);
20271 /* ??? There's no need to emit actual instructions here, but it's the
20272 easiest way to get the frame unwind information emitted. */
20273 if (crtl->calls_eh_return)
20275 unsigned int i, regno;
20277 for (i = 0; ; ++i)
20279 regno = EH_RETURN_DATA_REGNO (i);
20280 if (regno == INVALID_REGNUM)
20281 break;
20283 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20284 info->ehrd_offset + sp_offset
20285 + reg_size * (int) i,
20286 info->total_size);
20290 /* In AIX ABI we need to make sure r2 is really saved. */
20291 if (TARGET_AIX && crtl->calls_eh_return)
20293 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20294 rtx save_insn, join_insn, note;
20295 long toc_restore_insn;
20297 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20298 || frame_reg_rtx == sp_reg_rtx);
20299 tmp_reg = gen_rtx_REG (Pmode, 11);
20300 tmp_reg_si = gen_rtx_REG (SImode, 11);
20301 if (using_static_chain_p)
20302 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20303 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20304 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20305 /* Peek at instruction to which this function returns. If it's
20306 restoring r2, then we know we've already saved r2. We can't
20307 unconditionally save r2 because the value we have will already
20308 be updated if we arrived at this function via a plt call or
20309 toc adjusting stub. */
20310 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20311 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20312 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20313 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20314 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20315 validate_condition_mode (EQ, CCUNSmode);
20316 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20317 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20318 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20319 toc_save_done = gen_label_rtx ();
20320 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20321 gen_rtx_EQ (VOIDmode, compare_result,
20322 const0_rtx),
20323 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20324 pc_rtx);
20325 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20326 JUMP_LABEL (jump) = toc_save_done;
20327 LABEL_NUSES (toc_save_done) += 1;
20329 save_insn = emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode,
20330 TOC_REGNUM, sp_offset + 5 * reg_size,
20331 info->total_size);
20333 emit_label (toc_save_done);
20335 /* ??? If we leave SAVE_INSN as marked as saving R2, then we'll
20336 have a CFG that has different saves along different paths.
20337 Move the note to a dummy blockage insn, which describes that
20338 R2 is unconditionally saved after the label. */
20339 /* ??? An alternate representation might be a special insn pattern
20340 containing both the branch and the store. That might let the
20341 code that minimizes the number of DW_CFA_advance opcodes better
20342 freedom in placing the annotations. */
20343 note = find_reg_note (save_insn, REG_FRAME_RELATED_EXPR, NULL);
20344 gcc_assert (note);
20345 remove_note (save_insn, note);
20346 RTX_FRAME_RELATED_P (save_insn) = 0;
20348 join_insn = emit_insn (gen_blockage ());
20349 REG_NOTES (join_insn) = note;
20350 RTX_FRAME_RELATED_P (join_insn) = 1;
20352 if (using_static_chain_p)
20353 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20356 /* Save CR if we use any that must be preserved. */
20357 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20359 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20360 GEN_INT (info->cr_save_offset + sp_offset));
20361 rtx mem = gen_frame_mem (SImode, addr);
20362 /* See the large comment above about why CR2_REGNO is used. */
20363 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20365 /* If r12 was used to hold the original sp, copy cr into r0 now
20366 that it's free. */
20367 if (REGNO (frame_reg_rtx) == 12)
20369 rtx set;
20371 cr_save_rtx = gen_rtx_REG (SImode, 0);
20372 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20373 RTX_FRAME_RELATED_P (insn) = 1;
20374 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20375 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20377 insn = emit_move_insn (mem, cr_save_rtx);
20379 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20380 NULL_RTX, NULL_RTX);
20383 /* Update stack and set back pointer unless this is V.4,
20384 for which it was done previously. */
20385 if (!WORLD_SAVE_P (info) && info->push_p
20386 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20388 rtx copy_reg = NULL;
20390 if (info->total_size < 32767)
20391 sp_offset = info->total_size;
20392 else if (info->altivec_size != 0
20393 || info->vrsave_mask != 0)
20395 copy_reg = frame_ptr_rtx;
20396 frame_reg_rtx = copy_reg;
20398 else
20399 sp_offset = info->total_size;
20400 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20401 if (frame_reg_rtx != sp_reg_rtx)
20402 rs6000_emit_stack_tie ();
20405 /* Set frame pointer, if needed. */
20406 if (frame_pointer_needed)
20408 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20409 sp_reg_rtx);
20410 RTX_FRAME_RELATED_P (insn) = 1;
20413 /* Save AltiVec registers if needed. Save here because the red zone does
20414 not include AltiVec registers. */
20415 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20417 int i;
20419 /* There should be a non inline version of this, for when we
20420 are saving lots of vector registers. */
20421 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20422 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20424 rtx areg, savereg, mem;
20425 int offset;
20427 offset = info->altivec_save_offset + sp_offset
20428 + 16 * (i - info->first_altivec_reg_save);
20430 savereg = gen_rtx_REG (V4SImode, i);
20432 areg = gen_rtx_REG (Pmode, 0);
20433 emit_move_insn (areg, GEN_INT (offset));
20435 /* AltiVec addressing mode is [reg+reg]. */
20436 mem = gen_frame_mem (V4SImode,
20437 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20439 insn = emit_move_insn (mem, savereg);
20441 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20442 areg, GEN_INT (offset));
20446 /* VRSAVE is a bit vector representing which AltiVec registers
20447 are used. The OS uses this to determine which vector
20448 registers to save on a context switch. We need to save
20449 VRSAVE on the stack frame, add whatever AltiVec registers we
20450 used in this function, and do the corresponding magic in the
20451 epilogue. */
20453 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20454 && info->vrsave_mask != 0)
20456 rtx reg, mem, vrsave;
20457 int offset;
20459 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20460 as frame_reg_rtx and r11 as the static chain pointer for
20461 nested functions. */
20462 reg = gen_rtx_REG (SImode, 0);
20463 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20464 if (TARGET_MACHO)
20465 emit_insn (gen_get_vrsave_internal (reg));
20466 else
20467 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20469 if (!WORLD_SAVE_P (info))
20471 /* Save VRSAVE. */
20472 offset = info->vrsave_save_offset + sp_offset;
20473 mem = gen_frame_mem (SImode,
20474 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20475 GEN_INT (offset)));
20476 insn = emit_move_insn (mem, reg);
20479 /* Include the registers in the mask. */
20480 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20482 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20485 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20486 if (!TARGET_SINGLE_PIC_BASE
20487 && ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20488 || (DEFAULT_ABI == ABI_V4
20489 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20490 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))))
20492 /* If emit_load_toc_table will use the link register, we need to save
20493 it. We use R12 for this purpose because emit_load_toc_table
20494 can use register 0. This allows us to use a plain 'blr' to return
20495 from the procedure more often. */
20496 int save_LR_around_toc_setup = (TARGET_ELF
20497 && DEFAULT_ABI != ABI_AIX
20498 && flag_pic
20499 && ! info->lr_save_p
20500 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20501 if (save_LR_around_toc_setup)
20503 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20505 insn = emit_move_insn (frame_ptr_rtx, lr);
20506 RTX_FRAME_RELATED_P (insn) = 1;
20508 rs6000_emit_load_toc_table (TRUE);
20510 insn = emit_move_insn (lr, frame_ptr_rtx);
20511 add_reg_note (insn, REG_CFA_RESTORE, lr);
20512 RTX_FRAME_RELATED_P (insn) = 1;
20514 else
20515 rs6000_emit_load_toc_table (TRUE);
20518 #if TARGET_MACHO
20519 if (!TARGET_SINGLE_PIC_BASE
20520 && DEFAULT_ABI == ABI_DARWIN
20521 && flag_pic && crtl->uses_pic_offset_table)
20523 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20524 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20526 /* Save and restore LR locally around this call (in R0). */
20527 if (!info->lr_save_p)
20528 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20530 emit_insn (gen_load_macho_picbase (src));
20532 emit_move_insn (gen_rtx_REG (Pmode,
20533 RS6000_PIC_OFFSET_TABLE_REGNUM),
20534 lr);
20536 if (!info->lr_save_p)
20537 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20539 #endif
20541 /* If we need to, save the TOC register after doing the stack setup.
20542 Do not emit eh frame info for this save. The unwinder wants info,
20543 conceptually attached to instructions in this function, about
20544 register values in the caller of this function. This R2 may have
20545 already been changed from the value in the caller.
20546 We don't attempt to write accurate DWARF EH frame info for R2
20547 because code emitted by gcc for a (non-pointer) function call
20548 doesn't save and restore R2. Instead, R2 is managed out-of-line
20549 by a linker generated plt call stub when the function resides in
20550 a shared library. This behaviour is costly to describe in DWARF,
20551 both in terms of the size of DWARF info and the time taken in the
20552 unwinder to interpret it. R2 changes, apart from the
20553 calls_eh_return case earlier in this function, are handled by
20554 linux-unwind.h frob_update_context. */
20555 if (rs6000_save_toc_in_prologue_p ())
20557 rtx addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, GEN_INT (5 * reg_size));
20558 rtx mem = gen_frame_mem (reg_mode, addr);
20559 emit_move_insn (mem, gen_rtx_REG (reg_mode, TOC_REGNUM));
20563 /* Write function prologue. */
20565 static void
20566 rs6000_output_function_prologue (FILE *file,
20567 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20569 rs6000_stack_t *info = rs6000_stack_info ();
20571 if (TARGET_DEBUG_STACK)
20572 debug_stack_info (info);
20574 /* Write .extern for any function we will call to save and restore
20575 fp values. */
20576 if (info->first_fp_reg_save < 64
20577 && !TARGET_MACHO)
20579 char *name;
20580 int regno = info->first_fp_reg_save - 32;
20582 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20584 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20585 /*gpr=*/false, /*lr=*/false);
20586 fprintf (file, "\t.extern %s\n", name);
20588 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20590 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20591 /*gpr=*/false, /*lr=*/true);
20592 fprintf (file, "\t.extern %s\n", name);
20596 /* Write .extern for AIX common mode routines, if needed. */
20597 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20599 fputs ("\t.extern __mulh\n", file);
20600 fputs ("\t.extern __mull\n", file);
20601 fputs ("\t.extern __divss\n", file);
20602 fputs ("\t.extern __divus\n", file);
20603 fputs ("\t.extern __quoss\n", file);
20604 fputs ("\t.extern __quous\n", file);
20605 common_mode_defined = 1;
20608 rs6000_pic_labelno++;
20611 /* Non-zero if vmx regs are restored before the frame pop, zero if
20612 we restore after the pop when possible. */
20613 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20615 /* Reload CR from REG. */
20617 static void
20618 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20620 int count = 0;
20621 int i;
20623 if (using_mfcr_multiple)
20625 for (i = 0; i < 8; i++)
20626 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20627 count++;
20628 gcc_assert (count);
20631 if (using_mfcr_multiple && count > 1)
20633 rtvec p;
20634 int ndx;
20636 p = rtvec_alloc (count);
20638 ndx = 0;
20639 for (i = 0; i < 8; i++)
20640 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20642 rtvec r = rtvec_alloc (2);
20643 RTVEC_ELT (r, 0) = reg;
20644 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20645 RTVEC_ELT (p, ndx) =
20646 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20647 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20648 ndx++;
20650 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20651 gcc_assert (ndx == count);
20653 else
20654 for (i = 0; i < 8; i++)
20655 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20657 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20658 CR0_REGNO+i),
20659 reg));
20663 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20664 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20665 below stack pointer not cloberred by signals. */
20667 static inline bool
20668 offset_below_red_zone_p (HOST_WIDE_INT offset)
20670 return offset < (DEFAULT_ABI == ABI_V4
20672 : TARGET_32BIT ? -220 : -288);
20675 /* Append CFA_RESTORES to any existing REG_NOTES on the last insn. */
20677 static void
20678 emit_cfa_restores (rtx cfa_restores)
20680 rtx insn = get_last_insn ();
20681 rtx *loc = &REG_NOTES (insn);
20683 while (*loc)
20684 loc = &XEXP (*loc, 1);
20685 *loc = cfa_restores;
20686 RTX_FRAME_RELATED_P (insn) = 1;
20689 /* Emit function epilogue as insns. */
20691 void
20692 rs6000_emit_epilogue (int sibcall)
20694 rs6000_stack_t *info;
20695 int restoring_GPRs_inline;
20696 int restoring_FPRs_inline;
20697 int using_load_multiple;
20698 int using_mtcr_multiple;
20699 int use_backchain_to_restore_sp;
20700 int restore_lr;
20701 int strategy;
20702 int sp_offset = 0;
20703 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20704 rtx frame_reg_rtx = sp_reg_rtx;
20705 rtx cfa_restores = NULL_RTX;
20706 rtx insn;
20707 rtx cr_save_reg = NULL_RTX;
20708 enum machine_mode reg_mode = Pmode;
20709 int reg_size = TARGET_32BIT ? 4 : 8;
20710 int i;
20712 info = rs6000_stack_info ();
20714 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20716 reg_mode = V2SImode;
20717 reg_size = 8;
20720 strategy = info->savres_strategy;
20721 using_load_multiple = strategy & SAVRES_MULTIPLE;
20722 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20723 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20724 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20725 || rs6000_cpu == PROCESSOR_PPC603
20726 || rs6000_cpu == PROCESSOR_PPC750
20727 || optimize_size);
20728 /* Restore via the backchain when we have a large frame, since this
20729 is more efficient than an addis, addi pair. The second condition
20730 here will not trigger at the moment; We don't actually need a
20731 frame pointer for alloca, but the generic parts of the compiler
20732 give us one anyway. */
20733 use_backchain_to_restore_sp = (info->total_size > 32767 - info->lr_save_offset
20734 || (cfun->calls_alloca
20735 && !frame_pointer_needed));
20736 restore_lr = (info->lr_save_p
20737 && (restoring_FPRs_inline
20738 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20739 && (restoring_GPRs_inline
20740 || info->first_fp_reg_save < 64));
20742 if (WORLD_SAVE_P (info))
20744 int i, j;
20745 char rname[30];
20746 const char *alloc_rname;
20747 rtvec p;
20749 /* eh_rest_world_r10 will return to the location saved in the LR
20750 stack slot (which is not likely to be our caller.)
20751 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20752 rest_world is similar, except any R10 parameter is ignored.
20753 The exception-handling stuff that was here in 2.95 is no
20754 longer necessary. */
20756 p = rtvec_alloc (9
20758 + 32 - info->first_gp_reg_save
20759 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20760 + 63 + 1 - info->first_fp_reg_save);
20762 strcpy (rname, ((crtl->calls_eh_return) ?
20763 "*eh_rest_world_r10" : "*rest_world"));
20764 alloc_rname = ggc_strdup (rname);
20766 j = 0;
20767 RTVEC_ELT (p, j++) = ret_rtx;
20768 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20769 gen_rtx_REG (Pmode,
20770 LR_REGNO));
20771 RTVEC_ELT (p, j++)
20772 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20773 /* The instruction pattern requires a clobber here;
20774 it is shared with the restVEC helper. */
20775 RTVEC_ELT (p, j++)
20776 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20779 /* CR register traditionally saved as CR2. */
20780 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20781 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20782 GEN_INT (info->cr_save_offset));
20783 rtx mem = gen_frame_mem (reg_mode, addr);
20785 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20787 if (flag_shrink_wrap)
20789 cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
20790 gen_rtx_REG (Pmode, LR_REGNO),
20791 cfa_restores);
20792 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
20796 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20798 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20799 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20800 GEN_INT (info->gp_save_offset
20801 + reg_size * i));
20802 rtx mem = gen_frame_mem (reg_mode, addr);
20804 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20805 if (flag_shrink_wrap)
20806 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
20808 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20810 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20811 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20812 GEN_INT (info->altivec_save_offset
20813 + 16 * i));
20814 rtx mem = gen_frame_mem (V4SImode, addr);
20816 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20817 if (flag_shrink_wrap)
20818 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
20820 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20822 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20823 ? DFmode : SFmode),
20824 info->first_fp_reg_save + i);
20825 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20826 GEN_INT (info->fp_save_offset
20827 + 8 * i));
20828 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20829 ? DFmode : SFmode), addr);
20831 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20832 if (flag_shrink_wrap)
20833 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
20835 RTVEC_ELT (p, j++)
20836 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20837 RTVEC_ELT (p, j++)
20838 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20839 RTVEC_ELT (p, j++)
20840 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20841 RTVEC_ELT (p, j++)
20842 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20843 RTVEC_ELT (p, j++)
20844 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20845 insn = emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20847 if (flag_shrink_wrap)
20849 REG_NOTES (insn) = cfa_restores;
20850 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20851 RTX_FRAME_RELATED_P (insn) = 1;
20853 return;
20856 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20857 if (info->push_p)
20858 sp_offset = info->total_size;
20860 /* Restore AltiVec registers if we must do so before adjusting the
20861 stack. */
20862 if (TARGET_ALTIVEC_ABI
20863 && info->altivec_size != 0
20864 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20865 || (DEFAULT_ABI != ABI_V4
20866 && offset_below_red_zone_p (info->altivec_save_offset))))
20868 int i;
20870 if (use_backchain_to_restore_sp)
20872 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20873 emit_move_insn (frame_reg_rtx,
20874 gen_rtx_MEM (Pmode, sp_reg_rtx));
20875 sp_offset = 0;
20877 else if (frame_pointer_needed)
20878 frame_reg_rtx = hard_frame_pointer_rtx;
20880 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20881 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20883 rtx addr, areg, mem, reg;
20885 areg = gen_rtx_REG (Pmode, 0);
20886 emit_move_insn
20887 (areg, GEN_INT (info->altivec_save_offset
20888 + sp_offset
20889 + 16 * (i - info->first_altivec_reg_save)));
20891 /* AltiVec addressing mode is [reg+reg]. */
20892 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20893 mem = gen_frame_mem (V4SImode, addr);
20895 reg = gen_rtx_REG (V4SImode, i);
20896 emit_move_insn (reg, mem);
20897 if (flag_shrink_wrap
20898 || offset_below_red_zone_p (info->altivec_save_offset
20899 + (i - info->first_altivec_reg_save)
20900 * 16))
20901 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20902 cfa_restores);
20906 /* Restore VRSAVE if we must do so before adjusting the stack. */
20907 if (TARGET_ALTIVEC
20908 && TARGET_ALTIVEC_VRSAVE
20909 && info->vrsave_mask != 0
20910 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20911 || (DEFAULT_ABI != ABI_V4
20912 && offset_below_red_zone_p (info->vrsave_save_offset))))
20914 rtx addr, mem, reg;
20916 if (frame_reg_rtx == sp_reg_rtx)
20918 if (use_backchain_to_restore_sp)
20920 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20921 emit_move_insn (frame_reg_rtx,
20922 gen_rtx_MEM (Pmode, sp_reg_rtx));
20923 sp_offset = 0;
20925 else if (frame_pointer_needed)
20926 frame_reg_rtx = hard_frame_pointer_rtx;
20929 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20930 GEN_INT (info->vrsave_save_offset + sp_offset));
20931 mem = gen_frame_mem (SImode, addr);
20932 reg = gen_rtx_REG (SImode, 12);
20933 emit_move_insn (reg, mem);
20935 emit_insn (generate_set_vrsave (reg, info, 1));
20938 insn = NULL_RTX;
20939 /* If we have a large stack frame, restore the old stack pointer
20940 using the backchain. */
20941 if (use_backchain_to_restore_sp)
20943 if (frame_reg_rtx == sp_reg_rtx)
20945 /* Under V.4, don't reset the stack pointer until after we're done
20946 loading the saved registers. */
20947 if (DEFAULT_ABI == ABI_V4)
20948 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20950 insn = emit_move_insn (frame_reg_rtx,
20951 gen_rtx_MEM (Pmode, sp_reg_rtx));
20952 sp_offset = 0;
20954 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20955 && DEFAULT_ABI == ABI_V4)
20956 /* frame_reg_rtx has been set up by the altivec restore. */
20958 else
20960 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20961 frame_reg_rtx = sp_reg_rtx;
20964 /* If we have a frame pointer, we can restore the old stack pointer
20965 from it. */
20966 else if (frame_pointer_needed)
20968 frame_reg_rtx = sp_reg_rtx;
20969 if (DEFAULT_ABI == ABI_V4)
20970 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20971 /* Prevent reordering memory accesses against stack pointer restore. */
20972 else if (cfun->calls_alloca
20973 || offset_below_red_zone_p (-info->total_size))
20975 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20976 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20977 MEM_NOTRAP_P (mem1) = 1;
20978 MEM_NOTRAP_P (mem2) = 1;
20979 emit_insn (gen_frame_tie (mem1, mem2));
20982 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20983 GEN_INT (info->total_size)));
20984 sp_offset = 0;
20986 else if (info->push_p
20987 && DEFAULT_ABI != ABI_V4
20988 && !crtl->calls_eh_return)
20990 /* Prevent reordering memory accesses against stack pointer restore. */
20991 if (cfun->calls_alloca
20992 || offset_below_red_zone_p (-info->total_size))
20994 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20995 MEM_NOTRAP_P (mem) = 1;
20996 emit_insn (gen_stack_tie (mem));
20998 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20999 GEN_INT (info->total_size)));
21000 sp_offset = 0;
21002 if (insn && frame_reg_rtx == sp_reg_rtx)
21004 if (cfa_restores)
21006 REG_NOTES (insn) = cfa_restores;
21007 cfa_restores = NULL_RTX;
21009 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21010 RTX_FRAME_RELATED_P (insn) = 1;
21013 /* Restore AltiVec registers if we have not done so already. */
21014 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21015 && TARGET_ALTIVEC_ABI
21016 && info->altivec_size != 0
21017 && (DEFAULT_ABI == ABI_V4
21018 || !offset_below_red_zone_p (info->altivec_save_offset)))
21020 int i;
21022 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21023 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21025 rtx addr, areg, mem, reg;
21027 areg = gen_rtx_REG (Pmode, 0);
21028 emit_move_insn
21029 (areg, GEN_INT (info->altivec_save_offset
21030 + sp_offset
21031 + 16 * (i - info->first_altivec_reg_save)));
21033 /* AltiVec addressing mode is [reg+reg]. */
21034 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21035 mem = gen_frame_mem (V4SImode, addr);
21037 reg = gen_rtx_REG (V4SImode, i);
21038 emit_move_insn (reg, mem);
21039 if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21040 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21041 cfa_restores);
21045 /* Restore VRSAVE if we have not done so already. */
21046 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21047 && TARGET_ALTIVEC
21048 && TARGET_ALTIVEC_VRSAVE
21049 && info->vrsave_mask != 0
21050 && (DEFAULT_ABI == ABI_V4
21051 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21053 rtx addr, mem, reg;
21055 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21056 GEN_INT (info->vrsave_save_offset + sp_offset));
21057 mem = gen_frame_mem (SImode, addr);
21058 reg = gen_rtx_REG (SImode, 12);
21059 emit_move_insn (reg, mem);
21061 emit_insn (generate_set_vrsave (reg, info, 1));
21064 /* Get the old lr if we saved it. If we are restoring registers
21065 out-of-line, then the out-of-line routines can do this for us. */
21066 if (restore_lr && restoring_GPRs_inline)
21068 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21069 info->lr_save_offset + sp_offset);
21071 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21074 /* Get the old cr if we saved it. */
21075 if (info->cr_save_p)
21077 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21078 GEN_INT (info->cr_save_offset + sp_offset));
21079 rtx mem = gen_frame_mem (SImode, addr);
21081 cr_save_reg = gen_rtx_REG (SImode,
21082 DEFAULT_ABI == ABI_AIX
21083 && !restoring_GPRs_inline
21084 && info->first_fp_reg_save < 64
21085 ? 11 : 12);
21086 emit_move_insn (cr_save_reg, mem);
21089 /* Set LR here to try to overlap restores below. */
21090 if (restore_lr && restoring_GPRs_inline)
21091 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21092 gen_rtx_REG (Pmode, 0));
21094 /* Load exception handler data registers, if needed. */
21095 if (crtl->calls_eh_return)
21097 unsigned int i, regno;
21099 if (TARGET_AIX)
21101 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21102 GEN_INT (sp_offset + 5 * reg_size));
21103 rtx mem = gen_frame_mem (reg_mode, addr);
21105 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21108 for (i = 0; ; ++i)
21110 rtx mem;
21112 regno = EH_RETURN_DATA_REGNO (i);
21113 if (regno == INVALID_REGNUM)
21114 break;
21116 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21117 info->ehrd_offset + sp_offset
21118 + reg_size * (int) i);
21120 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21124 /* Restore GPRs. This is done as a PARALLEL if we are using
21125 the load-multiple instructions. */
21126 if (TARGET_SPE_ABI
21127 && info->spe_64bit_regs_used
21128 && info->first_gp_reg_save != 32)
21130 /* Determine whether we can address all of the registers that need
21131 to be saved with an offset from the stack pointer that fits in
21132 the small const field for SPE memory instructions. */
21133 int spe_regs_addressable_via_sp
21134 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21135 + (32 - info->first_gp_reg_save - 1) * reg_size)
21136 && restoring_GPRs_inline);
21137 int spe_offset;
21139 if (spe_regs_addressable_via_sp)
21140 spe_offset = info->spe_gp_save_offset + sp_offset;
21141 else
21143 rtx old_frame_reg_rtx = frame_reg_rtx;
21144 /* Make r11 point to the start of the SPE save area. We worried about
21145 not clobbering it when we were saving registers in the prologue.
21146 There's no need to worry here because the static chain is passed
21147 anew to every function. */
21148 int ool_adjust = (restoring_GPRs_inline
21150 : (info->first_gp_reg_save
21151 - (FIRST_SAVRES_REGISTER + 1)) * 8);
21153 if (frame_reg_rtx == sp_reg_rtx)
21154 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21155 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21156 GEN_INT (info->spe_gp_save_offset
21157 + sp_offset
21158 - ool_adjust)));
21159 /* Keep the invariant that frame_reg_rtx + sp_offset points
21160 at the top of the stack frame. */
21161 sp_offset = -info->spe_gp_save_offset;
21163 spe_offset = 0;
21166 if (restoring_GPRs_inline)
21168 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21169 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21171 rtx offset, addr, mem, reg;
21173 /* We're doing all this to ensure that the immediate offset
21174 fits into the immediate field of 'evldd'. */
21175 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21177 offset = GEN_INT (spe_offset + reg_size * i);
21178 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21179 mem = gen_rtx_MEM (V2SImode, addr);
21180 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21182 emit_move_insn (reg, mem);
21185 else
21186 rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21187 0, reg_mode,
21188 /*savep=*/false, /*gpr=*/true,
21189 /*lr=*/true);
21191 else if (!restoring_GPRs_inline)
21193 /* We are jumping to an out-of-line function. */
21194 bool can_use_exit = info->first_fp_reg_save == 64;
21196 /* Emit stack reset code if we need it. */
21197 if (can_use_exit)
21199 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21200 sp_offset, can_use_exit);
21201 if (DEFAULT_ABI == ABI_DARWIN)
21202 /* we only need a copy, no fprs were saved. */
21203 emit_move_insn (gen_rtx_REG (reg_mode, 11), frame_reg_rtx);
21205 if (info->cr_save_p)
21206 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21208 else
21210 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21211 ? 12 : 11),
21212 frame_reg_rtx,
21213 GEN_INT (sp_offset - info->fp_size)));
21214 if (REGNO (frame_reg_rtx) == 11)
21215 sp_offset += info->fp_size;
21218 rs6000_emit_savres_rtx (info, frame_reg_rtx,
21219 info->gp_save_offset, reg_mode,
21220 /*savep=*/false, /*gpr=*/true,
21221 /*lr=*/can_use_exit);
21223 else if (using_load_multiple)
21225 rtvec p;
21226 p = rtvec_alloc (32 - info->first_gp_reg_save);
21227 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21229 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21230 GEN_INT (info->gp_save_offset
21231 + sp_offset
21232 + reg_size * i));
21233 rtx mem = gen_frame_mem (reg_mode, addr);
21234 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21236 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21238 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21240 else
21242 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21243 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21245 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21246 GEN_INT (info->gp_save_offset
21247 + sp_offset
21248 + reg_size * i));
21249 rtx mem = gen_frame_mem (reg_mode, addr);
21250 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21252 emit_move_insn (reg, mem);
21256 if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21258 /* If the frame pointer was used then we can't delay emitting
21259 a REG_CFA_DEF_CFA note. This must happen on the insn that
21260 restores the frame pointer, r31. We may have already emitted
21261 a REG_CFA_DEF_CFA note, but that's OK; A duplicate is
21262 discarded by dwarf2cfi.c/dwarf2out.c, and in any case would
21263 be harmless if emitted. */
21264 if (frame_pointer_needed)
21266 insn = get_last_insn ();
21267 add_reg_note (insn, REG_CFA_DEF_CFA,
21268 plus_constant (frame_reg_rtx, sp_offset));
21269 RTX_FRAME_RELATED_P (insn) = 1;
21272 /* Set up cfa_restores. We always need these when
21273 shrink-wrapping. If not shrink-wrapping then we only need
21274 the cfa_restore when the stack location is no longer valid.
21275 The cfa_restores must be emitted on or before the insn that
21276 invalidates the stack, and of course must not be emitted
21277 before the insn that actually does the restore. The latter
21278 is why the LR cfa_restore condition below is a little
21279 complicated. It's also why it is a bad idea to emit the
21280 cfa_restores as a group on the last instruction here that
21281 actually does a restore: That insn may be reordered with
21282 respect to others doing restores. */
21283 if (info->cr_save_p)
21284 cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
21285 gen_rtx_REG (SImode, CR2_REGNO),
21286 cfa_restores);
21287 if (flag_shrink_wrap
21288 && (restore_lr
21289 || (info->lr_save_p
21290 && !restoring_GPRs_inline
21291 && info->first_fp_reg_save == 64)))
21292 cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
21293 gen_rtx_REG (Pmode, LR_REGNO),
21294 cfa_restores);
21296 for (i = info->first_gp_reg_save; i < 32; i++)
21297 if (!restoring_GPRs_inline
21298 || using_load_multiple
21299 || rs6000_reg_live_or_pic_offset_p (i))
21301 rtx reg = gen_rtx_REG (reg_mode, i);
21303 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
21307 if (!restoring_GPRs_inline
21308 && info->first_fp_reg_save == 64)
21310 /* We are jumping to an out-of-line function. */
21311 if (cfa_restores)
21312 emit_cfa_restores (cfa_restores);
21313 return;
21316 if (restore_lr && !restoring_GPRs_inline)
21318 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21319 info->lr_save_offset + sp_offset);
21321 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21322 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21323 gen_rtx_REG (Pmode, 0));
21326 /* Restore fpr's if we need to do it without calling a function. */
21327 if (restoring_FPRs_inline)
21328 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21329 if ((df_regs_ever_live_p (info->first_fp_reg_save + i)
21330 && !call_used_regs[info->first_fp_reg_save + i]))
21332 rtx addr, mem, reg;
21333 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21334 GEN_INT (info->fp_save_offset
21335 + sp_offset
21336 + 8 * i));
21337 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21338 ? DFmode : SFmode), addr);
21339 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21340 ? DFmode : SFmode),
21341 info->first_fp_reg_save + i);
21343 emit_move_insn (reg, mem);
21344 if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21345 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
21348 /* If we saved cr, restore it here. Just those that were used. */
21349 if (info->cr_save_p)
21350 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21352 /* If this is V.4, unwind the stack pointer after all of the loads
21353 have been done. */
21354 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21355 sp_offset, !restoring_FPRs_inline);
21356 if (insn)
21358 if (cfa_restores)
21360 REG_NOTES (insn) = cfa_restores;
21361 cfa_restores = NULL_RTX;
21363 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21364 RTX_FRAME_RELATED_P (insn) = 1;
21367 if (crtl->calls_eh_return)
21369 rtx sa = EH_RETURN_STACKADJ_RTX;
21370 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21373 if (!sibcall)
21375 rtvec p;
21376 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21377 if (! restoring_FPRs_inline)
21379 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21380 RTVEC_ELT (p, 0) = ret_rtx;
21382 else
21384 if (cfa_restores)
21386 /* We can't hang the cfa_restores off a simple return,
21387 since the shrink-wrap code sometimes uses an existing
21388 return. This means there might be a path from
21389 pre-prologue code to this return, and dwarf2cfi code
21390 wants the eh_frame unwinder state to be the same on
21391 all paths to any point. So we need to emit the
21392 cfa_restores before the return. For -m64 we really
21393 don't need epilogue cfa_restores at all, except for
21394 this irritating dwarf2cfi with shrink-wrap
21395 requirement; The stack red-zone means eh_frame info
21396 from the prologue telling the unwinder to restore
21397 from the stack is perfectly good right to the end of
21398 the function. */
21399 emit_insn (gen_blockage ());
21400 emit_cfa_restores (cfa_restores);
21401 cfa_restores = NULL_RTX;
21403 p = rtvec_alloc (2);
21404 RTVEC_ELT (p, 0) = simple_return_rtx;
21407 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21408 ? gen_rtx_USE (VOIDmode,
21409 gen_rtx_REG (Pmode, LR_REGNO))
21410 : gen_rtx_CLOBBER (VOIDmode,
21411 gen_rtx_REG (Pmode, LR_REGNO)));
21413 /* If we have to restore more than two FP registers, branch to the
21414 restore function. It will return to our caller. */
21415 if (! restoring_FPRs_inline)
21417 int i;
21418 rtx sym;
21420 if ((DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21421 && lr)
21422 cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
21423 gen_rtx_REG (Pmode, LR_REGNO),
21424 cfa_restores);
21426 sym = rs6000_savres_routine_sym (info,
21427 /*savep=*/false,
21428 /*gpr=*/false,
21429 /*lr=*/lr);
21430 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21431 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21432 gen_rtx_REG (Pmode,
21433 DEFAULT_ABI == ABI_AIX
21434 ? 1 : 11));
21435 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21437 rtx addr, mem, reg;
21439 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21440 GEN_INT (info->fp_save_offset + 8 * i));
21441 mem = gen_frame_mem (DFmode, addr);
21442 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
21444 RTVEC_ELT (p, i + 4) = gen_rtx_SET (VOIDmode, reg, mem);
21445 if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)
21446 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21447 cfa_restores);
21451 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21454 if (cfa_restores)
21456 if (sibcall)
21457 /* Ensure the cfa_restores are hung off an insn that won't
21458 be reordered above other restores. */
21459 emit_insn (gen_blockage ());
21461 emit_cfa_restores (cfa_restores);
21465 /* Write function epilogue. */
21467 static void
21468 rs6000_output_function_epilogue (FILE *file,
21469 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21471 #if TARGET_MACHO
21472 macho_branch_islands ();
21473 /* Mach-O doesn't support labels at the end of objects, so if
21474 it looks like we might want one, insert a NOP. */
21476 rtx insn = get_last_insn ();
21477 rtx deleted_debug_label = NULL_RTX;
21478 while (insn
21479 && NOTE_P (insn)
21480 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21482 /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
21483 notes only, instead set their CODE_LABEL_NUMBER to -1,
21484 otherwise there would be code generation differences
21485 in between -g and -g0. */
21486 if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
21487 deleted_debug_label = insn;
21488 insn = PREV_INSN (insn);
21490 if (insn
21491 && (LABEL_P (insn)
21492 || (NOTE_P (insn)
21493 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21494 fputs ("\tnop\n", file);
21495 else if (deleted_debug_label)
21496 for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
21497 if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
21498 CODE_LABEL_NUMBER (insn) = -1;
21500 #endif
21502 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21503 on its format.
21505 We don't output a traceback table if -finhibit-size-directive was
21506 used. The documentation for -finhibit-size-directive reads
21507 ``don't output a @code{.size} assembler directive, or anything
21508 else that would cause trouble if the function is split in the
21509 middle, and the two halves are placed at locations far apart in
21510 memory.'' The traceback table has this property, since it
21511 includes the offset from the start of the function to the
21512 traceback table itself.
21514 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21515 different traceback table. */
21516 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21517 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21519 const char *fname = NULL;
21520 const char *language_string = lang_hooks.name;
21521 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21522 int i;
21523 int optional_tbtab;
21524 rs6000_stack_t *info = rs6000_stack_info ();
21526 if (rs6000_traceback == traceback_full)
21527 optional_tbtab = 1;
21528 else if (rs6000_traceback == traceback_part)
21529 optional_tbtab = 0;
21530 else
21531 optional_tbtab = !optimize_size && !TARGET_ELF;
21533 if (optional_tbtab)
21535 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21536 while (*fname == '.') /* V.4 encodes . in the name */
21537 fname++;
21539 /* Need label immediately before tbtab, so we can compute
21540 its offset from the function start. */
21541 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21542 ASM_OUTPUT_LABEL (file, fname);
21545 /* The .tbtab pseudo-op can only be used for the first eight
21546 expressions, since it can't handle the possibly variable
21547 length fields that follow. However, if you omit the optional
21548 fields, the assembler outputs zeros for all optional fields
21549 anyways, giving each variable length field is minimum length
21550 (as defined in sys/debug.h). Thus we can not use the .tbtab
21551 pseudo-op at all. */
21553 /* An all-zero word flags the start of the tbtab, for debuggers
21554 that have to find it by searching forward from the entry
21555 point or from the current pc. */
21556 fputs ("\t.long 0\n", file);
21558 /* Tbtab format type. Use format type 0. */
21559 fputs ("\t.byte 0,", file);
21561 /* Language type. Unfortunately, there does not seem to be any
21562 official way to discover the language being compiled, so we
21563 use language_string.
21564 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21565 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21566 a number, so for now use 9. LTO and Go aren't assigned numbers
21567 either, so for now use 0. */
21568 if (! strcmp (language_string, "GNU C")
21569 || ! strcmp (language_string, "GNU GIMPLE")
21570 || ! strcmp (language_string, "GNU Go"))
21571 i = 0;
21572 else if (! strcmp (language_string, "GNU F77")
21573 || ! strcmp (language_string, "GNU Fortran"))
21574 i = 1;
21575 else if (! strcmp (language_string, "GNU Pascal"))
21576 i = 2;
21577 else if (! strcmp (language_string, "GNU Ada"))
21578 i = 3;
21579 else if (! strcmp (language_string, "GNU C++")
21580 || ! strcmp (language_string, "GNU Objective-C++"))
21581 i = 9;
21582 else if (! strcmp (language_string, "GNU Java"))
21583 i = 13;
21584 else if (! strcmp (language_string, "GNU Objective-C"))
21585 i = 14;
21586 else
21587 gcc_unreachable ();
21588 fprintf (file, "%d,", i);
21590 /* 8 single bit fields: global linkage (not set for C extern linkage,
21591 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21592 from start of procedure stored in tbtab, internal function, function
21593 has controlled storage, function has no toc, function uses fp,
21594 function logs/aborts fp operations. */
21595 /* Assume that fp operations are used if any fp reg must be saved. */
21596 fprintf (file, "%d,",
21597 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21599 /* 6 bitfields: function is interrupt handler, name present in
21600 proc table, function calls alloca, on condition directives
21601 (controls stack walks, 3 bits), saves condition reg, saves
21602 link reg. */
21603 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21604 set up as a frame pointer, even when there is no alloca call. */
21605 fprintf (file, "%d,",
21606 ((optional_tbtab << 6)
21607 | ((optional_tbtab & frame_pointer_needed) << 5)
21608 | (info->cr_save_p << 1)
21609 | (info->lr_save_p)));
21611 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21612 (6 bits). */
21613 fprintf (file, "%d,",
21614 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21616 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21617 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21619 if (optional_tbtab)
21621 /* Compute the parameter info from the function decl argument
21622 list. */
21623 tree decl;
21624 int next_parm_info_bit = 31;
21626 for (decl = DECL_ARGUMENTS (current_function_decl);
21627 decl; decl = DECL_CHAIN (decl))
21629 rtx parameter = DECL_INCOMING_RTL (decl);
21630 enum machine_mode mode = GET_MODE (parameter);
21632 if (GET_CODE (parameter) == REG)
21634 if (SCALAR_FLOAT_MODE_P (mode))
21636 int bits;
21638 float_parms++;
21640 switch (mode)
21642 case SFmode:
21643 case SDmode:
21644 bits = 0x2;
21645 break;
21647 case DFmode:
21648 case DDmode:
21649 case TFmode:
21650 case TDmode:
21651 bits = 0x3;
21652 break;
21654 default:
21655 gcc_unreachable ();
21658 /* If only one bit will fit, don't or in this entry. */
21659 if (next_parm_info_bit > 0)
21660 parm_info |= (bits << (next_parm_info_bit - 1));
21661 next_parm_info_bit -= 2;
21663 else
21665 fixed_parms += ((GET_MODE_SIZE (mode)
21666 + (UNITS_PER_WORD - 1))
21667 / UNITS_PER_WORD);
21668 next_parm_info_bit -= 1;
21674 /* Number of fixed point parameters. */
21675 /* This is actually the number of words of fixed point parameters; thus
21676 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21677 fprintf (file, "%d,", fixed_parms);
21679 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21680 all on stack. */
21681 /* This is actually the number of fp registers that hold parameters;
21682 and thus the maximum value is 13. */
21683 /* Set parameters on stack bit if parameters are not in their original
21684 registers, regardless of whether they are on the stack? Xlc
21685 seems to set the bit when not optimizing. */
21686 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21688 if (! optional_tbtab)
21689 return;
21691 /* Optional fields follow. Some are variable length. */
21693 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21694 11 double float. */
21695 /* There is an entry for each parameter in a register, in the order that
21696 they occur in the parameter list. Any intervening arguments on the
21697 stack are ignored. If the list overflows a long (max possible length
21698 34 bits) then completely leave off all elements that don't fit. */
21699 /* Only emit this long if there was at least one parameter. */
21700 if (fixed_parms || float_parms)
21701 fprintf (file, "\t.long %d\n", parm_info);
21703 /* Offset from start of code to tb table. */
21704 fputs ("\t.long ", file);
21705 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21706 RS6000_OUTPUT_BASENAME (file, fname);
21707 putc ('-', file);
21708 rs6000_output_function_entry (file, fname);
21709 putc ('\n', file);
21711 /* Interrupt handler mask. */
21712 /* Omit this long, since we never set the interrupt handler bit
21713 above. */
21715 /* Number of CTL (controlled storage) anchors. */
21716 /* Omit this long, since the has_ctl bit is never set above. */
21718 /* Displacement into stack of each CTL anchor. */
21719 /* Omit this list of longs, because there are no CTL anchors. */
21721 /* Length of function name. */
21722 if (*fname == '*')
21723 ++fname;
21724 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21726 /* Function name. */
21727 assemble_string (fname, strlen (fname));
21729 /* Register for alloca automatic storage; this is always reg 31.
21730 Only emit this if the alloca bit was set above. */
21731 if (frame_pointer_needed)
21732 fputs ("\t.byte 31\n", file);
21734 fputs ("\t.align 2\n", file);
21738 /* A C compound statement that outputs the assembler code for a thunk
21739 function, used to implement C++ virtual function calls with
21740 multiple inheritance. The thunk acts as a wrapper around a virtual
21741 function, adjusting the implicit object parameter before handing
21742 control off to the real function.
21744 First, emit code to add the integer DELTA to the location that
21745 contains the incoming first argument. Assume that this argument
21746 contains a pointer, and is the one used to pass the `this' pointer
21747 in C++. This is the incoming argument *before* the function
21748 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21749 values of all other incoming arguments.
21751 After the addition, emit code to jump to FUNCTION, which is a
21752 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21753 not touch the return address. Hence returning from FUNCTION will
21754 return to whoever called the current `thunk'.
21756 The effect must be as if FUNCTION had been called directly with the
21757 adjusted first argument. This macro is responsible for emitting
21758 all of the code for a thunk function; output_function_prologue()
21759 and output_function_epilogue() are not invoked.
21761 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21762 been extracted from it.) It might possibly be useful on some
21763 targets, but probably not.
21765 If you do not define this macro, the target-independent code in the
21766 C++ frontend will generate a less efficient heavyweight thunk that
21767 calls FUNCTION instead of jumping to it. The generic approach does
21768 not support varargs. */
21770 static void
21771 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21772 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21773 tree function)
21775 rtx this_rtx, insn, funexp;
21777 reload_completed = 1;
21778 epilogue_completed = 1;
21780 /* Mark the end of the (empty) prologue. */
21781 emit_note (NOTE_INSN_PROLOGUE_END);
21783 /* Find the "this" pointer. If the function returns a structure,
21784 the structure return pointer is in r3. */
21785 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21786 this_rtx = gen_rtx_REG (Pmode, 4);
21787 else
21788 this_rtx = gen_rtx_REG (Pmode, 3);
21790 /* Apply the constant offset, if required. */
21791 if (delta)
21792 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21794 /* Apply the offset from the vtable, if required. */
21795 if (vcall_offset)
21797 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21798 rtx tmp = gen_rtx_REG (Pmode, 12);
21800 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21801 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21803 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21804 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21806 else
21808 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21810 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21812 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21815 /* Generate a tail call to the target function. */
21816 if (!TREE_USED (function))
21818 assemble_external (function);
21819 TREE_USED (function) = 1;
21821 funexp = XEXP (DECL_RTL (function), 0);
21822 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21824 #if TARGET_MACHO
21825 if (MACHOPIC_INDIRECT)
21826 funexp = machopic_indirect_call_target (funexp);
21827 #endif
21829 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21830 generate sibcall RTL explicitly. */
21831 insn = emit_call_insn (
21832 gen_rtx_PARALLEL (VOIDmode,
21833 gen_rtvec (4,
21834 gen_rtx_CALL (VOIDmode,
21835 funexp, const0_rtx),
21836 gen_rtx_USE (VOIDmode, const0_rtx),
21837 gen_rtx_USE (VOIDmode,
21838 gen_rtx_REG (SImode,
21839 LR_REGNO)),
21840 simple_return_rtx)));
21841 SIBLING_CALL_P (insn) = 1;
21842 emit_barrier ();
21844 /* Run just enough of rest_of_compilation to get the insns emitted.
21845 There's not really enough bulk here to make other passes such as
21846 instruction scheduling worth while. Note that use_thunk calls
21847 assemble_start_function and assemble_end_function. */
21848 insn = get_insns ();
21849 insn_locators_alloc ();
21850 shorten_branches (insn);
21851 final_start_function (insn, file, 1);
21852 final (insn, file, 1);
21853 final_end_function ();
21855 reload_completed = 0;
21856 epilogue_completed = 0;
21859 /* A quick summary of the various types of 'constant-pool tables'
21860 under PowerPC:
21862 Target Flags Name One table per
21863 AIX (none) AIX TOC object file
21864 AIX -mfull-toc AIX TOC object file
21865 AIX -mminimal-toc AIX minimal TOC translation unit
21866 SVR4/EABI (none) SVR4 SDATA object file
21867 SVR4/EABI -fpic SVR4 pic object file
21868 SVR4/EABI -fPIC SVR4 PIC translation unit
21869 SVR4/EABI -mrelocatable EABI TOC function
21870 SVR4/EABI -maix AIX TOC object file
21871 SVR4/EABI -maix -mminimal-toc
21872 AIX minimal TOC translation unit
21874 Name Reg. Set by entries contains:
21875 made by addrs? fp? sum?
21877 AIX TOC 2 crt0 as Y option option
21878 AIX minimal TOC 30 prolog gcc Y Y option
21879 SVR4 SDATA 13 crt0 gcc N Y N
21880 SVR4 pic 30 prolog ld Y not yet N
21881 SVR4 PIC 30 prolog gcc Y option option
21882 EABI TOC 30 prolog gcc Y option option
21886 /* Hash functions for the hash table. */
21888 static unsigned
21889 rs6000_hash_constant (rtx k)
21891 enum rtx_code code = GET_CODE (k);
21892 enum machine_mode mode = GET_MODE (k);
21893 unsigned result = (code << 3) ^ mode;
21894 const char *format;
21895 int flen, fidx;
21897 format = GET_RTX_FORMAT (code);
21898 flen = strlen (format);
21899 fidx = 0;
21901 switch (code)
21903 case LABEL_REF:
21904 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21906 case CONST_DOUBLE:
21907 if (mode != VOIDmode)
21908 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21909 flen = 2;
21910 break;
21912 case CODE_LABEL:
21913 fidx = 3;
21914 break;
21916 default:
21917 break;
21920 for (; fidx < flen; fidx++)
21921 switch (format[fidx])
21923 case 's':
21925 unsigned i, len;
21926 const char *str = XSTR (k, fidx);
21927 len = strlen (str);
21928 result = result * 613 + len;
21929 for (i = 0; i < len; i++)
21930 result = result * 613 + (unsigned) str[i];
21931 break;
21933 case 'u':
21934 case 'e':
21935 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21936 break;
21937 case 'i':
21938 case 'n':
21939 result = result * 613 + (unsigned) XINT (k, fidx);
21940 break;
21941 case 'w':
21942 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21943 result = result * 613 + (unsigned) XWINT (k, fidx);
21944 else
21946 size_t i;
21947 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21948 result = result * 613 + (unsigned) (XWINT (k, fidx)
21949 >> CHAR_BIT * i);
21951 break;
21952 case '0':
21953 break;
21954 default:
21955 gcc_unreachable ();
21958 return result;
21961 static unsigned
21962 toc_hash_function (const void *hash_entry)
21964 const struct toc_hash_struct *thc =
21965 (const struct toc_hash_struct *) hash_entry;
21966 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21969 /* Compare H1 and H2 for equivalence. */
21971 static int
21972 toc_hash_eq (const void *h1, const void *h2)
21974 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21975 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21977 if (((const struct toc_hash_struct *) h1)->key_mode
21978 != ((const struct toc_hash_struct *) h2)->key_mode)
21979 return 0;
21981 return rtx_equal_p (r1, r2);
21984 /* These are the names given by the C++ front-end to vtables, and
21985 vtable-like objects. Ideally, this logic should not be here;
21986 instead, there should be some programmatic way of inquiring as
21987 to whether or not an object is a vtable. */
21989 #define VTABLE_NAME_P(NAME) \
21990 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21991 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21992 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21993 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21994 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21996 #ifdef NO_DOLLAR_IN_LABEL
21997 /* Return a GGC-allocated character string translating dollar signs in
21998 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22000 const char *
22001 rs6000_xcoff_strip_dollar (const char *name)
22003 char *strip, *p;
22004 const char *q;
22005 size_t len;
22007 q = (const char *) strchr (name, '$');
22009 if (q == 0 || q == name)
22010 return name;
22012 len = strlen (name);
22013 strip = XALLOCAVEC (char, len + 1);
22014 strcpy (strip, name);
22015 p = strip + (q - name);
22016 while (p)
22018 *p = '_';
22019 p = strchr (p + 1, '$');
22022 return ggc_alloc_string (strip, len);
22024 #endif
22026 void
22027 rs6000_output_symbol_ref (FILE *file, rtx x)
22029 /* Currently C++ toc references to vtables can be emitted before it
22030 is decided whether the vtable is public or private. If this is
22031 the case, then the linker will eventually complain that there is
22032 a reference to an unknown section. Thus, for vtables only,
22033 we emit the TOC reference to reference the symbol and not the
22034 section. */
22035 const char *name = XSTR (x, 0);
22037 if (VTABLE_NAME_P (name))
22039 RS6000_OUTPUT_BASENAME (file, name);
22041 else
22042 assemble_name (file, name);
22045 /* Output a TOC entry. We derive the entry name from what is being
22046 written. */
22048 void
22049 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22051 char buf[256];
22052 const char *name = buf;
22053 rtx base = x;
22054 HOST_WIDE_INT offset = 0;
22056 gcc_assert (!TARGET_NO_TOC);
22058 /* When the linker won't eliminate them, don't output duplicate
22059 TOC entries (this happens on AIX if there is any kind of TOC,
22060 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22061 CODE_LABELs. */
22062 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22064 struct toc_hash_struct *h;
22065 void * * found;
22067 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22068 time because GGC is not initialized at that point. */
22069 if (toc_hash_table == NULL)
22070 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22071 toc_hash_eq, NULL);
22073 h = ggc_alloc_toc_hash_struct ();
22074 h->key = x;
22075 h->key_mode = mode;
22076 h->labelno = labelno;
22078 found = htab_find_slot (toc_hash_table, h, INSERT);
22079 if (*found == NULL)
22080 *found = h;
22081 else /* This is indeed a duplicate.
22082 Set this label equal to that label. */
22084 fputs ("\t.set ", file);
22085 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22086 fprintf (file, "%d,", labelno);
22087 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22088 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22089 found)->labelno));
22090 return;
22094 /* If we're going to put a double constant in the TOC, make sure it's
22095 aligned properly when strict alignment is on. */
22096 if (GET_CODE (x) == CONST_DOUBLE
22097 && STRICT_ALIGNMENT
22098 && GET_MODE_BITSIZE (mode) >= 64
22099 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22100 ASM_OUTPUT_ALIGN (file, 3);
22103 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22105 /* Handle FP constants specially. Note that if we have a minimal
22106 TOC, things we put here aren't actually in the TOC, so we can allow
22107 FP constants. */
22108 if (GET_CODE (x) == CONST_DOUBLE &&
22109 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22111 REAL_VALUE_TYPE rv;
22112 long k[4];
22114 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22115 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22116 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22117 else
22118 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22120 if (TARGET_64BIT)
22122 if (TARGET_MINIMAL_TOC)
22123 fputs (DOUBLE_INT_ASM_OP, file);
22124 else
22125 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22126 k[0] & 0xffffffff, k[1] & 0xffffffff,
22127 k[2] & 0xffffffff, k[3] & 0xffffffff);
22128 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22129 k[0] & 0xffffffff, k[1] & 0xffffffff,
22130 k[2] & 0xffffffff, k[3] & 0xffffffff);
22131 return;
22133 else
22135 if (TARGET_MINIMAL_TOC)
22136 fputs ("\t.long ", file);
22137 else
22138 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22139 k[0] & 0xffffffff, k[1] & 0xffffffff,
22140 k[2] & 0xffffffff, k[3] & 0xffffffff);
22141 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22142 k[0] & 0xffffffff, k[1] & 0xffffffff,
22143 k[2] & 0xffffffff, k[3] & 0xffffffff);
22144 return;
22147 else if (GET_CODE (x) == CONST_DOUBLE &&
22148 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22150 REAL_VALUE_TYPE rv;
22151 long k[2];
22153 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22155 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22156 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22157 else
22158 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22160 if (TARGET_64BIT)
22162 if (TARGET_MINIMAL_TOC)
22163 fputs (DOUBLE_INT_ASM_OP, file);
22164 else
22165 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22166 k[0] & 0xffffffff, k[1] & 0xffffffff);
22167 fprintf (file, "0x%lx%08lx\n",
22168 k[0] & 0xffffffff, k[1] & 0xffffffff);
22169 return;
22171 else
22173 if (TARGET_MINIMAL_TOC)
22174 fputs ("\t.long ", file);
22175 else
22176 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22177 k[0] & 0xffffffff, k[1] & 0xffffffff);
22178 fprintf (file, "0x%lx,0x%lx\n",
22179 k[0] & 0xffffffff, k[1] & 0xffffffff);
22180 return;
22183 else if (GET_CODE (x) == CONST_DOUBLE &&
22184 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22186 REAL_VALUE_TYPE rv;
22187 long l;
22189 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22190 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22191 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22192 else
22193 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22195 if (TARGET_64BIT)
22197 if (TARGET_MINIMAL_TOC)
22198 fputs (DOUBLE_INT_ASM_OP, file);
22199 else
22200 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22201 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22202 return;
22204 else
22206 if (TARGET_MINIMAL_TOC)
22207 fputs ("\t.long ", file);
22208 else
22209 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22210 fprintf (file, "0x%lx\n", l & 0xffffffff);
22211 return;
22214 else if (GET_MODE (x) == VOIDmode
22215 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22217 unsigned HOST_WIDE_INT low;
22218 HOST_WIDE_INT high;
22220 if (GET_CODE (x) == CONST_DOUBLE)
22222 low = CONST_DOUBLE_LOW (x);
22223 high = CONST_DOUBLE_HIGH (x);
22225 else
22226 #if HOST_BITS_PER_WIDE_INT == 32
22228 low = INTVAL (x);
22229 high = (low & 0x80000000) ? ~0 : 0;
22231 #else
22233 low = INTVAL (x) & 0xffffffff;
22234 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22236 #endif
22238 /* TOC entries are always Pmode-sized, but since this
22239 is a bigendian machine then if we're putting smaller
22240 integer constants in the TOC we have to pad them.
22241 (This is still a win over putting the constants in
22242 a separate constant pool, because then we'd have
22243 to have both a TOC entry _and_ the actual constant.)
22245 For a 32-bit target, CONST_INT values are loaded and shifted
22246 entirely within `low' and can be stored in one TOC entry. */
22248 /* It would be easy to make this work, but it doesn't now. */
22249 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22251 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22253 #if HOST_BITS_PER_WIDE_INT == 32
22254 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22255 POINTER_SIZE, &low, &high, 0);
22256 #else
22257 low |= high << 32;
22258 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22259 high = (HOST_WIDE_INT) low >> 32;
22260 low &= 0xffffffff;
22261 #endif
22264 if (TARGET_64BIT)
22266 if (TARGET_MINIMAL_TOC)
22267 fputs (DOUBLE_INT_ASM_OP, file);
22268 else
22269 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22270 (long) high & 0xffffffff, (long) low & 0xffffffff);
22271 fprintf (file, "0x%lx%08lx\n",
22272 (long) high & 0xffffffff, (long) low & 0xffffffff);
22273 return;
22275 else
22277 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22279 if (TARGET_MINIMAL_TOC)
22280 fputs ("\t.long ", file);
22281 else
22282 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22283 (long) high & 0xffffffff, (long) low & 0xffffffff);
22284 fprintf (file, "0x%lx,0x%lx\n",
22285 (long) high & 0xffffffff, (long) low & 0xffffffff);
22287 else
22289 if (TARGET_MINIMAL_TOC)
22290 fputs ("\t.long ", file);
22291 else
22292 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22293 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22295 return;
22299 if (GET_CODE (x) == CONST)
22301 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22302 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22304 base = XEXP (XEXP (x, 0), 0);
22305 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22308 switch (GET_CODE (base))
22310 case SYMBOL_REF:
22311 name = XSTR (base, 0);
22312 break;
22314 case LABEL_REF:
22315 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22316 CODE_LABEL_NUMBER (XEXP (base, 0)));
22317 break;
22319 case CODE_LABEL:
22320 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22321 break;
22323 default:
22324 gcc_unreachable ();
22327 if (TARGET_MINIMAL_TOC)
22328 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22329 else
22331 fputs ("\t.tc ", file);
22332 RS6000_OUTPUT_BASENAME (file, name);
22334 if (offset < 0)
22335 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22336 else if (offset)
22337 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22339 fputs ("[TC],", file);
22342 /* Currently C++ toc references to vtables can be emitted before it
22343 is decided whether the vtable is public or private. If this is
22344 the case, then the linker will eventually complain that there is
22345 a TOC reference to an unknown section. Thus, for vtables only,
22346 we emit the TOC reference to reference the symbol and not the
22347 section. */
22348 if (VTABLE_NAME_P (name))
22350 RS6000_OUTPUT_BASENAME (file, name);
22351 if (offset < 0)
22352 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22353 else if (offset > 0)
22354 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22356 else
22357 output_addr_const (file, x);
22358 putc ('\n', file);
22361 /* Output an assembler pseudo-op to write an ASCII string of N characters
22362 starting at P to FILE.
22364 On the RS/6000, we have to do this using the .byte operation and
22365 write out special characters outside the quoted string.
22366 Also, the assembler is broken; very long strings are truncated,
22367 so we must artificially break them up early. */
22369 void
22370 output_ascii (FILE *file, const char *p, int n)
22372 char c;
22373 int i, count_string;
22374 const char *for_string = "\t.byte \"";
22375 const char *for_decimal = "\t.byte ";
22376 const char *to_close = NULL;
22378 count_string = 0;
22379 for (i = 0; i < n; i++)
22381 c = *p++;
22382 if (c >= ' ' && c < 0177)
22384 if (for_string)
22385 fputs (for_string, file);
22386 putc (c, file);
22388 /* Write two quotes to get one. */
22389 if (c == '"')
22391 putc (c, file);
22392 ++count_string;
22395 for_string = NULL;
22396 for_decimal = "\"\n\t.byte ";
22397 to_close = "\"\n";
22398 ++count_string;
22400 if (count_string >= 512)
22402 fputs (to_close, file);
22404 for_string = "\t.byte \"";
22405 for_decimal = "\t.byte ";
22406 to_close = NULL;
22407 count_string = 0;
22410 else
22412 if (for_decimal)
22413 fputs (for_decimal, file);
22414 fprintf (file, "%d", c);
22416 for_string = "\n\t.byte \"";
22417 for_decimal = ", ";
22418 to_close = "\n";
22419 count_string = 0;
22423 /* Now close the string if we have written one. Then end the line. */
22424 if (to_close)
22425 fputs (to_close, file);
22428 /* Generate a unique section name for FILENAME for a section type
22429 represented by SECTION_DESC. Output goes into BUF.
22431 SECTION_DESC can be any string, as long as it is different for each
22432 possible section type.
22434 We name the section in the same manner as xlc. The name begins with an
22435 underscore followed by the filename (after stripping any leading directory
22436 names) with the last period replaced by the string SECTION_DESC. If
22437 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22438 the name. */
22440 void
22441 rs6000_gen_section_name (char **buf, const char *filename,
22442 const char *section_desc)
22444 const char *q, *after_last_slash, *last_period = 0;
22445 char *p;
22446 int len;
22448 after_last_slash = filename;
22449 for (q = filename; *q; q++)
22451 if (*q == '/')
22452 after_last_slash = q + 1;
22453 else if (*q == '.')
22454 last_period = q;
22457 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22458 *buf = (char *) xmalloc (len);
22460 p = *buf;
22461 *p++ = '_';
22463 for (q = after_last_slash; *q; q++)
22465 if (q == last_period)
22467 strcpy (p, section_desc);
22468 p += strlen (section_desc);
22469 break;
22472 else if (ISALNUM (*q))
22473 *p++ = *q;
22476 if (last_period == 0)
22477 strcpy (p, section_desc);
22478 else
22479 *p = '\0';
22482 /* Emit profile function. */
22484 void
22485 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22487 /* Non-standard profiling for kernels, which just saves LR then calls
22488 _mcount without worrying about arg saves. The idea is to change
22489 the function prologue as little as possible as it isn't easy to
22490 account for arg save/restore code added just for _mcount. */
22491 if (TARGET_PROFILE_KERNEL)
22492 return;
22494 if (DEFAULT_ABI == ABI_AIX)
22496 #ifndef NO_PROFILE_COUNTERS
22497 # define NO_PROFILE_COUNTERS 0
22498 #endif
22499 if (NO_PROFILE_COUNTERS)
22500 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22501 LCT_NORMAL, VOIDmode, 0);
22502 else
22504 char buf[30];
22505 const char *label_name;
22506 rtx fun;
22508 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22509 label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
22510 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22512 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22513 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22516 else if (DEFAULT_ABI == ABI_DARWIN)
22518 const char *mcount_name = RS6000_MCOUNT;
22519 int caller_addr_regno = LR_REGNO;
22521 /* Be conservative and always set this, at least for now. */
22522 crtl->uses_pic_offset_table = 1;
22524 #if TARGET_MACHO
22525 /* For PIC code, set up a stub and collect the caller's address
22526 from r0, which is where the prologue puts it. */
22527 if (MACHOPIC_INDIRECT
22528 && crtl->uses_pic_offset_table)
22529 caller_addr_regno = 0;
22530 #endif
22531 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22532 LCT_NORMAL, VOIDmode, 1,
22533 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22537 /* Write function profiler code. */
22539 void
22540 output_function_profiler (FILE *file, int labelno)
22542 char buf[100];
22544 switch (DEFAULT_ABI)
22546 default:
22547 gcc_unreachable ();
22549 case ABI_V4:
22550 if (!TARGET_32BIT)
22552 warning (0, "no profiling of 64-bit code for this ABI");
22553 return;
22555 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22556 fprintf (file, "\tmflr %s\n", reg_names[0]);
22557 if (NO_PROFILE_COUNTERS)
22559 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22560 reg_names[0], reg_names[1]);
22562 else if (TARGET_SECURE_PLT && flag_pic)
22564 if (TARGET_LINK_STACK)
22566 char name[32];
22567 get_ppc476_thunk_name (name);
22568 asm_fprintf (file, "\tbl %s\n", name);
22570 else
22571 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n");
22572 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22573 reg_names[0], reg_names[1]);
22574 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22575 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22576 reg_names[12], reg_names[12]);
22577 assemble_name (file, buf);
22578 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22579 assemble_name (file, buf);
22580 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22582 else if (flag_pic == 1)
22584 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22585 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22586 reg_names[0], reg_names[1]);
22587 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22588 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22589 assemble_name (file, buf);
22590 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22592 else if (flag_pic > 1)
22594 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22595 reg_names[0], reg_names[1]);
22596 /* Now, we need to get the address of the label. */
22597 if (TARGET_LINK_STACK)
22599 char name[32];
22600 get_ppc476_thunk_name (name);
22601 asm_fprintf (file, "\tbl %s\n\tb 1f\n\t.long ", name);
22602 assemble_name (file, buf);
22603 fputs ("-.\n1:", file);
22604 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22605 asm_fprintf (file, "\taddi %s,%s,4\n",
22606 reg_names[11], reg_names[11]);
22608 else
22610 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22611 assemble_name (file, buf);
22612 fputs ("-.\n1:", file);
22613 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22615 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22616 reg_names[0], reg_names[11]);
22617 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22618 reg_names[0], reg_names[0], reg_names[11]);
22620 else
22622 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22623 assemble_name (file, buf);
22624 fputs ("@ha\n", file);
22625 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22626 reg_names[0], reg_names[1]);
22627 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22628 assemble_name (file, buf);
22629 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22632 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22633 fprintf (file, "\tbl %s%s\n",
22634 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22635 break;
22637 case ABI_AIX:
22638 case ABI_DARWIN:
22639 if (!TARGET_PROFILE_KERNEL)
22641 /* Don't do anything, done in output_profile_hook (). */
22643 else
22645 gcc_assert (!TARGET_32BIT);
22647 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22648 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22650 if (cfun->static_chain_decl != NULL)
22652 asm_fprintf (file, "\tstd %s,24(%s)\n",
22653 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22654 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22655 asm_fprintf (file, "\tld %s,24(%s)\n",
22656 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22658 else
22659 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22661 break;
22667 /* The following variable value is the last issued insn. */
22669 static rtx last_scheduled_insn;
22671 /* The following variable helps to balance issuing of load and
22672 store instructions */
22674 static int load_store_pendulum;
22676 /* Power4 load update and store update instructions are cracked into a
22677 load or store and an integer insn which are executed in the same cycle.
22678 Branches have their own dispatch slot which does not count against the
22679 GCC issue rate, but it changes the program flow so there are no other
22680 instructions to issue in this cycle. */
22682 static int
22683 rs6000_variable_issue_1 (rtx insn, int more)
22685 last_scheduled_insn = insn;
22686 if (GET_CODE (PATTERN (insn)) == USE
22687 || GET_CODE (PATTERN (insn)) == CLOBBER)
22689 cached_can_issue_more = more;
22690 return cached_can_issue_more;
22693 if (insn_terminates_group_p (insn, current_group))
22695 cached_can_issue_more = 0;
22696 return cached_can_issue_more;
22699 /* If no reservation, but reach here */
22700 if (recog_memoized (insn) < 0)
22701 return more;
22703 if (rs6000_sched_groups)
22705 if (is_microcoded_insn (insn))
22706 cached_can_issue_more = 0;
22707 else if (is_cracked_insn (insn))
22708 cached_can_issue_more = more > 2 ? more - 2 : 0;
22709 else
22710 cached_can_issue_more = more - 1;
22712 return cached_can_issue_more;
22715 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22716 return 0;
22718 cached_can_issue_more = more - 1;
22719 return cached_can_issue_more;
22722 static int
22723 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22725 int r = rs6000_variable_issue_1 (insn, more);
22726 if (verbose)
22727 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22728 return r;
22731 /* Adjust the cost of a scheduling dependency. Return the new cost of
22732 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22734 static int
22735 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22737 enum attr_type attr_type;
22739 if (! recog_memoized (insn))
22740 return 0;
22742 switch (REG_NOTE_KIND (link))
22744 case REG_DEP_TRUE:
22746 /* Data dependency; DEP_INSN writes a register that INSN reads
22747 some cycles later. */
22749 /* Separate a load from a narrower, dependent store. */
22750 if (rs6000_sched_groups
22751 && GET_CODE (PATTERN (insn)) == SET
22752 && GET_CODE (PATTERN (dep_insn)) == SET
22753 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22754 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22755 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22756 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22757 return cost + 14;
22759 attr_type = get_attr_type (insn);
22761 switch (attr_type)
22763 case TYPE_JMPREG:
22764 /* Tell the first scheduling pass about the latency between
22765 a mtctr and bctr (and mtlr and br/blr). The first
22766 scheduling pass will not know about this latency since
22767 the mtctr instruction, which has the latency associated
22768 to it, will be generated by reload. */
22769 return TARGET_POWER ? 5 : 4;
22770 case TYPE_BRANCH:
22771 /* Leave some extra cycles between a compare and its
22772 dependent branch, to inhibit expensive mispredicts. */
22773 if ((rs6000_cpu_attr == CPU_PPC603
22774 || rs6000_cpu_attr == CPU_PPC604
22775 || rs6000_cpu_attr == CPU_PPC604E
22776 || rs6000_cpu_attr == CPU_PPC620
22777 || rs6000_cpu_attr == CPU_PPC630
22778 || rs6000_cpu_attr == CPU_PPC750
22779 || rs6000_cpu_attr == CPU_PPC7400
22780 || rs6000_cpu_attr == CPU_PPC7450
22781 || rs6000_cpu_attr == CPU_POWER4
22782 || rs6000_cpu_attr == CPU_POWER5
22783 || rs6000_cpu_attr == CPU_POWER7
22784 || rs6000_cpu_attr == CPU_CELL)
22785 && recog_memoized (dep_insn)
22786 && (INSN_CODE (dep_insn) >= 0))
22788 switch (get_attr_type (dep_insn))
22790 case TYPE_CMP:
22791 case TYPE_COMPARE:
22792 case TYPE_DELAYED_COMPARE:
22793 case TYPE_IMUL_COMPARE:
22794 case TYPE_LMUL_COMPARE:
22795 case TYPE_FPCOMPARE:
22796 case TYPE_CR_LOGICAL:
22797 case TYPE_DELAYED_CR:
22798 return cost + 2;
22799 default:
22800 break;
22802 break;
22804 case TYPE_STORE:
22805 case TYPE_STORE_U:
22806 case TYPE_STORE_UX:
22807 case TYPE_FPSTORE:
22808 case TYPE_FPSTORE_U:
22809 case TYPE_FPSTORE_UX:
22810 if ((rs6000_cpu == PROCESSOR_POWER6)
22811 && recog_memoized (dep_insn)
22812 && (INSN_CODE (dep_insn) >= 0))
22815 if (GET_CODE (PATTERN (insn)) != SET)
22816 /* If this happens, we have to extend this to schedule
22817 optimally. Return default for now. */
22818 return cost;
22820 /* Adjust the cost for the case where the value written
22821 by a fixed point operation is used as the address
22822 gen value on a store. */
22823 switch (get_attr_type (dep_insn))
22825 case TYPE_LOAD:
22826 case TYPE_LOAD_U:
22827 case TYPE_LOAD_UX:
22828 case TYPE_CNTLZ:
22830 if (! store_data_bypass_p (dep_insn, insn))
22831 return 4;
22832 break;
22834 case TYPE_LOAD_EXT:
22835 case TYPE_LOAD_EXT_U:
22836 case TYPE_LOAD_EXT_UX:
22837 case TYPE_VAR_SHIFT_ROTATE:
22838 case TYPE_VAR_DELAYED_COMPARE:
22840 if (! store_data_bypass_p (dep_insn, insn))
22841 return 6;
22842 break;
22844 case TYPE_INTEGER:
22845 case TYPE_COMPARE:
22846 case TYPE_FAST_COMPARE:
22847 case TYPE_EXTS:
22848 case TYPE_SHIFT:
22849 case TYPE_INSERT_WORD:
22850 case TYPE_INSERT_DWORD:
22851 case TYPE_FPLOAD_U:
22852 case TYPE_FPLOAD_UX:
22853 case TYPE_STORE_U:
22854 case TYPE_STORE_UX:
22855 case TYPE_FPSTORE_U:
22856 case TYPE_FPSTORE_UX:
22858 if (! store_data_bypass_p (dep_insn, insn))
22859 return 3;
22860 break;
22862 case TYPE_IMUL:
22863 case TYPE_IMUL2:
22864 case TYPE_IMUL3:
22865 case TYPE_LMUL:
22866 case TYPE_IMUL_COMPARE:
22867 case TYPE_LMUL_COMPARE:
22869 if (! store_data_bypass_p (dep_insn, insn))
22870 return 17;
22871 break;
22873 case TYPE_IDIV:
22875 if (! store_data_bypass_p (dep_insn, insn))
22876 return 45;
22877 break;
22879 case TYPE_LDIV:
22881 if (! store_data_bypass_p (dep_insn, insn))
22882 return 57;
22883 break;
22885 default:
22886 break;
22889 break;
22891 case TYPE_LOAD:
22892 case TYPE_LOAD_U:
22893 case TYPE_LOAD_UX:
22894 case TYPE_LOAD_EXT:
22895 case TYPE_LOAD_EXT_U:
22896 case TYPE_LOAD_EXT_UX:
22897 if ((rs6000_cpu == PROCESSOR_POWER6)
22898 && recog_memoized (dep_insn)
22899 && (INSN_CODE (dep_insn) >= 0))
22902 /* Adjust the cost for the case where the value written
22903 by a fixed point instruction is used within the address
22904 gen portion of a subsequent load(u)(x) */
22905 switch (get_attr_type (dep_insn))
22907 case TYPE_LOAD:
22908 case TYPE_LOAD_U:
22909 case TYPE_LOAD_UX:
22910 case TYPE_CNTLZ:
22912 if (set_to_load_agen (dep_insn, insn))
22913 return 4;
22914 break;
22916 case TYPE_LOAD_EXT:
22917 case TYPE_LOAD_EXT_U:
22918 case TYPE_LOAD_EXT_UX:
22919 case TYPE_VAR_SHIFT_ROTATE:
22920 case TYPE_VAR_DELAYED_COMPARE:
22922 if (set_to_load_agen (dep_insn, insn))
22923 return 6;
22924 break;
22926 case TYPE_INTEGER:
22927 case TYPE_COMPARE:
22928 case TYPE_FAST_COMPARE:
22929 case TYPE_EXTS:
22930 case TYPE_SHIFT:
22931 case TYPE_INSERT_WORD:
22932 case TYPE_INSERT_DWORD:
22933 case TYPE_FPLOAD_U:
22934 case TYPE_FPLOAD_UX:
22935 case TYPE_STORE_U:
22936 case TYPE_STORE_UX:
22937 case TYPE_FPSTORE_U:
22938 case TYPE_FPSTORE_UX:
22940 if (set_to_load_agen (dep_insn, insn))
22941 return 3;
22942 break;
22944 case TYPE_IMUL:
22945 case TYPE_IMUL2:
22946 case TYPE_IMUL3:
22947 case TYPE_LMUL:
22948 case TYPE_IMUL_COMPARE:
22949 case TYPE_LMUL_COMPARE:
22951 if (set_to_load_agen (dep_insn, insn))
22952 return 17;
22953 break;
22955 case TYPE_IDIV:
22957 if (set_to_load_agen (dep_insn, insn))
22958 return 45;
22959 break;
22961 case TYPE_LDIV:
22963 if (set_to_load_agen (dep_insn, insn))
22964 return 57;
22965 break;
22967 default:
22968 break;
22971 break;
22973 case TYPE_FPLOAD:
22974 if ((rs6000_cpu == PROCESSOR_POWER6)
22975 && recog_memoized (dep_insn)
22976 && (INSN_CODE (dep_insn) >= 0)
22977 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22978 return 2;
22980 default:
22981 break;
22984 /* Fall out to return default cost. */
22986 break;
22988 case REG_DEP_OUTPUT:
22989 /* Output dependency; DEP_INSN writes a register that INSN writes some
22990 cycles later. */
22991 if ((rs6000_cpu == PROCESSOR_POWER6)
22992 && recog_memoized (dep_insn)
22993 && (INSN_CODE (dep_insn) >= 0))
22995 attr_type = get_attr_type (insn);
22997 switch (attr_type)
22999 case TYPE_FP:
23000 if (get_attr_type (dep_insn) == TYPE_FP)
23001 return 1;
23002 break;
23003 case TYPE_FPLOAD:
23004 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23005 return 2;
23006 break;
23007 default:
23008 break;
23011 case REG_DEP_ANTI:
23012 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23013 cycles later. */
23014 return 0;
23016 default:
23017 gcc_unreachable ();
23020 return cost;
23023 /* Debug version of rs6000_adjust_cost. */
23025 static int
23026 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23028 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23030 if (ret != cost)
23032 const char *dep;
23034 switch (REG_NOTE_KIND (link))
23036 default: dep = "unknown depencency"; break;
23037 case REG_DEP_TRUE: dep = "data dependency"; break;
23038 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23039 case REG_DEP_ANTI: dep = "anti depencency"; break;
23042 fprintf (stderr,
23043 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23044 "%s, insn:\n", ret, cost, dep);
23046 debug_rtx (insn);
23049 return ret;
23052 /* The function returns a true if INSN is microcoded.
23053 Return false otherwise. */
23055 static bool
23056 is_microcoded_insn (rtx insn)
23058 if (!insn || !NONDEBUG_INSN_P (insn)
23059 || GET_CODE (PATTERN (insn)) == USE
23060 || GET_CODE (PATTERN (insn)) == CLOBBER)
23061 return false;
23063 if (rs6000_cpu_attr == CPU_CELL)
23064 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23066 if (rs6000_sched_groups)
23068 enum attr_type type = get_attr_type (insn);
23069 if (type == TYPE_LOAD_EXT_U
23070 || type == TYPE_LOAD_EXT_UX
23071 || type == TYPE_LOAD_UX
23072 || type == TYPE_STORE_UX
23073 || type == TYPE_MFCR)
23074 return true;
23077 return false;
23080 /* The function returns true if INSN is cracked into 2 instructions
23081 by the processor (and therefore occupies 2 issue slots). */
23083 static bool
23084 is_cracked_insn (rtx insn)
23086 if (!insn || !NONDEBUG_INSN_P (insn)
23087 || GET_CODE (PATTERN (insn)) == USE
23088 || GET_CODE (PATTERN (insn)) == CLOBBER)
23089 return false;
23091 if (rs6000_sched_groups)
23093 enum attr_type type = get_attr_type (insn);
23094 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23095 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23096 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23097 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23098 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23099 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23100 || type == TYPE_IDIV || type == TYPE_LDIV
23101 || type == TYPE_INSERT_WORD)
23102 return true;
23105 return false;
23108 /* The function returns true if INSN can be issued only from
23109 the branch slot. */
23111 static bool
23112 is_branch_slot_insn (rtx insn)
23114 if (!insn || !NONDEBUG_INSN_P (insn)
23115 || GET_CODE (PATTERN (insn)) == USE
23116 || GET_CODE (PATTERN (insn)) == CLOBBER)
23117 return false;
23119 if (rs6000_sched_groups)
23121 enum attr_type type = get_attr_type (insn);
23122 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23123 return true;
23124 return false;
23127 return false;
23130 /* The function returns true if out_inst sets a value that is
23131 used in the address generation computation of in_insn */
23132 static bool
23133 set_to_load_agen (rtx out_insn, rtx in_insn)
23135 rtx out_set, in_set;
23137 /* For performance reasons, only handle the simple case where
23138 both loads are a single_set. */
23139 out_set = single_set (out_insn);
23140 if (out_set)
23142 in_set = single_set (in_insn);
23143 if (in_set)
23144 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23147 return false;
23150 /* The function returns true if the target storage location of
23151 out_insn is adjacent to the target storage location of in_insn */
23152 /* Return 1 if memory locations are adjacent. */
23154 static bool
23155 adjacent_mem_locations (rtx insn1, rtx insn2)
23158 rtx a = get_store_dest (PATTERN (insn1));
23159 rtx b = get_store_dest (PATTERN (insn2));
23161 if ((GET_CODE (XEXP (a, 0)) == REG
23162 || (GET_CODE (XEXP (a, 0)) == PLUS
23163 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23164 && (GET_CODE (XEXP (b, 0)) == REG
23165 || (GET_CODE (XEXP (b, 0)) == PLUS
23166 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23168 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23169 rtx reg0, reg1;
23171 if (GET_CODE (XEXP (a, 0)) == PLUS)
23173 reg0 = XEXP (XEXP (a, 0), 0);
23174 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23176 else
23177 reg0 = XEXP (a, 0);
23179 if (GET_CODE (XEXP (b, 0)) == PLUS)
23181 reg1 = XEXP (XEXP (b, 0), 0);
23182 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23184 else
23185 reg1 = XEXP (b, 0);
23187 val_diff = val1 - val0;
23189 return ((REGNO (reg0) == REGNO (reg1))
23190 && ((MEM_SIZE_KNOWN_P (a) && val_diff == MEM_SIZE (a))
23191 || (MEM_SIZE_KNOWN_P (b) && val_diff == -MEM_SIZE (b))));
23194 return false;
23197 /* A C statement (sans semicolon) to update the integer scheduling
23198 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23199 INSN earlier, reduce the priority to execute INSN later. Do not
23200 define this macro if you do not need to adjust the scheduling
23201 priorities of insns. */
23203 static int
23204 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23206 /* On machines (like the 750) which have asymmetric integer units,
23207 where one integer unit can do multiply and divides and the other
23208 can't, reduce the priority of multiply/divide so it is scheduled
23209 before other integer operations. */
23211 #if 0
23212 if (! INSN_P (insn))
23213 return priority;
23215 if (GET_CODE (PATTERN (insn)) == USE)
23216 return priority;
23218 switch (rs6000_cpu_attr) {
23219 case CPU_PPC750:
23220 switch (get_attr_type (insn))
23222 default:
23223 break;
23225 case TYPE_IMUL:
23226 case TYPE_IDIV:
23227 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23228 priority, priority);
23229 if (priority >= 0 && priority < 0x01000000)
23230 priority >>= 3;
23231 break;
23234 #endif
23236 if (insn_must_be_first_in_group (insn)
23237 && reload_completed
23238 && current_sched_info->sched_max_insns_priority
23239 && rs6000_sched_restricted_insns_priority)
23242 /* Prioritize insns that can be dispatched only in the first
23243 dispatch slot. */
23244 if (rs6000_sched_restricted_insns_priority == 1)
23245 /* Attach highest priority to insn. This means that in
23246 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23247 precede 'priority' (critical path) considerations. */
23248 return current_sched_info->sched_max_insns_priority;
23249 else if (rs6000_sched_restricted_insns_priority == 2)
23250 /* Increase priority of insn by a minimal amount. This means that in
23251 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23252 considerations precede dispatch-slot restriction considerations. */
23253 return (priority + 1);
23256 if (rs6000_cpu == PROCESSOR_POWER6
23257 && ((load_store_pendulum == -2 && is_load_insn (insn))
23258 || (load_store_pendulum == 2 && is_store_insn (insn))))
23259 /* Attach highest priority to insn if the scheduler has just issued two
23260 stores and this instruction is a load, or two loads and this instruction
23261 is a store. Power6 wants loads and stores scheduled alternately
23262 when possible */
23263 return current_sched_info->sched_max_insns_priority;
23265 return priority;
23268 /* Return true if the instruction is nonpipelined on the Cell. */
23269 static bool
23270 is_nonpipeline_insn (rtx insn)
23272 enum attr_type type;
23273 if (!insn || !NONDEBUG_INSN_P (insn)
23274 || GET_CODE (PATTERN (insn)) == USE
23275 || GET_CODE (PATTERN (insn)) == CLOBBER)
23276 return false;
23278 type = get_attr_type (insn);
23279 if (type == TYPE_IMUL
23280 || type == TYPE_IMUL2
23281 || type == TYPE_IMUL3
23282 || type == TYPE_LMUL
23283 || type == TYPE_IDIV
23284 || type == TYPE_LDIV
23285 || type == TYPE_SDIV
23286 || type == TYPE_DDIV
23287 || type == TYPE_SSQRT
23288 || type == TYPE_DSQRT
23289 || type == TYPE_MFCR
23290 || type == TYPE_MFCRF
23291 || type == TYPE_MFJMPR)
23293 return true;
23295 return false;
23299 /* Return how many instructions the machine can issue per cycle. */
23301 static int
23302 rs6000_issue_rate (void)
23304 /* Unless scheduling for register pressure, use issue rate of 1 for
23305 first scheduling pass to decrease degradation. */
23306 if (!reload_completed && !flag_sched_pressure)
23307 return 1;
23309 switch (rs6000_cpu_attr) {
23310 case CPU_RIOS1: /* ? */
23311 case CPU_RS64A:
23312 case CPU_PPC601: /* ? */
23313 case CPU_PPC7450:
23314 return 3;
23315 case CPU_PPC440:
23316 case CPU_PPC603:
23317 case CPU_PPC750:
23318 case CPU_PPC7400:
23319 case CPU_PPC8540:
23320 case CPU_CELL:
23321 case CPU_PPCE300C2:
23322 case CPU_PPCE300C3:
23323 case CPU_PPCE500MC:
23324 case CPU_PPCE500MC64:
23325 case CPU_TITAN:
23326 return 2;
23327 case CPU_RIOS2:
23328 case CPU_PPC476:
23329 case CPU_PPC604:
23330 case CPU_PPC604E:
23331 case CPU_PPC620:
23332 case CPU_PPC630:
23333 return 4;
23334 case CPU_POWER4:
23335 case CPU_POWER5:
23336 case CPU_POWER6:
23337 case CPU_POWER7:
23338 return 5;
23339 default:
23340 return 1;
23344 /* Return how many instructions to look ahead for better insn
23345 scheduling. */
23347 static int
23348 rs6000_use_sched_lookahead (void)
23350 if (rs6000_cpu_attr == CPU_PPC8540)
23351 return 4;
23352 if (rs6000_cpu_attr == CPU_CELL)
23353 return (reload_completed ? 8 : 0);
23354 return 0;
23357 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23358 static int
23359 rs6000_use_sched_lookahead_guard (rtx insn)
23361 if (rs6000_cpu_attr != CPU_CELL)
23362 return 1;
23364 if (insn == NULL_RTX || !INSN_P (insn))
23365 abort ();
23367 if (!reload_completed
23368 || is_nonpipeline_insn (insn)
23369 || is_microcoded_insn (insn))
23370 return 0;
23372 return 1;
23375 /* Determine is PAT refers to memory. */
23377 static bool
23378 is_mem_ref (rtx pat)
23380 const char * fmt;
23381 int i, j;
23382 bool ret = false;
23384 /* stack_tie does not produce any real memory traffic. */
23385 if (GET_CODE (pat) == UNSPEC
23386 && XINT (pat, 1) == UNSPEC_TIE)
23387 return false;
23389 if (GET_CODE (pat) == MEM)
23390 return true;
23392 /* Recursively process the pattern. */
23393 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23395 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23397 if (fmt[i] == 'e')
23398 ret |= is_mem_ref (XEXP (pat, i));
23399 else if (fmt[i] == 'E')
23400 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23401 ret |= is_mem_ref (XVECEXP (pat, i, j));
23404 return ret;
23407 /* Determine if PAT is a PATTERN of a load insn. */
23409 static bool
23410 is_load_insn1 (rtx pat)
23412 if (!pat || pat == NULL_RTX)
23413 return false;
23415 if (GET_CODE (pat) == SET)
23416 return is_mem_ref (SET_SRC (pat));
23418 if (GET_CODE (pat) == PARALLEL)
23420 int i;
23422 for (i = 0; i < XVECLEN (pat, 0); i++)
23423 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23424 return true;
23427 return false;
23430 /* Determine if INSN loads from memory. */
23432 static bool
23433 is_load_insn (rtx insn)
23435 if (!insn || !INSN_P (insn))
23436 return false;
23438 if (GET_CODE (insn) == CALL_INSN)
23439 return false;
23441 return is_load_insn1 (PATTERN (insn));
23444 /* Determine if PAT is a PATTERN of a store insn. */
23446 static bool
23447 is_store_insn1 (rtx pat)
23449 if (!pat || pat == NULL_RTX)
23450 return false;
23452 if (GET_CODE (pat) == SET)
23453 return is_mem_ref (SET_DEST (pat));
23455 if (GET_CODE (pat) == PARALLEL)
23457 int i;
23459 for (i = 0; i < XVECLEN (pat, 0); i++)
23460 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23461 return true;
23464 return false;
23467 /* Determine if INSN stores to memory. */
23469 static bool
23470 is_store_insn (rtx insn)
23472 if (!insn || !INSN_P (insn))
23473 return false;
23475 return is_store_insn1 (PATTERN (insn));
23478 /* Return the dest of a store insn. */
23480 static rtx
23481 get_store_dest (rtx pat)
23483 gcc_assert (is_store_insn1 (pat));
23485 if (GET_CODE (pat) == SET)
23486 return SET_DEST (pat);
23487 else if (GET_CODE (pat) == PARALLEL)
23489 int i;
23491 for (i = 0; i < XVECLEN (pat, 0); i++)
23493 rtx inner_pat = XVECEXP (pat, 0, i);
23494 if (GET_CODE (inner_pat) == SET
23495 && is_mem_ref (SET_DEST (inner_pat)))
23496 return inner_pat;
23499 /* We shouldn't get here, because we should have either a simple
23500 store insn or a store with update which are covered above. */
23501 gcc_unreachable();
23504 /* Returns whether the dependence between INSN and NEXT is considered
23505 costly by the given target. */
23507 static bool
23508 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23510 rtx insn;
23511 rtx next;
23513 /* If the flag is not enabled - no dependence is considered costly;
23514 allow all dependent insns in the same group.
23515 This is the most aggressive option. */
23516 if (rs6000_sched_costly_dep == no_dep_costly)
23517 return false;
23519 /* If the flag is set to 1 - a dependence is always considered costly;
23520 do not allow dependent instructions in the same group.
23521 This is the most conservative option. */
23522 if (rs6000_sched_costly_dep == all_deps_costly)
23523 return true;
23525 insn = DEP_PRO (dep);
23526 next = DEP_CON (dep);
23528 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23529 && is_load_insn (next)
23530 && is_store_insn (insn))
23531 /* Prevent load after store in the same group. */
23532 return true;
23534 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23535 && is_load_insn (next)
23536 && is_store_insn (insn)
23537 && DEP_TYPE (dep) == REG_DEP_TRUE)
23538 /* Prevent load after store in the same group if it is a true
23539 dependence. */
23540 return true;
23542 /* The flag is set to X; dependences with latency >= X are considered costly,
23543 and will not be scheduled in the same group. */
23544 if (rs6000_sched_costly_dep <= max_dep_latency
23545 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23546 return true;
23548 return false;
23551 /* Return the next insn after INSN that is found before TAIL is reached,
23552 skipping any "non-active" insns - insns that will not actually occupy
23553 an issue slot. Return NULL_RTX if such an insn is not found. */
23555 static rtx
23556 get_next_active_insn (rtx insn, rtx tail)
23558 if (insn == NULL_RTX || insn == tail)
23559 return NULL_RTX;
23561 while (1)
23563 insn = NEXT_INSN (insn);
23564 if (insn == NULL_RTX || insn == tail)
23565 return NULL_RTX;
23567 if (CALL_P (insn)
23568 || JUMP_P (insn)
23569 || (NONJUMP_INSN_P (insn)
23570 && GET_CODE (PATTERN (insn)) != USE
23571 && GET_CODE (PATTERN (insn)) != CLOBBER
23572 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23573 break;
23575 return insn;
23578 /* We are about to begin issuing insns for this clock cycle. */
23580 static int
23581 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23582 rtx *ready ATTRIBUTE_UNUSED,
23583 int *pn_ready ATTRIBUTE_UNUSED,
23584 int clock_var ATTRIBUTE_UNUSED)
23586 int n_ready = *pn_ready;
23588 if (sched_verbose)
23589 fprintf (dump, "// rs6000_sched_reorder :\n");
23591 /* Reorder the ready list, if the second to last ready insn
23592 is a nonepipeline insn. */
23593 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23595 if (is_nonpipeline_insn (ready[n_ready - 1])
23596 && (recog_memoized (ready[n_ready - 2]) > 0))
23597 /* Simply swap first two insns. */
23599 rtx tmp = ready[n_ready - 1];
23600 ready[n_ready - 1] = ready[n_ready - 2];
23601 ready[n_ready - 2] = tmp;
23605 if (rs6000_cpu == PROCESSOR_POWER6)
23606 load_store_pendulum = 0;
23608 return rs6000_issue_rate ();
23611 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23613 static int
23614 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23615 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23617 if (sched_verbose)
23618 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23620 /* For Power6, we need to handle some special cases to try and keep the
23621 store queue from overflowing and triggering expensive flushes.
23623 This code monitors how load and store instructions are being issued
23624 and skews the ready list one way or the other to increase the likelihood
23625 that a desired instruction is issued at the proper time.
23627 A couple of things are done. First, we maintain a "load_store_pendulum"
23628 to track the current state of load/store issue.
23630 - If the pendulum is at zero, then no loads or stores have been
23631 issued in the current cycle so we do nothing.
23633 - If the pendulum is 1, then a single load has been issued in this
23634 cycle and we attempt to locate another load in the ready list to
23635 issue with it.
23637 - If the pendulum is -2, then two stores have already been
23638 issued in this cycle, so we increase the priority of the first load
23639 in the ready list to increase it's likelihood of being chosen first
23640 in the next cycle.
23642 - If the pendulum is -1, then a single store has been issued in this
23643 cycle and we attempt to locate another store in the ready list to
23644 issue with it, preferring a store to an adjacent memory location to
23645 facilitate store pairing in the store queue.
23647 - If the pendulum is 2, then two loads have already been
23648 issued in this cycle, so we increase the priority of the first store
23649 in the ready list to increase it's likelihood of being chosen first
23650 in the next cycle.
23652 - If the pendulum < -2 or > 2, then do nothing.
23654 Note: This code covers the most common scenarios. There exist non
23655 load/store instructions which make use of the LSU and which
23656 would need to be accounted for to strictly model the behavior
23657 of the machine. Those instructions are currently unaccounted
23658 for to help minimize compile time overhead of this code.
23660 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23662 int pos;
23663 int i;
23664 rtx tmp;
23666 if (is_store_insn (last_scheduled_insn))
23667 /* Issuing a store, swing the load_store_pendulum to the left */
23668 load_store_pendulum--;
23669 else if (is_load_insn (last_scheduled_insn))
23670 /* Issuing a load, swing the load_store_pendulum to the right */
23671 load_store_pendulum++;
23672 else
23673 return cached_can_issue_more;
23675 /* If the pendulum is balanced, or there is only one instruction on
23676 the ready list, then all is well, so return. */
23677 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23678 return cached_can_issue_more;
23680 if (load_store_pendulum == 1)
23682 /* A load has been issued in this cycle. Scan the ready list
23683 for another load to issue with it */
23684 pos = *pn_ready-1;
23686 while (pos >= 0)
23688 if (is_load_insn (ready[pos]))
23690 /* Found a load. Move it to the head of the ready list,
23691 and adjust it's priority so that it is more likely to
23692 stay there */
23693 tmp = ready[pos];
23694 for (i=pos; i<*pn_ready-1; i++)
23695 ready[i] = ready[i + 1];
23696 ready[*pn_ready-1] = tmp;
23698 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23699 INSN_PRIORITY (tmp)++;
23700 break;
23702 pos--;
23705 else if (load_store_pendulum == -2)
23707 /* Two stores have been issued in this cycle. Increase the
23708 priority of the first load in the ready list to favor it for
23709 issuing in the next cycle. */
23710 pos = *pn_ready-1;
23712 while (pos >= 0)
23714 if (is_load_insn (ready[pos])
23715 && !sel_sched_p ()
23716 && INSN_PRIORITY_KNOWN (ready[pos]))
23718 INSN_PRIORITY (ready[pos])++;
23720 /* Adjust the pendulum to account for the fact that a load
23721 was found and increased in priority. This is to prevent
23722 increasing the priority of multiple loads */
23723 load_store_pendulum--;
23725 break;
23727 pos--;
23730 else if (load_store_pendulum == -1)
23732 /* A store has been issued in this cycle. Scan the ready list for
23733 another store to issue with it, preferring a store to an adjacent
23734 memory location */
23735 int first_store_pos = -1;
23737 pos = *pn_ready-1;
23739 while (pos >= 0)
23741 if (is_store_insn (ready[pos]))
23743 /* Maintain the index of the first store found on the
23744 list */
23745 if (first_store_pos == -1)
23746 first_store_pos = pos;
23748 if (is_store_insn (last_scheduled_insn)
23749 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23751 /* Found an adjacent store. Move it to the head of the
23752 ready list, and adjust it's priority so that it is
23753 more likely to stay there */
23754 tmp = ready[pos];
23755 for (i=pos; i<*pn_ready-1; i++)
23756 ready[i] = ready[i + 1];
23757 ready[*pn_ready-1] = tmp;
23759 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23760 INSN_PRIORITY (tmp)++;
23762 first_store_pos = -1;
23764 break;
23767 pos--;
23770 if (first_store_pos >= 0)
23772 /* An adjacent store wasn't found, but a non-adjacent store was,
23773 so move the non-adjacent store to the front of the ready
23774 list, and adjust its priority so that it is more likely to
23775 stay there. */
23776 tmp = ready[first_store_pos];
23777 for (i=first_store_pos; i<*pn_ready-1; i++)
23778 ready[i] = ready[i + 1];
23779 ready[*pn_ready-1] = tmp;
23780 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23781 INSN_PRIORITY (tmp)++;
23784 else if (load_store_pendulum == 2)
23786 /* Two loads have been issued in this cycle. Increase the priority
23787 of the first store in the ready list to favor it for issuing in
23788 the next cycle. */
23789 pos = *pn_ready-1;
23791 while (pos >= 0)
23793 if (is_store_insn (ready[pos])
23794 && !sel_sched_p ()
23795 && INSN_PRIORITY_KNOWN (ready[pos]))
23797 INSN_PRIORITY (ready[pos])++;
23799 /* Adjust the pendulum to account for the fact that a store
23800 was found and increased in priority. This is to prevent
23801 increasing the priority of multiple stores */
23802 load_store_pendulum++;
23804 break;
23806 pos--;
23811 return cached_can_issue_more;
23814 /* Return whether the presence of INSN causes a dispatch group termination
23815 of group WHICH_GROUP.
23817 If WHICH_GROUP == current_group, this function will return true if INSN
23818 causes the termination of the current group (i.e, the dispatch group to
23819 which INSN belongs). This means that INSN will be the last insn in the
23820 group it belongs to.
23822 If WHICH_GROUP == previous_group, this function will return true if INSN
23823 causes the termination of the previous group (i.e, the dispatch group that
23824 precedes the group to which INSN belongs). This means that INSN will be
23825 the first insn in the group it belongs to). */
23827 static bool
23828 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23830 bool first, last;
23832 if (! insn)
23833 return false;
23835 first = insn_must_be_first_in_group (insn);
23836 last = insn_must_be_last_in_group (insn);
23838 if (first && last)
23839 return true;
23841 if (which_group == current_group)
23842 return last;
23843 else if (which_group == previous_group)
23844 return first;
23846 return false;
23850 static bool
23851 insn_must_be_first_in_group (rtx insn)
23853 enum attr_type type;
23855 if (!insn
23856 || GET_CODE (insn) == NOTE
23857 || DEBUG_INSN_P (insn)
23858 || GET_CODE (PATTERN (insn)) == USE
23859 || GET_CODE (PATTERN (insn)) == CLOBBER)
23860 return false;
23862 switch (rs6000_cpu)
23864 case PROCESSOR_POWER5:
23865 if (is_cracked_insn (insn))
23866 return true;
23867 case PROCESSOR_POWER4:
23868 if (is_microcoded_insn (insn))
23869 return true;
23871 if (!rs6000_sched_groups)
23872 return false;
23874 type = get_attr_type (insn);
23876 switch (type)
23878 case TYPE_MFCR:
23879 case TYPE_MFCRF:
23880 case TYPE_MTCR:
23881 case TYPE_DELAYED_CR:
23882 case TYPE_CR_LOGICAL:
23883 case TYPE_MTJMPR:
23884 case TYPE_MFJMPR:
23885 case TYPE_IDIV:
23886 case TYPE_LDIV:
23887 case TYPE_LOAD_L:
23888 case TYPE_STORE_C:
23889 case TYPE_ISYNC:
23890 case TYPE_SYNC:
23891 return true;
23892 default:
23893 break;
23895 break;
23896 case PROCESSOR_POWER6:
23897 type = get_attr_type (insn);
23899 switch (type)
23901 case TYPE_INSERT_DWORD:
23902 case TYPE_EXTS:
23903 case TYPE_CNTLZ:
23904 case TYPE_SHIFT:
23905 case TYPE_VAR_SHIFT_ROTATE:
23906 case TYPE_TRAP:
23907 case TYPE_IMUL:
23908 case TYPE_IMUL2:
23909 case TYPE_IMUL3:
23910 case TYPE_LMUL:
23911 case TYPE_IDIV:
23912 case TYPE_INSERT_WORD:
23913 case TYPE_DELAYED_COMPARE:
23914 case TYPE_IMUL_COMPARE:
23915 case TYPE_LMUL_COMPARE:
23916 case TYPE_FPCOMPARE:
23917 case TYPE_MFCR:
23918 case TYPE_MTCR:
23919 case TYPE_MFJMPR:
23920 case TYPE_MTJMPR:
23921 case TYPE_ISYNC:
23922 case TYPE_SYNC:
23923 case TYPE_LOAD_L:
23924 case TYPE_STORE_C:
23925 case TYPE_LOAD_U:
23926 case TYPE_LOAD_UX:
23927 case TYPE_LOAD_EXT_UX:
23928 case TYPE_STORE_U:
23929 case TYPE_STORE_UX:
23930 case TYPE_FPLOAD_U:
23931 case TYPE_FPLOAD_UX:
23932 case TYPE_FPSTORE_U:
23933 case TYPE_FPSTORE_UX:
23934 return true;
23935 default:
23936 break;
23938 break;
23939 case PROCESSOR_POWER7:
23940 type = get_attr_type (insn);
23942 switch (type)
23944 case TYPE_CR_LOGICAL:
23945 case TYPE_MFCR:
23946 case TYPE_MFCRF:
23947 case TYPE_MTCR:
23948 case TYPE_IDIV:
23949 case TYPE_LDIV:
23950 case TYPE_COMPARE:
23951 case TYPE_DELAYED_COMPARE:
23952 case TYPE_VAR_DELAYED_COMPARE:
23953 case TYPE_ISYNC:
23954 case TYPE_LOAD_L:
23955 case TYPE_STORE_C:
23956 case TYPE_LOAD_U:
23957 case TYPE_LOAD_UX:
23958 case TYPE_LOAD_EXT:
23959 case TYPE_LOAD_EXT_U:
23960 case TYPE_LOAD_EXT_UX:
23961 case TYPE_STORE_U:
23962 case TYPE_STORE_UX:
23963 case TYPE_FPLOAD_U:
23964 case TYPE_FPLOAD_UX:
23965 case TYPE_FPSTORE_U:
23966 case TYPE_FPSTORE_UX:
23967 case TYPE_MFJMPR:
23968 case TYPE_MTJMPR:
23969 return true;
23970 default:
23971 break;
23973 break;
23974 default:
23975 break;
23978 return false;
23981 static bool
23982 insn_must_be_last_in_group (rtx insn)
23984 enum attr_type type;
23986 if (!insn
23987 || GET_CODE (insn) == NOTE
23988 || DEBUG_INSN_P (insn)
23989 || GET_CODE (PATTERN (insn)) == USE
23990 || GET_CODE (PATTERN (insn)) == CLOBBER)
23991 return false;
23993 switch (rs6000_cpu) {
23994 case PROCESSOR_POWER4:
23995 case PROCESSOR_POWER5:
23996 if (is_microcoded_insn (insn))
23997 return true;
23999 if (is_branch_slot_insn (insn))
24000 return true;
24002 break;
24003 case PROCESSOR_POWER6:
24004 type = get_attr_type (insn);
24006 switch (type)
24008 case TYPE_EXTS:
24009 case TYPE_CNTLZ:
24010 case TYPE_SHIFT:
24011 case TYPE_VAR_SHIFT_ROTATE:
24012 case TYPE_TRAP:
24013 case TYPE_IMUL:
24014 case TYPE_IMUL2:
24015 case TYPE_IMUL3:
24016 case TYPE_LMUL:
24017 case TYPE_IDIV:
24018 case TYPE_DELAYED_COMPARE:
24019 case TYPE_IMUL_COMPARE:
24020 case TYPE_LMUL_COMPARE:
24021 case TYPE_FPCOMPARE:
24022 case TYPE_MFCR:
24023 case TYPE_MTCR:
24024 case TYPE_MFJMPR:
24025 case TYPE_MTJMPR:
24026 case TYPE_ISYNC:
24027 case TYPE_SYNC:
24028 case TYPE_LOAD_L:
24029 case TYPE_STORE_C:
24030 return true;
24031 default:
24032 break;
24034 break;
24035 case PROCESSOR_POWER7:
24036 type = get_attr_type (insn);
24038 switch (type)
24040 case TYPE_ISYNC:
24041 case TYPE_SYNC:
24042 case TYPE_LOAD_L:
24043 case TYPE_STORE_C:
24044 case TYPE_LOAD_EXT_U:
24045 case TYPE_LOAD_EXT_UX:
24046 case TYPE_STORE_UX:
24047 return true;
24048 default:
24049 break;
24051 break;
24052 default:
24053 break;
24056 return false;
24059 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24060 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24062 static bool
24063 is_costly_group (rtx *group_insns, rtx next_insn)
24065 int i;
24066 int issue_rate = rs6000_issue_rate ();
24068 for (i = 0; i < issue_rate; i++)
24070 sd_iterator_def sd_it;
24071 dep_t dep;
24072 rtx insn = group_insns[i];
24074 if (!insn)
24075 continue;
24077 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24079 rtx next = DEP_CON (dep);
24081 if (next == next_insn
24082 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24083 return true;
24087 return false;
24090 /* Utility of the function redefine_groups.
24091 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24092 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24093 to keep it "far" (in a separate group) from GROUP_INSNS, following
24094 one of the following schemes, depending on the value of the flag
24095 -minsert_sched_nops = X:
24096 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24097 in order to force NEXT_INSN into a separate group.
24098 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24099 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24100 insertion (has a group just ended, how many vacant issue slots remain in the
24101 last group, and how many dispatch groups were encountered so far). */
24103 static int
24104 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24105 rtx next_insn, bool *group_end, int can_issue_more,
24106 int *group_count)
24108 rtx nop;
24109 bool force;
24110 int issue_rate = rs6000_issue_rate ();
24111 bool end = *group_end;
24112 int i;
24114 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24115 return can_issue_more;
24117 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24118 return can_issue_more;
24120 force = is_costly_group (group_insns, next_insn);
24121 if (!force)
24122 return can_issue_more;
24124 if (sched_verbose > 6)
24125 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24126 *group_count ,can_issue_more);
24128 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24130 if (*group_end)
24131 can_issue_more = 0;
24133 /* Since only a branch can be issued in the last issue_slot, it is
24134 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24135 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24136 in this case the last nop will start a new group and the branch
24137 will be forced to the new group. */
24138 if (can_issue_more && !is_branch_slot_insn (next_insn))
24139 can_issue_more--;
24141 while (can_issue_more > 0)
24143 nop = gen_nop ();
24144 emit_insn_before (nop, next_insn);
24145 can_issue_more--;
24148 *group_end = true;
24149 return 0;
24152 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24154 int n_nops = rs6000_sched_insert_nops;
24156 /* Nops can't be issued from the branch slot, so the effective
24157 issue_rate for nops is 'issue_rate - 1'. */
24158 if (can_issue_more == 0)
24159 can_issue_more = issue_rate;
24160 can_issue_more--;
24161 if (can_issue_more == 0)
24163 can_issue_more = issue_rate - 1;
24164 (*group_count)++;
24165 end = true;
24166 for (i = 0; i < issue_rate; i++)
24168 group_insns[i] = 0;
24172 while (n_nops > 0)
24174 nop = gen_nop ();
24175 emit_insn_before (nop, next_insn);
24176 if (can_issue_more == issue_rate - 1) /* new group begins */
24177 end = false;
24178 can_issue_more--;
24179 if (can_issue_more == 0)
24181 can_issue_more = issue_rate - 1;
24182 (*group_count)++;
24183 end = true;
24184 for (i = 0; i < issue_rate; i++)
24186 group_insns[i] = 0;
24189 n_nops--;
24192 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24193 can_issue_more++;
24195 /* Is next_insn going to start a new group? */
24196 *group_end
24197 = (end
24198 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24199 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24200 || (can_issue_more < issue_rate &&
24201 insn_terminates_group_p (next_insn, previous_group)));
24202 if (*group_end && end)
24203 (*group_count)--;
24205 if (sched_verbose > 6)
24206 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24207 *group_count, can_issue_more);
24208 return can_issue_more;
24211 return can_issue_more;
24214 /* This function tries to synch the dispatch groups that the compiler "sees"
24215 with the dispatch groups that the processor dispatcher is expected to
24216 form in practice. It tries to achieve this synchronization by forcing the
24217 estimated processor grouping on the compiler (as opposed to the function
24218 'pad_goups' which tries to force the scheduler's grouping on the processor).
24220 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24221 examines the (estimated) dispatch groups that will be formed by the processor
24222 dispatcher. It marks these group boundaries to reflect the estimated
24223 processor grouping, overriding the grouping that the scheduler had marked.
24224 Depending on the value of the flag '-minsert-sched-nops' this function can
24225 force certain insns into separate groups or force a certain distance between
24226 them by inserting nops, for example, if there exists a "costly dependence"
24227 between the insns.
24229 The function estimates the group boundaries that the processor will form as
24230 follows: It keeps track of how many vacant issue slots are available after
24231 each insn. A subsequent insn will start a new group if one of the following
24232 4 cases applies:
24233 - no more vacant issue slots remain in the current dispatch group.
24234 - only the last issue slot, which is the branch slot, is vacant, but the next
24235 insn is not a branch.
24236 - only the last 2 or less issue slots, including the branch slot, are vacant,
24237 which means that a cracked insn (which occupies two issue slots) can't be
24238 issued in this group.
24239 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24240 start a new group. */
24242 static int
24243 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24245 rtx insn, next_insn;
24246 int issue_rate;
24247 int can_issue_more;
24248 int slot, i;
24249 bool group_end;
24250 int group_count = 0;
24251 rtx *group_insns;
24253 /* Initialize. */
24254 issue_rate = rs6000_issue_rate ();
24255 group_insns = XALLOCAVEC (rtx, issue_rate);
24256 for (i = 0; i < issue_rate; i++)
24258 group_insns[i] = 0;
24260 can_issue_more = issue_rate;
24261 slot = 0;
24262 insn = get_next_active_insn (prev_head_insn, tail);
24263 group_end = false;
24265 while (insn != NULL_RTX)
24267 slot = (issue_rate - can_issue_more);
24268 group_insns[slot] = insn;
24269 can_issue_more =
24270 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24271 if (insn_terminates_group_p (insn, current_group))
24272 can_issue_more = 0;
24274 next_insn = get_next_active_insn (insn, tail);
24275 if (next_insn == NULL_RTX)
24276 return group_count + 1;
24278 /* Is next_insn going to start a new group? */
24279 group_end
24280 = (can_issue_more == 0
24281 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24282 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24283 || (can_issue_more < issue_rate &&
24284 insn_terminates_group_p (next_insn, previous_group)));
24286 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24287 next_insn, &group_end, can_issue_more,
24288 &group_count);
24290 if (group_end)
24292 group_count++;
24293 can_issue_more = 0;
24294 for (i = 0; i < issue_rate; i++)
24296 group_insns[i] = 0;
24300 if (GET_MODE (next_insn) == TImode && can_issue_more)
24301 PUT_MODE (next_insn, VOIDmode);
24302 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24303 PUT_MODE (next_insn, TImode);
24305 insn = next_insn;
24306 if (can_issue_more == 0)
24307 can_issue_more = issue_rate;
24308 } /* while */
24310 return group_count;
24313 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24314 dispatch group boundaries that the scheduler had marked. Pad with nops
24315 any dispatch groups which have vacant issue slots, in order to force the
24316 scheduler's grouping on the processor dispatcher. The function
24317 returns the number of dispatch groups found. */
24319 static int
24320 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24322 rtx insn, next_insn;
24323 rtx nop;
24324 int issue_rate;
24325 int can_issue_more;
24326 int group_end;
24327 int group_count = 0;
24329 /* Initialize issue_rate. */
24330 issue_rate = rs6000_issue_rate ();
24331 can_issue_more = issue_rate;
24333 insn = get_next_active_insn (prev_head_insn, tail);
24334 next_insn = get_next_active_insn (insn, tail);
24336 while (insn != NULL_RTX)
24338 can_issue_more =
24339 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24341 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24343 if (next_insn == NULL_RTX)
24344 break;
24346 if (group_end)
24348 /* If the scheduler had marked group termination at this location
24349 (between insn and next_insn), and neither insn nor next_insn will
24350 force group termination, pad the group with nops to force group
24351 termination. */
24352 if (can_issue_more
24353 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24354 && !insn_terminates_group_p (insn, current_group)
24355 && !insn_terminates_group_p (next_insn, previous_group))
24357 if (!is_branch_slot_insn (next_insn))
24358 can_issue_more--;
24360 while (can_issue_more)
24362 nop = gen_nop ();
24363 emit_insn_before (nop, next_insn);
24364 can_issue_more--;
24368 can_issue_more = issue_rate;
24369 group_count++;
24372 insn = next_insn;
24373 next_insn = get_next_active_insn (insn, tail);
24376 return group_count;
24379 /* We're beginning a new block. Initialize data structures as necessary. */
24381 static void
24382 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24383 int sched_verbose ATTRIBUTE_UNUSED,
24384 int max_ready ATTRIBUTE_UNUSED)
24386 last_scheduled_insn = NULL_RTX;
24387 load_store_pendulum = 0;
24390 /* The following function is called at the end of scheduling BB.
24391 After reload, it inserts nops at insn group bundling. */
24393 static void
24394 rs6000_sched_finish (FILE *dump, int sched_verbose)
24396 int n_groups;
24398 if (sched_verbose)
24399 fprintf (dump, "=== Finishing schedule.\n");
24401 if (reload_completed && rs6000_sched_groups)
24403 /* Do not run sched_finish hook when selective scheduling enabled. */
24404 if (sel_sched_p ())
24405 return;
24407 if (rs6000_sched_insert_nops == sched_finish_none)
24408 return;
24410 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24411 n_groups = pad_groups (dump, sched_verbose,
24412 current_sched_info->prev_head,
24413 current_sched_info->next_tail);
24414 else
24415 n_groups = redefine_groups (dump, sched_verbose,
24416 current_sched_info->prev_head,
24417 current_sched_info->next_tail);
24419 if (sched_verbose >= 6)
24421 fprintf (dump, "ngroups = %d\n", n_groups);
24422 print_rtl (dump, current_sched_info->prev_head);
24423 fprintf (dump, "Done finish_sched\n");
24428 struct _rs6000_sched_context
24430 short cached_can_issue_more;
24431 rtx last_scheduled_insn;
24432 int load_store_pendulum;
24435 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24436 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24438 /* Allocate store for new scheduling context. */
24439 static void *
24440 rs6000_alloc_sched_context (void)
24442 return xmalloc (sizeof (rs6000_sched_context_def));
24445 /* If CLEAN_P is true then initializes _SC with clean data,
24446 and from the global context otherwise. */
24447 static void
24448 rs6000_init_sched_context (void *_sc, bool clean_p)
24450 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24452 if (clean_p)
24454 sc->cached_can_issue_more = 0;
24455 sc->last_scheduled_insn = NULL_RTX;
24456 sc->load_store_pendulum = 0;
24458 else
24460 sc->cached_can_issue_more = cached_can_issue_more;
24461 sc->last_scheduled_insn = last_scheduled_insn;
24462 sc->load_store_pendulum = load_store_pendulum;
24466 /* Sets the global scheduling context to the one pointed to by _SC. */
24467 static void
24468 rs6000_set_sched_context (void *_sc)
24470 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24472 gcc_assert (sc != NULL);
24474 cached_can_issue_more = sc->cached_can_issue_more;
24475 last_scheduled_insn = sc->last_scheduled_insn;
24476 load_store_pendulum = sc->load_store_pendulum;
24479 /* Free _SC. */
24480 static void
24481 rs6000_free_sched_context (void *_sc)
24483 gcc_assert (_sc != NULL);
24485 free (_sc);
24489 /* Length in units of the trampoline for entering a nested function. */
24492 rs6000_trampoline_size (void)
24494 int ret = 0;
24496 switch (DEFAULT_ABI)
24498 default:
24499 gcc_unreachable ();
24501 case ABI_AIX:
24502 ret = (TARGET_32BIT) ? 12 : 24;
24503 break;
24505 case ABI_DARWIN:
24506 case ABI_V4:
24507 ret = (TARGET_32BIT) ? 40 : 48;
24508 break;
24511 return ret;
24514 /* Emit RTL insns to initialize the variable parts of a trampoline.
24515 FNADDR is an RTX for the address of the function's pure code.
24516 CXT is an RTX for the static chain value for the function. */
24518 static void
24519 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24521 int regsize = (TARGET_32BIT) ? 4 : 8;
24522 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24523 rtx ctx_reg = force_reg (Pmode, cxt);
24524 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24526 switch (DEFAULT_ABI)
24528 default:
24529 gcc_unreachable ();
24531 /* Under AIX, just build the 3 word function descriptor */
24532 case ABI_AIX:
24534 rtx fnmem, fn_reg, toc_reg;
24536 if (!TARGET_POINTERS_TO_NESTED_FUNCTIONS)
24537 error ("-mno-r11 must not be used if you have trampolines");
24539 fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24540 fn_reg = gen_reg_rtx (Pmode);
24541 toc_reg = gen_reg_rtx (Pmode);
24543 /* Macro to shorten the code expansions below. */
24544 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24546 m_tramp = replace_equiv_address (m_tramp, addr);
24548 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24549 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24550 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24551 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24552 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24554 # undef MEM_PLUS
24556 break;
24558 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24559 case ABI_DARWIN:
24560 case ABI_V4:
24561 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24562 LCT_NORMAL, VOIDmode, 4,
24563 addr, Pmode,
24564 GEN_INT (rs6000_trampoline_size ()), SImode,
24565 fnaddr, Pmode,
24566 ctx_reg, Pmode);
24567 break;
24572 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24573 identifier as an argument, so the front end shouldn't look it up. */
24575 static bool
24576 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24578 return is_attribute_p ("altivec", attr_id);
24581 /* Handle the "altivec" attribute. The attribute may have
24582 arguments as follows:
24584 __attribute__((altivec(vector__)))
24585 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24586 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24588 and may appear more than once (e.g., 'vector bool char') in a
24589 given declaration. */
24591 static tree
24592 rs6000_handle_altivec_attribute (tree *node,
24593 tree name ATTRIBUTE_UNUSED,
24594 tree args,
24595 int flags ATTRIBUTE_UNUSED,
24596 bool *no_add_attrs)
24598 tree type = *node, result = NULL_TREE;
24599 enum machine_mode mode;
24600 int unsigned_p;
24601 char altivec_type
24602 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24603 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24604 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24605 : '?');
24607 while (POINTER_TYPE_P (type)
24608 || TREE_CODE (type) == FUNCTION_TYPE
24609 || TREE_CODE (type) == METHOD_TYPE
24610 || TREE_CODE (type) == ARRAY_TYPE)
24611 type = TREE_TYPE (type);
24613 mode = TYPE_MODE (type);
24615 /* Check for invalid AltiVec type qualifiers. */
24616 if (type == long_double_type_node)
24617 error ("use of %<long double%> in AltiVec types is invalid");
24618 else if (type == boolean_type_node)
24619 error ("use of boolean types in AltiVec types is invalid");
24620 else if (TREE_CODE (type) == COMPLEX_TYPE)
24621 error ("use of %<complex%> in AltiVec types is invalid");
24622 else if (DECIMAL_FLOAT_MODE_P (mode))
24623 error ("use of decimal floating point types in AltiVec types is invalid");
24624 else if (!TARGET_VSX)
24626 if (type == long_unsigned_type_node || type == long_integer_type_node)
24628 if (TARGET_64BIT)
24629 error ("use of %<long%> in AltiVec types is invalid for "
24630 "64-bit code without -mvsx");
24631 else if (rs6000_warn_altivec_long)
24632 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24633 "use %<int%>");
24635 else if (type == long_long_unsigned_type_node
24636 || type == long_long_integer_type_node)
24637 error ("use of %<long long%> in AltiVec types is invalid without "
24638 "-mvsx");
24639 else if (type == double_type_node)
24640 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24643 switch (altivec_type)
24645 case 'v':
24646 unsigned_p = TYPE_UNSIGNED (type);
24647 switch (mode)
24649 case DImode:
24650 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24651 break;
24652 case SImode:
24653 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24654 break;
24655 case HImode:
24656 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24657 break;
24658 case QImode:
24659 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24660 break;
24661 case SFmode: result = V4SF_type_node; break;
24662 case DFmode: result = V2DF_type_node; break;
24663 /* If the user says 'vector int bool', we may be handed the 'bool'
24664 attribute _before_ the 'vector' attribute, and so select the
24665 proper type in the 'b' case below. */
24666 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24667 case V2DImode: case V2DFmode:
24668 result = type;
24669 default: break;
24671 break;
24672 case 'b':
24673 switch (mode)
24675 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24676 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24677 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24678 case QImode: case V16QImode: result = bool_V16QI_type_node;
24679 default: break;
24681 break;
24682 case 'p':
24683 switch (mode)
24685 case V8HImode: result = pixel_V8HI_type_node;
24686 default: break;
24688 default: break;
24691 /* Propagate qualifiers attached to the element type
24692 onto the vector type. */
24693 if (result && result != type && TYPE_QUALS (type))
24694 result = build_qualified_type (result, TYPE_QUALS (type));
24696 *no_add_attrs = true; /* No need to hang on to the attribute. */
24698 if (result)
24699 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24701 return NULL_TREE;
24704 /* AltiVec defines four built-in scalar types that serve as vector
24705 elements; we must teach the compiler how to mangle them. */
24707 static const char *
24708 rs6000_mangle_type (const_tree type)
24710 type = TYPE_MAIN_VARIANT (type);
24712 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24713 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24714 return NULL;
24716 if (type == bool_char_type_node) return "U6__boolc";
24717 if (type == bool_short_type_node) return "U6__bools";
24718 if (type == pixel_type_node) return "u7__pixel";
24719 if (type == bool_int_type_node) return "U6__booli";
24720 if (type == bool_long_type_node) return "U6__booll";
24722 /* Mangle IBM extended float long double as `g' (__float128) on
24723 powerpc*-linux where long-double-64 previously was the default. */
24724 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24725 && TARGET_ELF
24726 && TARGET_LONG_DOUBLE_128
24727 && !TARGET_IEEEQUAD)
24728 return "g";
24730 /* For all other types, use normal C++ mangling. */
24731 return NULL;
24734 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24735 struct attribute_spec.handler. */
24737 static tree
24738 rs6000_handle_longcall_attribute (tree *node, tree name,
24739 tree args ATTRIBUTE_UNUSED,
24740 int flags ATTRIBUTE_UNUSED,
24741 bool *no_add_attrs)
24743 if (TREE_CODE (*node) != FUNCTION_TYPE
24744 && TREE_CODE (*node) != FIELD_DECL
24745 && TREE_CODE (*node) != TYPE_DECL)
24747 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24748 name);
24749 *no_add_attrs = true;
24752 return NULL_TREE;
24755 /* Set longcall attributes on all functions declared when
24756 rs6000_default_long_calls is true. */
24757 static void
24758 rs6000_set_default_type_attributes (tree type)
24760 if (rs6000_default_long_calls
24761 && (TREE_CODE (type) == FUNCTION_TYPE
24762 || TREE_CODE (type) == METHOD_TYPE))
24763 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24764 NULL_TREE,
24765 TYPE_ATTRIBUTES (type));
24767 #if TARGET_MACHO
24768 darwin_set_default_type_attributes (type);
24769 #endif
24772 /* Return a reference suitable for calling a function with the
24773 longcall attribute. */
24776 rs6000_longcall_ref (rtx call_ref)
24778 const char *call_name;
24779 tree node;
24781 if (GET_CODE (call_ref) != SYMBOL_REF)
24782 return call_ref;
24784 /* System V adds '.' to the internal name, so skip them. */
24785 call_name = XSTR (call_ref, 0);
24786 if (*call_name == '.')
24788 while (*call_name == '.')
24789 call_name++;
24791 node = get_identifier (call_name);
24792 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24795 return force_reg (Pmode, call_ref);
24798 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24799 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24800 #endif
24802 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24803 struct attribute_spec.handler. */
24804 static tree
24805 rs6000_handle_struct_attribute (tree *node, tree name,
24806 tree args ATTRIBUTE_UNUSED,
24807 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24809 tree *type = NULL;
24810 if (DECL_P (*node))
24812 if (TREE_CODE (*node) == TYPE_DECL)
24813 type = &TREE_TYPE (*node);
24815 else
24816 type = node;
24818 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24819 || TREE_CODE (*type) == UNION_TYPE)))
24821 warning (OPT_Wattributes, "%qE attribute ignored", name);
24822 *no_add_attrs = true;
24825 else if ((is_attribute_p ("ms_struct", name)
24826 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24827 || ((is_attribute_p ("gcc_struct", name)
24828 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24830 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24831 name);
24832 *no_add_attrs = true;
24835 return NULL_TREE;
24838 static bool
24839 rs6000_ms_bitfield_layout_p (const_tree record_type)
24841 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24842 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24843 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24846 #ifdef USING_ELFOS_H
24848 /* A get_unnamed_section callback, used for switching to toc_section. */
24850 static void
24851 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24853 if (DEFAULT_ABI == ABI_AIX
24854 && TARGET_MINIMAL_TOC
24855 && !TARGET_RELOCATABLE)
24857 if (!toc_initialized)
24859 toc_initialized = 1;
24860 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24861 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24862 fprintf (asm_out_file, "\t.tc ");
24863 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24864 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24865 fprintf (asm_out_file, "\n");
24867 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24868 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24869 fprintf (asm_out_file, " = .+32768\n");
24871 else
24872 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24874 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24875 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24876 else
24878 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24879 if (!toc_initialized)
24881 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24882 fprintf (asm_out_file, " = .+32768\n");
24883 toc_initialized = 1;
24888 /* Implement TARGET_ASM_INIT_SECTIONS. */
24890 static void
24891 rs6000_elf_asm_init_sections (void)
24893 toc_section
24894 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24896 sdata2_section
24897 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24898 SDATA2_SECTION_ASM_OP);
24901 /* Implement TARGET_SELECT_RTX_SECTION. */
24903 static section *
24904 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24905 unsigned HOST_WIDE_INT align)
24907 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24908 return toc_section;
24909 else
24910 return default_elf_select_rtx_section (mode, x, align);
24913 /* For a SYMBOL_REF, set generic flags and then perform some
24914 target-specific processing.
24916 When the AIX ABI is requested on a non-AIX system, replace the
24917 function name with the real name (with a leading .) rather than the
24918 function descriptor name. This saves a lot of overriding code to
24919 read the prefixes. */
24921 static void
24922 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24924 default_encode_section_info (decl, rtl, first);
24926 if (first
24927 && TREE_CODE (decl) == FUNCTION_DECL
24928 && !TARGET_AIX
24929 && DEFAULT_ABI == ABI_AIX)
24931 rtx sym_ref = XEXP (rtl, 0);
24932 size_t len = strlen (XSTR (sym_ref, 0));
24933 char *str = XALLOCAVEC (char, len + 2);
24934 str[0] = '.';
24935 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24936 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24940 static inline bool
24941 compare_section_name (const char *section, const char *templ)
24943 int len;
24945 len = strlen (templ);
24946 return (strncmp (section, templ, len) == 0
24947 && (section[len] == 0 || section[len] == '.'));
24950 bool
24951 rs6000_elf_in_small_data_p (const_tree decl)
24953 if (rs6000_sdata == SDATA_NONE)
24954 return false;
24956 /* We want to merge strings, so we never consider them small data. */
24957 if (TREE_CODE (decl) == STRING_CST)
24958 return false;
24960 /* Functions are never in the small data area. */
24961 if (TREE_CODE (decl) == FUNCTION_DECL)
24962 return false;
24964 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24966 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24967 if (compare_section_name (section, ".sdata")
24968 || compare_section_name (section, ".sdata2")
24969 || compare_section_name (section, ".gnu.linkonce.s")
24970 || compare_section_name (section, ".sbss")
24971 || compare_section_name (section, ".sbss2")
24972 || compare_section_name (section, ".gnu.linkonce.sb")
24973 || strcmp (section, ".PPC.EMB.sdata0") == 0
24974 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24975 return true;
24977 else
24979 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24981 if (size > 0
24982 && size <= g_switch_value
24983 /* If it's not public, and we're not going to reference it there,
24984 there's no need to put it in the small data section. */
24985 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24986 return true;
24989 return false;
24992 #endif /* USING_ELFOS_H */
24994 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24996 static bool
24997 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24999 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25002 /* Return a REG that occurs in ADDR with coefficient 1.
25003 ADDR can be effectively incremented by incrementing REG.
25005 r0 is special and we must not select it as an address
25006 register by this routine since our caller will try to
25007 increment the returned register via an "la" instruction. */
25010 find_addr_reg (rtx addr)
25012 while (GET_CODE (addr) == PLUS)
25014 if (GET_CODE (XEXP (addr, 0)) == REG
25015 && REGNO (XEXP (addr, 0)) != 0)
25016 addr = XEXP (addr, 0);
25017 else if (GET_CODE (XEXP (addr, 1)) == REG
25018 && REGNO (XEXP (addr, 1)) != 0)
25019 addr = XEXP (addr, 1);
25020 else if (CONSTANT_P (XEXP (addr, 0)))
25021 addr = XEXP (addr, 1);
25022 else if (CONSTANT_P (XEXP (addr, 1)))
25023 addr = XEXP (addr, 0);
25024 else
25025 gcc_unreachable ();
25027 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25028 return addr;
25031 void
25032 rs6000_fatal_bad_address (rtx op)
25034 fatal_insn ("bad address", op);
25037 #if TARGET_MACHO
25039 typedef struct branch_island_d {
25040 tree function_name;
25041 tree label_name;
25042 int line_number;
25043 } branch_island;
25045 DEF_VEC_O(branch_island);
25046 DEF_VEC_ALLOC_O(branch_island,gc);
25048 static VEC(branch_island,gc) *branch_islands;
25050 /* Remember to generate a branch island for far calls to the given
25051 function. */
25053 static void
25054 add_compiler_branch_island (tree label_name, tree function_name,
25055 int line_number)
25057 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25059 bi->function_name = function_name;
25060 bi->label_name = label_name;
25061 bi->line_number = line_number;
25064 /* Generate far-jump branch islands for everything recorded in
25065 branch_islands. Invoked immediately after the last instruction of
25066 the epilogue has been emitted; the branch islands must be appended
25067 to, and contiguous with, the function body. Mach-O stubs are
25068 generated in machopic_output_stub(). */
25070 static void
25071 macho_branch_islands (void)
25073 char tmp_buf[512];
25075 while (!VEC_empty (branch_island, branch_islands))
25077 branch_island *bi = VEC_last (branch_island, branch_islands);
25078 const char *label = IDENTIFIER_POINTER (bi->label_name);
25079 const char *name = IDENTIFIER_POINTER (bi->function_name);
25080 char name_buf[512];
25081 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25082 if (name[0] == '*' || name[0] == '&')
25083 strcpy (name_buf, name+1);
25084 else
25086 name_buf[0] = '_';
25087 strcpy (name_buf+1, name);
25089 strcpy (tmp_buf, "\n");
25090 strcat (tmp_buf, label);
25091 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25092 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25093 dbxout_stabd (N_SLINE, bi->line_number);
25094 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25095 if (flag_pic)
25097 if (TARGET_LINK_STACK)
25099 char name[32];
25100 get_ppc476_thunk_name (name);
25101 strcat (tmp_buf, ":\n\tmflr r0\n\tbl ");
25102 strcat (tmp_buf, name);
25103 strcat (tmp_buf, "\n");
25104 strcat (tmp_buf, label);
25105 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25107 else
25109 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25110 strcat (tmp_buf, label);
25111 strcat (tmp_buf, "_pic\n");
25112 strcat (tmp_buf, label);
25113 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25116 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25117 strcat (tmp_buf, name_buf);
25118 strcat (tmp_buf, " - ");
25119 strcat (tmp_buf, label);
25120 strcat (tmp_buf, "_pic)\n");
25122 strcat (tmp_buf, "\tmtlr r0\n");
25124 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25125 strcat (tmp_buf, name_buf);
25126 strcat (tmp_buf, " - ");
25127 strcat (tmp_buf, label);
25128 strcat (tmp_buf, "_pic)\n");
25130 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25132 else
25134 strcat (tmp_buf, ":\nlis r12,hi16(");
25135 strcat (tmp_buf, name_buf);
25136 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25137 strcat (tmp_buf, name_buf);
25138 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25140 output_asm_insn (tmp_buf, 0);
25141 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25142 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25143 dbxout_stabd (N_SLINE, bi->line_number);
25144 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25145 VEC_pop (branch_island, branch_islands);
25149 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25150 already there or not. */
25152 static int
25153 no_previous_def (tree function_name)
25155 branch_island *bi;
25156 unsigned ix;
25158 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25159 if (function_name == bi->function_name)
25160 return 0;
25161 return 1;
25164 /* GET_PREV_LABEL gets the label name from the previous definition of
25165 the function. */
25167 static tree
25168 get_prev_label (tree function_name)
25170 branch_island *bi;
25171 unsigned ix;
25173 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25174 if (function_name == bi->function_name)
25175 return bi->label_name;
25176 return NULL_TREE;
25179 /* INSN is either a function call or a millicode call. It may have an
25180 unconditional jump in its delay slot.
25182 CALL_DEST is the routine we are calling. */
25184 char *
25185 output_call (rtx insn, rtx *operands, int dest_operand_number,
25186 int cookie_operand_number)
25188 static char buf[256];
25189 if (darwin_emit_branch_islands
25190 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25191 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25193 tree labelname;
25194 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25196 if (no_previous_def (funname))
25198 rtx label_rtx = gen_label_rtx ();
25199 char *label_buf, temp_buf[256];
25200 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25201 CODE_LABEL_NUMBER (label_rtx));
25202 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25203 labelname = get_identifier (label_buf);
25204 add_compiler_branch_island (labelname, funname, insn_line (insn));
25206 else
25207 labelname = get_prev_label (funname);
25209 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25210 instruction will reach 'foo', otherwise link as 'bl L42'".
25211 "L42" should be a 'branch island', that will do a far jump to
25212 'foo'. Branch islands are generated in
25213 macho_branch_islands(). */
25214 sprintf (buf, "jbsr %%z%d,%.246s",
25215 dest_operand_number, IDENTIFIER_POINTER (labelname));
25217 else
25218 sprintf (buf, "bl %%z%d", dest_operand_number);
25219 return buf;
25222 /* Generate PIC and indirect symbol stubs. */
25224 void
25225 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25227 unsigned int length;
25228 char *symbol_name, *lazy_ptr_name;
25229 char *local_label_0;
25230 static int label = 0;
25232 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25233 symb = (*targetm.strip_name_encoding) (symb);
25236 length = strlen (symb);
25237 symbol_name = XALLOCAVEC (char, length + 32);
25238 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25240 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25241 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25243 if (flag_pic == 2)
25244 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25245 else
25246 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25248 if (flag_pic == 2)
25250 fprintf (file, "\t.align 5\n");
25252 fprintf (file, "%s:\n", stub);
25253 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25255 label++;
25256 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25257 sprintf (local_label_0, "\"L%011d$spb\"", label);
25259 fprintf (file, "\tmflr r0\n");
25260 if (TARGET_LINK_STACK)
25262 char name[32];
25263 get_ppc476_thunk_name (name);
25264 fprintf (file, "\tbl %s\n", name);
25265 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25267 else
25269 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25270 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25272 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25273 lazy_ptr_name, local_label_0);
25274 fprintf (file, "\tmtlr r0\n");
25275 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25276 (TARGET_64BIT ? "ldu" : "lwzu"),
25277 lazy_ptr_name, local_label_0);
25278 fprintf (file, "\tmtctr r12\n");
25279 fprintf (file, "\tbctr\n");
25281 else
25283 fprintf (file, "\t.align 4\n");
25285 fprintf (file, "%s:\n", stub);
25286 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25288 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25289 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25290 (TARGET_64BIT ? "ldu" : "lwzu"),
25291 lazy_ptr_name);
25292 fprintf (file, "\tmtctr r12\n");
25293 fprintf (file, "\tbctr\n");
25296 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25297 fprintf (file, "%s:\n", lazy_ptr_name);
25298 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25299 fprintf (file, "%sdyld_stub_binding_helper\n",
25300 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25303 /* Legitimize PIC addresses. If the address is already
25304 position-independent, we return ORIG. Newly generated
25305 position-independent addresses go into a reg. This is REG if non
25306 zero, otherwise we allocate register(s) as necessary. */
25308 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25311 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25312 rtx reg)
25314 rtx base, offset;
25316 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25317 reg = gen_reg_rtx (Pmode);
25319 if (GET_CODE (orig) == CONST)
25321 rtx reg_temp;
25323 if (GET_CODE (XEXP (orig, 0)) == PLUS
25324 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25325 return orig;
25327 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25329 /* Use a different reg for the intermediate value, as
25330 it will be marked UNCHANGING. */
25331 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25332 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25333 Pmode, reg_temp);
25334 offset =
25335 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25336 Pmode, reg);
25338 if (GET_CODE (offset) == CONST_INT)
25340 if (SMALL_INT (offset))
25341 return plus_constant (base, INTVAL (offset));
25342 else if (! reload_in_progress && ! reload_completed)
25343 offset = force_reg (Pmode, offset);
25344 else
25346 rtx mem = force_const_mem (Pmode, orig);
25347 return machopic_legitimize_pic_address (mem, Pmode, reg);
25350 return gen_rtx_PLUS (Pmode, base, offset);
25353 /* Fall back on generic machopic code. */
25354 return machopic_legitimize_pic_address (orig, mode, reg);
25357 /* Output a .machine directive for the Darwin assembler, and call
25358 the generic start_file routine. */
25360 static void
25361 rs6000_darwin_file_start (void)
25363 static const struct
25365 const char *arg;
25366 const char *name;
25367 int if_set;
25368 } mapping[] = {
25369 { "ppc64", "ppc64", MASK_64BIT },
25370 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25371 { "power4", "ppc970", 0 },
25372 { "G5", "ppc970", 0 },
25373 { "7450", "ppc7450", 0 },
25374 { "7400", "ppc7400", MASK_ALTIVEC },
25375 { "G4", "ppc7400", 0 },
25376 { "750", "ppc750", 0 },
25377 { "740", "ppc750", 0 },
25378 { "G3", "ppc750", 0 },
25379 { "604e", "ppc604e", 0 },
25380 { "604", "ppc604", 0 },
25381 { "603e", "ppc603", 0 },
25382 { "603", "ppc603", 0 },
25383 { "601", "ppc601", 0 },
25384 { NULL, "ppc", 0 } };
25385 const char *cpu_id = "";
25386 size_t i;
25388 rs6000_file_start ();
25389 darwin_file_start ();
25391 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25393 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
25394 cpu_id = rs6000_default_cpu;
25396 if (global_options_set.x_rs6000_cpu_index)
25397 cpu_id = processor_target_table[rs6000_cpu_index].name;
25399 /* Look through the mapping array. Pick the first name that either
25400 matches the argument, has a bit set in IF_SET that is also set
25401 in the target flags, or has a NULL name. */
25403 i = 0;
25404 while (mapping[i].arg != NULL
25405 && strcmp (mapping[i].arg, cpu_id) != 0
25406 && (mapping[i].if_set & target_flags) == 0)
25407 i++;
25409 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25412 #endif /* TARGET_MACHO */
25414 #if TARGET_ELF
25415 static int
25416 rs6000_elf_reloc_rw_mask (void)
25418 if (flag_pic)
25419 return 3;
25420 else if (DEFAULT_ABI == ABI_AIX)
25421 return 2;
25422 else
25423 return 0;
25426 /* Record an element in the table of global constructors. SYMBOL is
25427 a SYMBOL_REF of the function to be called; PRIORITY is a number
25428 between 0 and MAX_INIT_PRIORITY.
25430 This differs from default_named_section_asm_out_constructor in
25431 that we have special handling for -mrelocatable. */
25433 static void
25434 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25436 const char *section = ".ctors";
25437 char buf[16];
25439 if (priority != DEFAULT_INIT_PRIORITY)
25441 sprintf (buf, ".ctors.%.5u",
25442 /* Invert the numbering so the linker puts us in the proper
25443 order; constructors are run from right to left, and the
25444 linker sorts in increasing order. */
25445 MAX_INIT_PRIORITY - priority);
25446 section = buf;
25449 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25450 assemble_align (POINTER_SIZE);
25452 if (TARGET_RELOCATABLE)
25454 fputs ("\t.long (", asm_out_file);
25455 output_addr_const (asm_out_file, symbol);
25456 fputs (")@fixup\n", asm_out_file);
25458 else
25459 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25462 static void
25463 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25465 const char *section = ".dtors";
25466 char buf[16];
25468 if (priority != DEFAULT_INIT_PRIORITY)
25470 sprintf (buf, ".dtors.%.5u",
25471 /* Invert the numbering so the linker puts us in the proper
25472 order; constructors are run from right to left, and the
25473 linker sorts in increasing order. */
25474 MAX_INIT_PRIORITY - priority);
25475 section = buf;
25478 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25479 assemble_align (POINTER_SIZE);
25481 if (TARGET_RELOCATABLE)
25483 fputs ("\t.long (", asm_out_file);
25484 output_addr_const (asm_out_file, symbol);
25485 fputs (")@fixup\n", asm_out_file);
25487 else
25488 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25491 void
25492 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25494 if (TARGET_64BIT)
25496 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25497 ASM_OUTPUT_LABEL (file, name);
25498 fputs (DOUBLE_INT_ASM_OP, file);
25499 rs6000_output_function_entry (file, name);
25500 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25501 if (DOT_SYMBOLS)
25503 fputs ("\t.size\t", file);
25504 assemble_name (file, name);
25505 fputs (",24\n\t.type\t.", file);
25506 assemble_name (file, name);
25507 fputs (",@function\n", file);
25508 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25510 fputs ("\t.globl\t.", file);
25511 assemble_name (file, name);
25512 putc ('\n', file);
25515 else
25516 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25517 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25518 rs6000_output_function_entry (file, name);
25519 fputs (":\n", file);
25520 return;
25523 if (TARGET_RELOCATABLE
25524 && !TARGET_SECURE_PLT
25525 && (get_pool_size () != 0 || crtl->profile)
25526 && uses_TOC ())
25528 char buf[256];
25530 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25532 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25533 fprintf (file, "\t.long ");
25534 assemble_name (file, buf);
25535 putc ('-', file);
25536 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25537 assemble_name (file, buf);
25538 putc ('\n', file);
25541 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25542 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25544 if (DEFAULT_ABI == ABI_AIX)
25546 const char *desc_name, *orig_name;
25548 orig_name = (*targetm.strip_name_encoding) (name);
25549 desc_name = orig_name;
25550 while (*desc_name == '.')
25551 desc_name++;
25553 if (TREE_PUBLIC (decl))
25554 fprintf (file, "\t.globl %s\n", desc_name);
25556 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25557 fprintf (file, "%s:\n", desc_name);
25558 fprintf (file, "\t.long %s\n", orig_name);
25559 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25560 if (DEFAULT_ABI == ABI_AIX)
25561 fputs ("\t.long 0\n", file);
25562 fprintf (file, "\t.previous\n");
25564 ASM_OUTPUT_LABEL (file, name);
25567 static void
25568 rs6000_elf_file_end (void)
25570 #ifdef HAVE_AS_GNU_ATTRIBUTE
25571 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25573 if (rs6000_passes_float)
25574 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25575 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25576 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25577 : 2));
25578 if (rs6000_passes_vector)
25579 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25580 (TARGET_ALTIVEC_ABI ? 2
25581 : TARGET_SPE_ABI ? 3
25582 : 1));
25583 if (rs6000_returns_struct)
25584 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25585 aix_struct_return ? 2 : 1);
25587 #endif
25588 #ifdef POWERPC_LINUX
25589 if (TARGET_32BIT)
25590 file_end_indicate_exec_stack ();
25591 #endif
25593 #endif
25595 #if TARGET_XCOFF
25596 static void
25597 rs6000_xcoff_asm_output_anchor (rtx symbol)
25599 char buffer[100];
25601 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25602 SYMBOL_REF_BLOCK_OFFSET (symbol));
25603 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25606 static void
25607 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25609 fputs (GLOBAL_ASM_OP, stream);
25610 RS6000_OUTPUT_BASENAME (stream, name);
25611 putc ('\n', stream);
25614 /* A get_unnamed_decl callback, used for read-only sections. PTR
25615 points to the section string variable. */
25617 static void
25618 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25620 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25621 *(const char *const *) directive,
25622 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25625 /* Likewise for read-write sections. */
25627 static void
25628 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25630 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25631 *(const char *const *) directive,
25632 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25635 /* A get_unnamed_section callback, used for switching to toc_section. */
25637 static void
25638 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25640 if (TARGET_MINIMAL_TOC)
25642 /* toc_section is always selected at least once from
25643 rs6000_xcoff_file_start, so this is guaranteed to
25644 always be defined once and only once in each file. */
25645 if (!toc_initialized)
25647 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25648 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25649 toc_initialized = 1;
25651 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25652 (TARGET_32BIT ? "" : ",3"));
25654 else
25655 fputs ("\t.toc\n", asm_out_file);
25658 /* Implement TARGET_ASM_INIT_SECTIONS. */
25660 static void
25661 rs6000_xcoff_asm_init_sections (void)
25663 read_only_data_section
25664 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25665 &xcoff_read_only_section_name);
25667 private_data_section
25668 = get_unnamed_section (SECTION_WRITE,
25669 rs6000_xcoff_output_readwrite_section_asm_op,
25670 &xcoff_private_data_section_name);
25672 read_only_private_data_section
25673 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25674 &xcoff_private_data_section_name);
25676 toc_section
25677 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25679 readonly_data_section = read_only_data_section;
25680 exception_section = data_section;
25683 static int
25684 rs6000_xcoff_reloc_rw_mask (void)
25686 return 3;
25689 static void
25690 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25691 tree decl ATTRIBUTE_UNUSED)
25693 int smclass;
25694 static const char * const suffix[3] = { "PR", "RO", "RW" };
25696 if (flags & SECTION_CODE)
25697 smclass = 0;
25698 else if (flags & SECTION_WRITE)
25699 smclass = 2;
25700 else
25701 smclass = 1;
25703 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25704 (flags & SECTION_CODE) ? "." : "",
25705 name, suffix[smclass], flags & SECTION_ENTSIZE);
25708 static section *
25709 rs6000_xcoff_select_section (tree decl, int reloc,
25710 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25712 if (decl_readonly_section (decl, reloc))
25714 if (TREE_PUBLIC (decl))
25715 return read_only_data_section;
25716 else
25717 return read_only_private_data_section;
25719 else
25721 if (TREE_PUBLIC (decl))
25722 return data_section;
25723 else
25724 return private_data_section;
25728 static void
25729 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25731 const char *name;
25733 /* Use select_section for private and uninitialized data. */
25734 if (!TREE_PUBLIC (decl)
25735 || DECL_COMMON (decl)
25736 || DECL_INITIAL (decl) == NULL_TREE
25737 || DECL_INITIAL (decl) == error_mark_node
25738 || (flag_zero_initialized_in_bss
25739 && initializer_zerop (DECL_INITIAL (decl))))
25740 return;
25742 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25743 name = (*targetm.strip_name_encoding) (name);
25744 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25747 /* Select section for constant in constant pool.
25749 On RS/6000, all constants are in the private read-only data area.
25750 However, if this is being placed in the TOC it must be output as a
25751 toc entry. */
25753 static section *
25754 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25755 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25757 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25758 return toc_section;
25759 else
25760 return read_only_private_data_section;
25763 /* Remove any trailing [DS] or the like from the symbol name. */
25765 static const char *
25766 rs6000_xcoff_strip_name_encoding (const char *name)
25768 size_t len;
25769 if (*name == '*')
25770 name++;
25771 len = strlen (name);
25772 if (name[len - 1] == ']')
25773 return ggc_alloc_string (name, len - 4);
25774 else
25775 return name;
25778 /* Section attributes. AIX is always PIC. */
25780 static unsigned int
25781 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25783 unsigned int align;
25784 unsigned int flags = default_section_type_flags (decl, name, reloc);
25786 /* Align to at least UNIT size. */
25787 if (flags & SECTION_CODE || !decl)
25788 align = MIN_UNITS_PER_WORD;
25789 else
25790 /* Increase alignment of large objects if not already stricter. */
25791 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25792 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25793 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25795 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25798 /* Output at beginning of assembler file.
25800 Initialize the section names for the RS/6000 at this point.
25802 Specify filename, including full path, to assembler.
25804 We want to go into the TOC section so at least one .toc will be emitted.
25805 Also, in order to output proper .bs/.es pairs, we need at least one static
25806 [RW] section emitted.
25808 Finally, declare mcount when profiling to make the assembler happy. */
25810 static void
25811 rs6000_xcoff_file_start (void)
25813 rs6000_gen_section_name (&xcoff_bss_section_name,
25814 main_input_filename, ".bss_");
25815 rs6000_gen_section_name (&xcoff_private_data_section_name,
25816 main_input_filename, ".rw_");
25817 rs6000_gen_section_name (&xcoff_read_only_section_name,
25818 main_input_filename, ".ro_");
25820 fputs ("\t.file\t", asm_out_file);
25821 output_quoted_string (asm_out_file, main_input_filename);
25822 fputc ('\n', asm_out_file);
25823 if (write_symbols != NO_DEBUG)
25824 switch_to_section (private_data_section);
25825 switch_to_section (text_section);
25826 if (profile_flag)
25827 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25828 rs6000_file_start ();
25831 /* Output at end of assembler file.
25832 On the RS/6000, referencing data should automatically pull in text. */
25834 static void
25835 rs6000_xcoff_file_end (void)
25837 switch_to_section (text_section);
25838 fputs ("_section_.text:\n", asm_out_file);
25839 switch_to_section (data_section);
25840 fputs (TARGET_32BIT
25841 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25842 asm_out_file);
25844 #endif /* TARGET_XCOFF */
25846 /* Compute a (partial) cost for rtx X. Return true if the complete
25847 cost has been computed, and false if subexpressions should be
25848 scanned. In either case, *TOTAL contains the cost result. */
25850 static bool
25851 rs6000_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
25852 int *total, bool speed)
25854 enum machine_mode mode = GET_MODE (x);
25856 switch (code)
25858 /* On the RS/6000, if it is valid in the insn, it is free. */
25859 case CONST_INT:
25860 if (((outer_code == SET
25861 || outer_code == PLUS
25862 || outer_code == MINUS)
25863 && (satisfies_constraint_I (x)
25864 || satisfies_constraint_L (x)))
25865 || (outer_code == AND
25866 && (satisfies_constraint_K (x)
25867 || (mode == SImode
25868 ? satisfies_constraint_L (x)
25869 : satisfies_constraint_J (x))
25870 || mask_operand (x, mode)
25871 || (mode == DImode
25872 && mask64_operand (x, DImode))))
25873 || ((outer_code == IOR || outer_code == XOR)
25874 && (satisfies_constraint_K (x)
25875 || (mode == SImode
25876 ? satisfies_constraint_L (x)
25877 : satisfies_constraint_J (x))))
25878 || outer_code == ASHIFT
25879 || outer_code == ASHIFTRT
25880 || outer_code == LSHIFTRT
25881 || outer_code == ROTATE
25882 || outer_code == ROTATERT
25883 || outer_code == ZERO_EXTRACT
25884 || (outer_code == MULT
25885 && satisfies_constraint_I (x))
25886 || ((outer_code == DIV || outer_code == UDIV
25887 || outer_code == MOD || outer_code == UMOD)
25888 && exact_log2 (INTVAL (x)) >= 0)
25889 || (outer_code == COMPARE
25890 && (satisfies_constraint_I (x)
25891 || satisfies_constraint_K (x)))
25892 || ((outer_code == EQ || outer_code == NE)
25893 && (satisfies_constraint_I (x)
25894 || satisfies_constraint_K (x)
25895 || (mode == SImode
25896 ? satisfies_constraint_L (x)
25897 : satisfies_constraint_J (x))))
25898 || (outer_code == GTU
25899 && satisfies_constraint_I (x))
25900 || (outer_code == LTU
25901 && satisfies_constraint_P (x)))
25903 *total = 0;
25904 return true;
25906 else if ((outer_code == PLUS
25907 && reg_or_add_cint_operand (x, VOIDmode))
25908 || (outer_code == MINUS
25909 && reg_or_sub_cint_operand (x, VOIDmode))
25910 || ((outer_code == SET
25911 || outer_code == IOR
25912 || outer_code == XOR)
25913 && (INTVAL (x)
25914 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25916 *total = COSTS_N_INSNS (1);
25917 return true;
25919 /* FALLTHRU */
25921 case CONST_DOUBLE:
25922 if (mode == DImode && code == CONST_DOUBLE)
25924 if ((outer_code == IOR || outer_code == XOR)
25925 && CONST_DOUBLE_HIGH (x) == 0
25926 && (CONST_DOUBLE_LOW (x)
25927 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25929 *total = 0;
25930 return true;
25932 else if ((outer_code == AND && and64_2_operand (x, DImode))
25933 || ((outer_code == SET
25934 || outer_code == IOR
25935 || outer_code == XOR)
25936 && CONST_DOUBLE_HIGH (x) == 0))
25938 *total = COSTS_N_INSNS (1);
25939 return true;
25942 /* FALLTHRU */
25944 case CONST:
25945 case HIGH:
25946 case SYMBOL_REF:
25947 case MEM:
25948 /* When optimizing for size, MEM should be slightly more expensive
25949 than generating address, e.g., (plus (reg) (const)).
25950 L1 cache latency is about two instructions. */
25951 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25952 return true;
25954 case LABEL_REF:
25955 *total = 0;
25956 return true;
25958 case PLUS:
25959 case MINUS:
25960 if (FLOAT_MODE_P (mode))
25961 *total = rs6000_cost->fp;
25962 else
25963 *total = COSTS_N_INSNS (1);
25964 return false;
25966 case MULT:
25967 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25968 && satisfies_constraint_I (XEXP (x, 1)))
25970 if (INTVAL (XEXP (x, 1)) >= -256
25971 && INTVAL (XEXP (x, 1)) <= 255)
25972 *total = rs6000_cost->mulsi_const9;
25973 else
25974 *total = rs6000_cost->mulsi_const;
25976 else if (mode == SFmode)
25977 *total = rs6000_cost->fp;
25978 else if (FLOAT_MODE_P (mode))
25979 *total = rs6000_cost->dmul;
25980 else if (mode == DImode)
25981 *total = rs6000_cost->muldi;
25982 else
25983 *total = rs6000_cost->mulsi;
25984 return false;
25986 case FMA:
25987 if (mode == SFmode)
25988 *total = rs6000_cost->fp;
25989 else
25990 *total = rs6000_cost->dmul;
25991 break;
25993 case DIV:
25994 case MOD:
25995 if (FLOAT_MODE_P (mode))
25997 *total = mode == DFmode ? rs6000_cost->ddiv
25998 : rs6000_cost->sdiv;
25999 return false;
26001 /* FALLTHRU */
26003 case UDIV:
26004 case UMOD:
26005 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26006 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26008 if (code == DIV || code == MOD)
26009 /* Shift, addze */
26010 *total = COSTS_N_INSNS (2);
26011 else
26012 /* Shift */
26013 *total = COSTS_N_INSNS (1);
26015 else
26017 if (GET_MODE (XEXP (x, 1)) == DImode)
26018 *total = rs6000_cost->divdi;
26019 else
26020 *total = rs6000_cost->divsi;
26022 /* Add in shift and subtract for MOD. */
26023 if (code == MOD || code == UMOD)
26024 *total += COSTS_N_INSNS (2);
26025 return false;
26027 case CTZ:
26028 case FFS:
26029 *total = COSTS_N_INSNS (4);
26030 return false;
26032 case POPCOUNT:
26033 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26034 return false;
26036 case PARITY:
26037 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26038 return false;
26040 case NOT:
26041 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26043 *total = 0;
26044 return false;
26046 /* FALLTHRU */
26048 case AND:
26049 case CLZ:
26050 case IOR:
26051 case XOR:
26052 case ZERO_EXTRACT:
26053 *total = COSTS_N_INSNS (1);
26054 return false;
26056 case ASHIFT:
26057 case ASHIFTRT:
26058 case LSHIFTRT:
26059 case ROTATE:
26060 case ROTATERT:
26061 /* Handle mul_highpart. */
26062 if (outer_code == TRUNCATE
26063 && GET_CODE (XEXP (x, 0)) == MULT)
26065 if (mode == DImode)
26066 *total = rs6000_cost->muldi;
26067 else
26068 *total = rs6000_cost->mulsi;
26069 return true;
26071 else if (outer_code == AND)
26072 *total = 0;
26073 else
26074 *total = COSTS_N_INSNS (1);
26075 return false;
26077 case SIGN_EXTEND:
26078 case ZERO_EXTEND:
26079 if (GET_CODE (XEXP (x, 0)) == MEM)
26080 *total = 0;
26081 else
26082 *total = COSTS_N_INSNS (1);
26083 return false;
26085 case COMPARE:
26086 case NEG:
26087 case ABS:
26088 if (!FLOAT_MODE_P (mode))
26090 *total = COSTS_N_INSNS (1);
26091 return false;
26093 /* FALLTHRU */
26095 case FLOAT:
26096 case UNSIGNED_FLOAT:
26097 case FIX:
26098 case UNSIGNED_FIX:
26099 case FLOAT_TRUNCATE:
26100 *total = rs6000_cost->fp;
26101 return false;
26103 case FLOAT_EXTEND:
26104 if (mode == DFmode)
26105 *total = 0;
26106 else
26107 *total = rs6000_cost->fp;
26108 return false;
26110 case UNSPEC:
26111 switch (XINT (x, 1))
26113 case UNSPEC_FRSP:
26114 *total = rs6000_cost->fp;
26115 return true;
26117 default:
26118 break;
26120 break;
26122 case CALL:
26123 case IF_THEN_ELSE:
26124 if (!speed)
26126 *total = COSTS_N_INSNS (1);
26127 return true;
26129 else if (FLOAT_MODE_P (mode)
26130 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26132 *total = rs6000_cost->fp;
26133 return false;
26135 break;
26137 case EQ:
26138 case GTU:
26139 case LTU:
26140 /* Carry bit requires mode == Pmode.
26141 NEG or PLUS already counted so only add one. */
26142 if (mode == Pmode
26143 && (outer_code == NEG || outer_code == PLUS))
26145 *total = COSTS_N_INSNS (1);
26146 return true;
26148 if (outer_code == SET)
26150 if (XEXP (x, 1) == const0_rtx)
26152 if (TARGET_ISEL && !TARGET_MFCRF)
26153 *total = COSTS_N_INSNS (8);
26154 else
26155 *total = COSTS_N_INSNS (2);
26156 return true;
26158 else if (mode == Pmode)
26160 *total = COSTS_N_INSNS (3);
26161 return false;
26164 /* FALLTHRU */
26166 case GT:
26167 case LT:
26168 case UNORDERED:
26169 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26171 if (TARGET_ISEL && !TARGET_MFCRF)
26172 *total = COSTS_N_INSNS (8);
26173 else
26174 *total = COSTS_N_INSNS (2);
26175 return true;
26177 /* CC COMPARE. */
26178 if (outer_code == COMPARE)
26180 *total = 0;
26181 return true;
26183 break;
26185 default:
26186 break;
26189 return false;
26192 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26194 static bool
26195 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
26196 bool speed)
26198 bool ret = rs6000_rtx_costs (x, code, outer_code, opno, total, speed);
26200 fprintf (stderr,
26201 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26202 "opno = %d, total = %d, speed = %s, x:\n",
26203 ret ? "complete" : "scan inner",
26204 GET_RTX_NAME (code),
26205 GET_RTX_NAME (outer_code),
26206 opno,
26207 *total,
26208 speed ? "true" : "false");
26210 debug_rtx (x);
26212 return ret;
26215 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26217 static int
26218 rs6000_debug_address_cost (rtx x, bool speed)
26220 int ret = TARGET_ADDRESS_COST (x, speed);
26222 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26223 ret, speed ? "true" : "false");
26224 debug_rtx (x);
26226 return ret;
26230 /* A C expression returning the cost of moving data from a register of class
26231 CLASS1 to one of CLASS2. */
26233 static int
26234 rs6000_register_move_cost (enum machine_mode mode,
26235 reg_class_t from, reg_class_t to)
26237 int ret;
26239 if (TARGET_DEBUG_COST)
26240 dbg_cost_ctrl++;
26242 /* Moves from/to GENERAL_REGS. */
26243 if (reg_classes_intersect_p (to, GENERAL_REGS)
26244 || reg_classes_intersect_p (from, GENERAL_REGS))
26246 reg_class_t rclass = from;
26248 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26249 rclass = to;
26251 if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS)
26252 ret = (rs6000_memory_move_cost (mode, rclass, false)
26253 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26255 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26256 shift. */
26257 else if (rclass == CR_REGS)
26258 ret = 4;
26260 /* For those processors that have slow LR/CTR moves, make them more
26261 expensive than memory in order to bias spills to memory .*/
26262 else if ((rs6000_cpu == PROCESSOR_POWER6
26263 || rs6000_cpu == PROCESSOR_POWER7)
26264 && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
26265 ret = 6 * hard_regno_nregs[0][mode];
26267 else
26268 /* A move will cost one instruction per GPR moved. */
26269 ret = 2 * hard_regno_nregs[0][mode];
26272 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26273 else if (VECTOR_UNIT_VSX_P (mode)
26274 && reg_classes_intersect_p (to, VSX_REGS)
26275 && reg_classes_intersect_p (from, VSX_REGS))
26276 ret = 2 * hard_regno_nregs[32][mode];
26278 /* Moving between two similar registers is just one instruction. */
26279 else if (reg_classes_intersect_p (to, from))
26280 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26282 /* Everything else has to go through GENERAL_REGS. */
26283 else
26284 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26285 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26287 if (TARGET_DEBUG_COST)
26289 if (dbg_cost_ctrl == 1)
26290 fprintf (stderr,
26291 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26292 ret, GET_MODE_NAME (mode), reg_class_names[from],
26293 reg_class_names[to]);
26294 dbg_cost_ctrl--;
26297 return ret;
26300 /* A C expressions returning the cost of moving data of MODE from a register to
26301 or from memory. */
26303 static int
26304 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26305 bool in ATTRIBUTE_UNUSED)
26307 int ret;
26309 if (TARGET_DEBUG_COST)
26310 dbg_cost_ctrl++;
26312 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26313 ret = 4 * hard_regno_nregs[0][mode];
26314 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26315 ret = 4 * hard_regno_nregs[32][mode];
26316 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26317 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26318 else
26319 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26321 if (TARGET_DEBUG_COST)
26323 if (dbg_cost_ctrl == 1)
26324 fprintf (stderr,
26325 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26326 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26327 dbg_cost_ctrl--;
26330 return ret;
26333 /* Returns a code for a target-specific builtin that implements
26334 reciprocal of the function, or NULL_TREE if not available. */
26336 static tree
26337 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26338 bool sqrt ATTRIBUTE_UNUSED)
26340 if (optimize_insn_for_size_p ())
26341 return NULL_TREE;
26343 if (md_fn)
26344 switch (fn)
26346 case VSX_BUILTIN_XVSQRTDP:
26347 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26348 return NULL_TREE;
26350 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26352 case VSX_BUILTIN_XVSQRTSP:
26353 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26354 return NULL_TREE;
26356 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26358 default:
26359 return NULL_TREE;
26362 else
26363 switch (fn)
26365 case BUILT_IN_SQRT:
26366 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26367 return NULL_TREE;
26369 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26371 case BUILT_IN_SQRTF:
26372 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26373 return NULL_TREE;
26375 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26377 default:
26378 return NULL_TREE;
26382 /* Load up a constant. If the mode is a vector mode, splat the value across
26383 all of the vector elements. */
26385 static rtx
26386 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26388 rtx reg;
26390 if (mode == SFmode || mode == DFmode)
26392 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26393 reg = force_reg (mode, d);
26395 else if (mode == V4SFmode)
26397 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26398 rtvec v = gen_rtvec (4, d, d, d, d);
26399 reg = gen_reg_rtx (mode);
26400 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26402 else if (mode == V2DFmode)
26404 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26405 rtvec v = gen_rtvec (2, d, d);
26406 reg = gen_reg_rtx (mode);
26407 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26409 else
26410 gcc_unreachable ();
26412 return reg;
26415 /* Generate an FMA instruction. */
26417 static void
26418 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26420 enum machine_mode mode = GET_MODE (target);
26421 rtx dst;
26423 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26424 gcc_assert (dst != NULL);
26426 if (dst != target)
26427 emit_move_insn (target, dst);
26430 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26432 static void
26433 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26435 enum machine_mode mode = GET_MODE (target);
26436 rtx dst;
26438 /* Altivec does not support fms directly;
26439 generate in terms of fma in that case. */
26440 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26441 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26442 else
26444 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26445 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26447 gcc_assert (dst != NULL);
26449 if (dst != target)
26450 emit_move_insn (target, dst);
26453 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26455 static void
26456 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26458 enum machine_mode mode = GET_MODE (dst);
26459 rtx r;
26461 /* This is a tad more complicated, since the fnma_optab is for
26462 a different expression: fma(-m1, m2, a), which is the same
26463 thing except in the case of signed zeros.
26465 Fortunately we know that if FMA is supported that FNMSUB is
26466 also supported in the ISA. Just expand it directly. */
26468 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26470 r = gen_rtx_NEG (mode, a);
26471 r = gen_rtx_FMA (mode, m1, m2, r);
26472 r = gen_rtx_NEG (mode, r);
26473 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26476 /* Newton-Raphson approximation of floating point divide with just 2 passes
26477 (either single precision floating point, or newer machines with higher
26478 accuracy estimates). Support both scalar and vector divide. Assumes no
26479 trapping math and finite arguments. */
26481 static void
26482 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26484 enum machine_mode mode = GET_MODE (dst);
26485 rtx x0, e0, e1, y1, u0, v0;
26486 enum insn_code code = optab_handler (smul_optab, mode);
26487 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26488 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26490 gcc_assert (code != CODE_FOR_nothing);
26492 /* x0 = 1./d estimate */
26493 x0 = gen_reg_rtx (mode);
26494 emit_insn (gen_rtx_SET (VOIDmode, x0,
26495 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26496 UNSPEC_FRES)));
26498 e0 = gen_reg_rtx (mode);
26499 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26501 e1 = gen_reg_rtx (mode);
26502 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26504 y1 = gen_reg_rtx (mode);
26505 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26507 u0 = gen_reg_rtx (mode);
26508 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26510 v0 = gen_reg_rtx (mode);
26511 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26513 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26516 /* Newton-Raphson approximation of floating point divide that has a low
26517 precision estimate. Assumes no trapping math and finite arguments. */
26519 static void
26520 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26522 enum machine_mode mode = GET_MODE (dst);
26523 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26524 enum insn_code code = optab_handler (smul_optab, mode);
26525 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26527 gcc_assert (code != CODE_FOR_nothing);
26529 one = rs6000_load_constant_and_splat (mode, dconst1);
26531 /* x0 = 1./d estimate */
26532 x0 = gen_reg_rtx (mode);
26533 emit_insn (gen_rtx_SET (VOIDmode, x0,
26534 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26535 UNSPEC_FRES)));
26537 e0 = gen_reg_rtx (mode);
26538 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26540 y1 = gen_reg_rtx (mode);
26541 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26543 e1 = gen_reg_rtx (mode);
26544 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26546 y2 = gen_reg_rtx (mode);
26547 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26549 e2 = gen_reg_rtx (mode);
26550 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26552 y3 = gen_reg_rtx (mode);
26553 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26555 u0 = gen_reg_rtx (mode);
26556 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26558 v0 = gen_reg_rtx (mode);
26559 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26561 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26564 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26565 add a reg_note saying that this was a division. Support both scalar and
26566 vector divide. Assumes no trapping math and finite arguments. */
26568 void
26569 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26571 enum machine_mode mode = GET_MODE (dst);
26573 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26574 rs6000_emit_swdiv_high_precision (dst, n, d);
26575 else
26576 rs6000_emit_swdiv_low_precision (dst, n, d);
26578 if (note_p)
26579 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26582 /* Newton-Raphson approximation of single/double-precision floating point
26583 rsqrt. Assumes no trapping math and finite arguments. */
26585 void
26586 rs6000_emit_swrsqrt (rtx dst, rtx src)
26588 enum machine_mode mode = GET_MODE (src);
26589 rtx x0 = gen_reg_rtx (mode);
26590 rtx y = gen_reg_rtx (mode);
26591 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26592 REAL_VALUE_TYPE dconst3_2;
26593 int i;
26594 rtx halfthree;
26595 enum insn_code code = optab_handler (smul_optab, mode);
26596 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26598 gcc_assert (code != CODE_FOR_nothing);
26600 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26601 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26602 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26604 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26606 /* x0 = rsqrt estimate */
26607 emit_insn (gen_rtx_SET (VOIDmode, x0,
26608 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26609 UNSPEC_RSQRT)));
26611 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26612 rs6000_emit_msub (y, src, halfthree, src);
26614 for (i = 0; i < passes; i++)
26616 rtx x1 = gen_reg_rtx (mode);
26617 rtx u = gen_reg_rtx (mode);
26618 rtx v = gen_reg_rtx (mode);
26620 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26621 emit_insn (gen_mul (u, x0, x0));
26622 rs6000_emit_nmsub (v, y, u, halfthree);
26623 emit_insn (gen_mul (x1, x0, v));
26624 x0 = x1;
26627 emit_move_insn (dst, x0);
26628 return;
26631 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26632 (Power7) targets. DST is the target, and SRC is the argument operand. */
26634 void
26635 rs6000_emit_popcount (rtx dst, rtx src)
26637 enum machine_mode mode = GET_MODE (dst);
26638 rtx tmp1, tmp2;
26640 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26641 if (TARGET_POPCNTD)
26643 if (mode == SImode)
26644 emit_insn (gen_popcntdsi2 (dst, src));
26645 else
26646 emit_insn (gen_popcntddi2 (dst, src));
26647 return;
26650 tmp1 = gen_reg_rtx (mode);
26652 if (mode == SImode)
26654 emit_insn (gen_popcntbsi2 (tmp1, src));
26655 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26656 NULL_RTX, 0);
26657 tmp2 = force_reg (SImode, tmp2);
26658 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26660 else
26662 emit_insn (gen_popcntbdi2 (tmp1, src));
26663 tmp2 = expand_mult (DImode, tmp1,
26664 GEN_INT ((HOST_WIDE_INT)
26665 0x01010101 << 32 | 0x01010101),
26666 NULL_RTX, 0);
26667 tmp2 = force_reg (DImode, tmp2);
26668 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26673 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26674 target, and SRC is the argument operand. */
26676 void
26677 rs6000_emit_parity (rtx dst, rtx src)
26679 enum machine_mode mode = GET_MODE (dst);
26680 rtx tmp;
26682 tmp = gen_reg_rtx (mode);
26684 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26685 if (TARGET_CMPB)
26687 if (mode == SImode)
26689 emit_insn (gen_popcntbsi2 (tmp, src));
26690 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26692 else
26694 emit_insn (gen_popcntbdi2 (tmp, src));
26695 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26697 return;
26700 if (mode == SImode)
26702 /* Is mult+shift >= shift+xor+shift+xor? */
26703 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26705 rtx tmp1, tmp2, tmp3, tmp4;
26707 tmp1 = gen_reg_rtx (SImode);
26708 emit_insn (gen_popcntbsi2 (tmp1, src));
26710 tmp2 = gen_reg_rtx (SImode);
26711 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26712 tmp3 = gen_reg_rtx (SImode);
26713 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26715 tmp4 = gen_reg_rtx (SImode);
26716 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26717 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26719 else
26720 rs6000_emit_popcount (tmp, src);
26721 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26723 else
26725 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26726 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26728 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26730 tmp1 = gen_reg_rtx (DImode);
26731 emit_insn (gen_popcntbdi2 (tmp1, src));
26733 tmp2 = gen_reg_rtx (DImode);
26734 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26735 tmp3 = gen_reg_rtx (DImode);
26736 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26738 tmp4 = gen_reg_rtx (DImode);
26739 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26740 tmp5 = gen_reg_rtx (DImode);
26741 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26743 tmp6 = gen_reg_rtx (DImode);
26744 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26745 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26747 else
26748 rs6000_emit_popcount (tmp, src);
26749 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26753 /* Return an RTX representing where to find the function value of a
26754 function returning MODE. */
26755 static rtx
26756 rs6000_complex_function_value (enum machine_mode mode)
26758 unsigned int regno;
26759 rtx r1, r2;
26760 enum machine_mode inner = GET_MODE_INNER (mode);
26761 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26763 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26764 regno = FP_ARG_RETURN;
26765 else
26767 regno = GP_ARG_RETURN;
26769 /* 32-bit is OK since it'll go in r3/r4. */
26770 if (TARGET_32BIT && inner_bytes >= 4)
26771 return gen_rtx_REG (mode, regno);
26774 if (inner_bytes >= 8)
26775 return gen_rtx_REG (mode, regno);
26777 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26778 const0_rtx);
26779 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26780 GEN_INT (inner_bytes));
26781 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26784 /* Target hook for TARGET_FUNCTION_VALUE.
26786 On the SPE, both FPs and vectors are returned in r3.
26788 On RS/6000 an integer value is in r3 and a floating-point value is in
26789 fp1, unless -msoft-float. */
26792 rs6000_function_value (const_tree valtype,
26793 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26794 bool outgoing ATTRIBUTE_UNUSED)
26796 enum machine_mode mode;
26797 unsigned int regno;
26799 /* Special handling for structs in darwin64. */
26800 if (TARGET_MACHO
26801 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26803 CUMULATIVE_ARGS valcum;
26804 rtx valret;
26806 valcum.words = 0;
26807 valcum.fregno = FP_ARG_MIN_REG;
26808 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26809 /* Do a trial code generation as if this were going to be passed as
26810 an argument; if any part goes in memory, we return NULL. */
26811 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
26812 if (valret)
26813 return valret;
26814 /* Otherwise fall through to standard ABI rules. */
26817 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26819 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26820 return gen_rtx_PARALLEL (DImode,
26821 gen_rtvec (2,
26822 gen_rtx_EXPR_LIST (VOIDmode,
26823 gen_rtx_REG (SImode, GP_ARG_RETURN),
26824 const0_rtx),
26825 gen_rtx_EXPR_LIST (VOIDmode,
26826 gen_rtx_REG (SImode,
26827 GP_ARG_RETURN + 1),
26828 GEN_INT (4))));
26830 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26832 return gen_rtx_PARALLEL (DCmode,
26833 gen_rtvec (4,
26834 gen_rtx_EXPR_LIST (VOIDmode,
26835 gen_rtx_REG (SImode, GP_ARG_RETURN),
26836 const0_rtx),
26837 gen_rtx_EXPR_LIST (VOIDmode,
26838 gen_rtx_REG (SImode,
26839 GP_ARG_RETURN + 1),
26840 GEN_INT (4)),
26841 gen_rtx_EXPR_LIST (VOIDmode,
26842 gen_rtx_REG (SImode,
26843 GP_ARG_RETURN + 2),
26844 GEN_INT (8)),
26845 gen_rtx_EXPR_LIST (VOIDmode,
26846 gen_rtx_REG (SImode,
26847 GP_ARG_RETURN + 3),
26848 GEN_INT (12))));
26851 mode = TYPE_MODE (valtype);
26852 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26853 || POINTER_TYPE_P (valtype))
26854 mode = TARGET_32BIT ? SImode : DImode;
26856 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26857 /* _Decimal128 must use an even/odd register pair. */
26858 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26859 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26860 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26861 regno = FP_ARG_RETURN;
26862 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26863 && targetm.calls.split_complex_arg)
26864 return rs6000_complex_function_value (mode);
26865 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26866 return register is used in both cases, and we won't see V2DImode/V2DFmode
26867 for pure altivec, combine the two cases. */
26868 else if (TREE_CODE (valtype) == VECTOR_TYPE
26869 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26870 && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
26871 regno = ALTIVEC_ARG_RETURN;
26872 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26873 && (mode == DFmode || mode == DCmode
26874 || mode == TFmode || mode == TCmode))
26875 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26876 else
26877 regno = GP_ARG_RETURN;
26879 return gen_rtx_REG (mode, regno);
26882 /* Define how to find the value returned by a library function
26883 assuming the value has mode MODE. */
26885 rs6000_libcall_value (enum machine_mode mode)
26887 unsigned int regno;
26889 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26891 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26892 return gen_rtx_PARALLEL (DImode,
26893 gen_rtvec (2,
26894 gen_rtx_EXPR_LIST (VOIDmode,
26895 gen_rtx_REG (SImode, GP_ARG_RETURN),
26896 const0_rtx),
26897 gen_rtx_EXPR_LIST (VOIDmode,
26898 gen_rtx_REG (SImode,
26899 GP_ARG_RETURN + 1),
26900 GEN_INT (4))));
26903 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26904 /* _Decimal128 must use an even/odd register pair. */
26905 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26906 else if (SCALAR_FLOAT_MODE_P (mode)
26907 && TARGET_HARD_FLOAT && TARGET_FPRS
26908 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26909 regno = FP_ARG_RETURN;
26910 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26911 return register is used in both cases, and we won't see V2DImode/V2DFmode
26912 for pure altivec, combine the two cases. */
26913 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
26914 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26915 regno = ALTIVEC_ARG_RETURN;
26916 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26917 return rs6000_complex_function_value (mode);
26918 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26919 && (mode == DFmode || mode == DCmode
26920 || mode == TFmode || mode == TCmode))
26921 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26922 else
26923 regno = GP_ARG_RETURN;
26925 return gen_rtx_REG (mode, regno);
26929 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26930 Frame pointer elimination is automatically handled.
26932 For the RS/6000, if frame pointer elimination is being done, we would like
26933 to convert ap into fp, not sp.
26935 We need r30 if -mminimal-toc was specified, and there are constant pool
26936 references. */
26938 bool
26939 rs6000_can_eliminate (const int from, const int to)
26941 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26942 ? ! frame_pointer_needed
26943 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26944 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26945 : true);
26948 /* Define the offset between two registers, FROM to be eliminated and its
26949 replacement TO, at the start of a routine. */
26950 HOST_WIDE_INT
26951 rs6000_initial_elimination_offset (int from, int to)
26953 rs6000_stack_t *info = rs6000_stack_info ();
26954 HOST_WIDE_INT offset;
26956 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26957 offset = info->push_p ? 0 : -info->total_size;
26958 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26960 offset = info->push_p ? 0 : -info->total_size;
26961 if (FRAME_GROWS_DOWNWARD)
26962 offset += info->fixed_size + info->vars_size + info->parm_size;
26964 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26965 offset = FRAME_GROWS_DOWNWARD
26966 ? info->fixed_size + info->vars_size + info->parm_size
26967 : 0;
26968 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26969 offset = info->total_size;
26970 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26971 offset = info->push_p ? info->total_size : 0;
26972 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26973 offset = 0;
26974 else
26975 gcc_unreachable ();
26977 return offset;
26980 static rtx
26981 rs6000_dwarf_register_span (rtx reg)
26983 rtx parts[8];
26984 int i, words;
26985 unsigned regno = REGNO (reg);
26986 enum machine_mode mode = GET_MODE (reg);
26988 if (TARGET_SPE
26989 && regno < 32
26990 && (SPE_VECTOR_MODE (GET_MODE (reg))
26991 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26992 && mode != SFmode && mode != SDmode && mode != SCmode)))
26994 else
26995 return NULL_RTX;
26997 regno = REGNO (reg);
26999 /* The duality of the SPE register size wreaks all kinds of havoc.
27000 This is a way of distinguishing r0 in 32-bits from r0 in
27001 64-bits. */
27002 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27003 gcc_assert (words <= 4);
27004 for (i = 0; i < words; i++, regno++)
27006 if (BYTES_BIG_ENDIAN)
27008 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27009 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27011 else
27013 parts[2 * i] = gen_rtx_REG (SImode, regno);
27014 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27018 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27021 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27023 static void
27024 rs6000_init_dwarf_reg_sizes_extra (tree address)
27026 if (TARGET_SPE)
27028 int i;
27029 enum machine_mode mode = TYPE_MODE (char_type_node);
27030 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27031 rtx mem = gen_rtx_MEM (BLKmode, addr);
27032 rtx value = gen_int_mode (4, mode);
27034 for (i = 1201; i < 1232; i++)
27036 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27037 HOST_WIDE_INT offset
27038 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27040 emit_move_insn (adjust_address (mem, mode, offset), value);
27045 /* Map internal gcc register numbers to DWARF2 register numbers. */
27047 unsigned int
27048 rs6000_dbx_register_number (unsigned int regno)
27050 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27051 return regno;
27052 if (regno == MQ_REGNO)
27053 return 100;
27054 if (regno == LR_REGNO)
27055 return 108;
27056 if (regno == CTR_REGNO)
27057 return 109;
27058 if (CR_REGNO_P (regno))
27059 return regno - CR0_REGNO + 86;
27060 if (regno == CA_REGNO)
27061 return 101; /* XER */
27062 if (ALTIVEC_REGNO_P (regno))
27063 return regno - FIRST_ALTIVEC_REGNO + 1124;
27064 if (regno == VRSAVE_REGNO)
27065 return 356;
27066 if (regno == VSCR_REGNO)
27067 return 67;
27068 if (regno == SPE_ACC_REGNO)
27069 return 99;
27070 if (regno == SPEFSCR_REGNO)
27071 return 612;
27072 /* SPE high reg number. We get these values of regno from
27073 rs6000_dwarf_register_span. */
27074 gcc_assert (regno >= 1200 && regno < 1232);
27075 return regno;
27078 /* target hook eh_return_filter_mode */
27079 static enum machine_mode
27080 rs6000_eh_return_filter_mode (void)
27082 return TARGET_32BIT ? SImode : word_mode;
27085 /* Target hook for scalar_mode_supported_p. */
27086 static bool
27087 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27089 if (DECIMAL_FLOAT_MODE_P (mode))
27090 return default_decimal_float_supported_p ();
27091 else
27092 return default_scalar_mode_supported_p (mode);
27095 /* Target hook for vector_mode_supported_p. */
27096 static bool
27097 rs6000_vector_mode_supported_p (enum machine_mode mode)
27100 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27101 return true;
27103 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27104 return true;
27106 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27107 return true;
27109 else
27110 return false;
27113 /* Target hook for invalid_arg_for_unprototyped_fn. */
27114 static const char *
27115 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27117 return (!rs6000_darwin64_abi
27118 && typelist == 0
27119 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27120 && (funcdecl == NULL_TREE
27121 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27122 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27123 ? N_("AltiVec argument passed to unprototyped function")
27124 : NULL;
27127 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27128 setup by using __stack_chk_fail_local hidden function instead of
27129 calling __stack_chk_fail directly. Otherwise it is better to call
27130 __stack_chk_fail directly. */
27132 static tree ATTRIBUTE_UNUSED
27133 rs6000_stack_protect_fail (void)
27135 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27136 ? default_hidden_stack_protect_fail ()
27137 : default_external_stack_protect_fail ();
27140 void
27141 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27142 int num_operands ATTRIBUTE_UNUSED)
27144 if (rs6000_warn_cell_microcode)
27146 const char *temp;
27147 int insn_code_number = recog_memoized (insn);
27148 location_t location = locator_location (INSN_LOCATOR (insn));
27150 /* Punt on insns we cannot recognize. */
27151 if (insn_code_number < 0)
27152 return;
27154 temp = get_insn_template (insn_code_number, insn);
27156 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27157 warning_at (location, OPT_mwarn_cell_microcode,
27158 "emitting microcode insn %s\t[%s] #%d",
27159 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27160 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27161 warning_at (location, OPT_mwarn_cell_microcode,
27162 "emitting conditional microcode insn %s\t[%s] #%d",
27163 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27168 /* Mask options that we want to support inside of attribute((target)) and
27169 #pragma GCC target operations. Note, we do not include things like
27170 64/32-bit, endianess, hard/soft floating point, etc. that would have
27171 different calling sequences. */
27173 struct rs6000_opt_mask {
27174 const char *name; /* option name */
27175 int mask; /* mask to set */
27176 bool invert; /* invert sense of mask */
27177 bool valid_target; /* option is a target option */
27180 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27182 { "altivec", MASK_ALTIVEC, false, true },
27183 { "cmpb", MASK_CMPB, false, true },
27184 { "dlmzb", MASK_DLMZB, false, true },
27185 { "fprnd", MASK_FPRND, false, true },
27186 { "hard-dfp", MASK_DFP, false, true },
27187 { "isel", MASK_ISEL, false, true },
27188 { "mfcrf", MASK_MFCRF, false, true },
27189 { "mfpgpr", MASK_MFPGPR, false, true },
27190 { "mulhw", MASK_MULHW, false, true },
27191 { "multiple", MASK_MULTIPLE, false, true },
27192 { "update", MASK_NO_UPDATE, true , true },
27193 { "popcntb", MASK_POPCNTB, false, true },
27194 { "popcntd", MASK_POPCNTD, false, true },
27195 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27196 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27197 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27198 { "string", MASK_STRING, false, true },
27199 { "vsx", MASK_VSX, false, true },
27200 #ifdef MASK_64BIT
27201 #if TARGET_AIX_OS
27202 { "aix64", MASK_64BIT, false, false },
27203 { "aix32", MASK_64BIT, true, false },
27204 #else
27205 { "64", MASK_64BIT, false, false },
27206 { "32", MASK_64BIT, true, false },
27207 #endif
27208 #endif
27209 #ifdef MASK_EABI
27210 { "eabi", MASK_EABI, false, false },
27211 #endif
27212 #ifdef MASK_LITTLE_ENDIAN
27213 { "little", MASK_LITTLE_ENDIAN, false, false },
27214 { "big", MASK_LITTLE_ENDIAN, true, false },
27215 #endif
27216 #ifdef MASK_RELOCATABLE
27217 { "relocatable", MASK_RELOCATABLE, false, false },
27218 #endif
27219 #ifdef MASK_STRICT_ALIGN
27220 { "strict-align", MASK_STRICT_ALIGN, false, false },
27221 #endif
27222 { "power", MASK_POWER, false, false },
27223 { "power2", MASK_POWER2, false, false },
27224 { "powerpc", MASK_POWERPC, false, false },
27225 { "soft-float", MASK_SOFT_FLOAT, false, false },
27226 { "string", MASK_STRING, false, false },
27229 /* Option variables that we want to support inside attribute((target)) and
27230 #pragma GCC target operations. */
27232 struct rs6000_opt_var {
27233 const char *name; /* option name */
27234 size_t global_offset; /* offset of the option in global_options. */
27235 size_t target_offset; /* offset of the option in target optiosn. */
27238 static struct rs6000_opt_var const rs6000_opt_vars[] =
27240 { "friz",
27241 offsetof (struct gcc_options, x_TARGET_FRIZ),
27242 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27243 { "avoid-indexed-addresses",
27244 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27245 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27246 { "paired",
27247 offsetof (struct gcc_options, x_rs6000_paired_float),
27248 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27249 { "longcall",
27250 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27251 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27254 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27255 parsing. Return true if there were no errors. */
27257 static bool
27258 rs6000_inner_target_options (tree args, bool attr_p)
27260 bool ret = true;
27262 if (args == NULL_TREE)
27265 else if (TREE_CODE (args) == STRING_CST)
27267 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27268 char *q;
27270 while ((q = strtok (p, ",")) != NULL)
27272 bool error_p = false;
27273 bool not_valid_p = false;
27274 const char *cpu_opt = NULL;
27276 p = NULL;
27277 if (strncmp (q, "cpu=", 4) == 0)
27279 int cpu_index = rs6000_cpu_name_lookup (q+4);
27280 if (cpu_index >= 0)
27281 rs6000_cpu_index = cpu_index;
27282 else
27284 error_p = true;
27285 cpu_opt = q+4;
27288 else if (strncmp (q, "tune=", 5) == 0)
27290 int tune_index = rs6000_cpu_name_lookup (q+5);
27291 if (tune_index >= 0)
27292 rs6000_tune_index = tune_index;
27293 else
27295 error_p = true;
27296 cpu_opt = q+5;
27299 else
27301 size_t i;
27302 bool invert = false;
27303 char *r = q;
27305 error_p = true;
27306 if (strncmp (r, "no-", 3) == 0)
27308 invert = true;
27309 r += 3;
27312 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27313 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27315 int mask = rs6000_opt_masks[i].mask;
27317 if (!rs6000_opt_masks[i].valid_target)
27318 not_valid_p = true;
27319 else
27321 error_p = false;
27322 target_flags_explicit |= mask;
27324 if (rs6000_opt_masks[i].invert)
27325 invert = !invert;
27327 if (invert)
27328 target_flags &= ~mask;
27329 else
27330 target_flags |= mask;
27332 break;
27335 if (error_p && !not_valid_p)
27337 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27338 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27340 size_t j = rs6000_opt_vars[i].global_offset;
27341 ((int *) &global_options)[j] = !invert;
27342 error_p = false;
27343 break;
27348 if (error_p)
27350 const char *eprefix, *esuffix;
27352 ret = false;
27353 if (attr_p)
27355 eprefix = "__attribute__((__target__(";
27356 esuffix = ")))";
27358 else
27360 eprefix = "#pragma GCC target ";
27361 esuffix = "";
27364 if (cpu_opt)
27365 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27366 q, esuffix);
27367 else if (not_valid_p)
27368 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27369 else
27370 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27375 else if (TREE_CODE (args) == TREE_LIST)
27379 tree value = TREE_VALUE (args);
27380 if (value)
27382 bool ret2 = rs6000_inner_target_options (value, attr_p);
27383 if (!ret2)
27384 ret = false;
27386 args = TREE_CHAIN (args);
27388 while (args != NULL_TREE);
27391 else
27392 gcc_unreachable ();
27394 return ret;
27397 /* Print out the target options as a list for -mdebug=target. */
27399 static void
27400 rs6000_debug_target_options (tree args, const char *prefix)
27402 if (args == NULL_TREE)
27403 fprintf (stderr, "%s<NULL>", prefix);
27405 else if (TREE_CODE (args) == STRING_CST)
27407 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27408 char *q;
27410 while ((q = strtok (p, ",")) != NULL)
27412 p = NULL;
27413 fprintf (stderr, "%s\"%s\"", prefix, q);
27414 prefix = ", ";
27418 else if (TREE_CODE (args) == TREE_LIST)
27422 tree value = TREE_VALUE (args);
27423 if (value)
27425 rs6000_debug_target_options (value, prefix);
27426 prefix = ", ";
27428 args = TREE_CHAIN (args);
27430 while (args != NULL_TREE);
27433 else
27434 gcc_unreachable ();
27436 return;
27440 /* Hook to validate attribute((target("..."))). */
27442 static bool
27443 rs6000_valid_attribute_p (tree fndecl,
27444 tree ARG_UNUSED (name),
27445 tree args,
27446 int flags)
27448 struct cl_target_option cur_target;
27449 bool ret;
27450 tree old_optimize = build_optimization_node ();
27451 tree new_target, new_optimize;
27452 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27454 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27456 if (TARGET_DEBUG_TARGET)
27458 tree tname = DECL_NAME (fndecl);
27459 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27460 if (tname)
27461 fprintf (stderr, "function: %.*s\n",
27462 (int) IDENTIFIER_LENGTH (tname),
27463 IDENTIFIER_POINTER (tname));
27464 else
27465 fprintf (stderr, "function: unknown\n");
27467 fprintf (stderr, "args:");
27468 rs6000_debug_target_options (args, " ");
27469 fprintf (stderr, "\n");
27471 if (flags)
27472 fprintf (stderr, "flags: 0x%x\n", flags);
27474 fprintf (stderr, "--------------------\n");
27477 old_optimize = build_optimization_node ();
27478 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27480 /* If the function changed the optimization levels as well as setting target
27481 options, start with the optimizations specified. */
27482 if (func_optimize && func_optimize != old_optimize)
27483 cl_optimization_restore (&global_options,
27484 TREE_OPTIMIZATION (func_optimize));
27486 /* The target attributes may also change some optimization flags, so update
27487 the optimization options if necessary. */
27488 cl_target_option_save (&cur_target, &global_options);
27489 rs6000_cpu_index = rs6000_tune_index = -1;
27490 ret = rs6000_inner_target_options (args, true);
27492 /* Set up any additional state. */
27493 if (ret)
27495 ret = rs6000_option_override_internal (false);
27496 new_target = build_target_option_node ();
27498 else
27499 new_target = NULL;
27501 new_optimize = build_optimization_node ();
27503 if (!new_target)
27504 ret = false;
27506 else if (fndecl)
27508 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27510 if (old_optimize != new_optimize)
27511 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27514 cl_target_option_restore (&global_options, &cur_target);
27516 if (old_optimize != new_optimize)
27517 cl_optimization_restore (&global_options,
27518 TREE_OPTIMIZATION (old_optimize));
27520 return ret;
27524 /* Hook to validate the current #pragma GCC target and set the state, and
27525 update the macros based on what was changed. If ARGS is NULL, then
27526 POP_TARGET is used to reset the options. */
27528 bool
27529 rs6000_pragma_target_parse (tree args, tree pop_target)
27531 tree cur_tree;
27532 bool ret;
27534 if (TARGET_DEBUG_TARGET)
27536 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27537 fprintf (stderr, "args:");
27538 rs6000_debug_target_options (args, " ");
27539 fprintf (stderr, "\n");
27541 if (pop_target)
27543 fprintf (stderr, "pop_target:\n");
27544 debug_tree (pop_target);
27546 else
27547 fprintf (stderr, "pop_target: <NULL>\n");
27549 fprintf (stderr, "--------------------\n");
27552 if (! args)
27554 ret = true;
27555 cur_tree = ((pop_target)
27556 ? pop_target
27557 : target_option_default_node);
27558 cl_target_option_restore (&global_options,
27559 TREE_TARGET_OPTION (cur_tree));
27561 else
27563 rs6000_cpu_index = rs6000_tune_index = -1;
27564 ret = rs6000_inner_target_options (args, false);
27565 cur_tree = build_target_option_node ();
27567 if (!cur_tree)
27568 ret = false;
27571 if (cur_tree)
27572 target_option_current_node = cur_tree;
27574 return ret;
27578 /* Remember the last target of rs6000_set_current_function. */
27579 static GTY(()) tree rs6000_previous_fndecl;
27581 /* Establish appropriate back-end context for processing the function
27582 FNDECL. The argument might be NULL to indicate processing at top
27583 level, outside of any function scope. */
27584 static void
27585 rs6000_set_current_function (tree fndecl)
27587 tree old_tree = (rs6000_previous_fndecl
27588 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27589 : NULL_TREE);
27591 tree new_tree = (fndecl
27592 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27593 : NULL_TREE);
27595 if (TARGET_DEBUG_TARGET)
27597 bool print_final = false;
27598 fprintf (stderr, "\n==================== rs6000_set_current_function");
27600 if (fndecl)
27601 fprintf (stderr, ", fndecl %s (%p)",
27602 (DECL_NAME (fndecl)
27603 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27604 : "<unknown>"), (void *)fndecl);
27606 if (rs6000_previous_fndecl)
27607 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27609 fprintf (stderr, "\n");
27610 if (new_tree)
27612 fprintf (stderr, "\nnew fndecl target specific options:\n");
27613 debug_tree (new_tree);
27614 print_final = true;
27617 if (old_tree)
27619 fprintf (stderr, "\nold fndecl target specific options:\n");
27620 debug_tree (old_tree);
27621 print_final = true;
27624 if (print_final)
27625 fprintf (stderr, "--------------------\n");
27628 /* Only change the context if the function changes. This hook is called
27629 several times in the course of compiling a function, and we don't want to
27630 slow things down too much or call target_reinit when it isn't safe. */
27631 if (fndecl && fndecl != rs6000_previous_fndecl)
27633 rs6000_previous_fndecl = fndecl;
27634 if (old_tree == new_tree)
27637 else if (new_tree)
27639 cl_target_option_restore (&global_options,
27640 TREE_TARGET_OPTION (new_tree));
27641 target_reinit ();
27644 else if (old_tree)
27646 struct cl_target_option *def
27647 = TREE_TARGET_OPTION (target_option_current_node);
27649 cl_target_option_restore (&global_options, def);
27650 target_reinit ();
27656 /* Save the current options */
27658 static void
27659 rs6000_function_specific_save (struct cl_target_option *ptr)
27661 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27664 /* Restore the current options */
27666 static void
27667 rs6000_function_specific_restore (struct cl_target_option *ptr)
27669 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27670 (void) rs6000_option_override_internal (false);
27673 /* Print the current options */
27675 static void
27676 rs6000_function_specific_print (FILE *file, int indent,
27677 struct cl_target_option *ptr)
27679 size_t i;
27680 int flags = ptr->x_target_flags;
27682 /* Print the various mask options. */
27683 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27684 if ((flags & rs6000_opt_masks[i].mask) != 0)
27686 flags &= ~ rs6000_opt_masks[i].mask;
27687 fprintf (file, "%*s-m%s%s\n", indent, "",
27688 rs6000_opt_masks[i].invert ? "no-" : "",
27689 rs6000_opt_masks[i].name);
27692 /* Print the various options that are variables. */
27693 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27695 size_t j = rs6000_opt_vars[i].target_offset;
27696 if (((signed char *) ptr)[j])
27697 fprintf (file, "%*s-m%s\n", indent, "",
27698 rs6000_opt_vars[i].name);
27703 /* Hook to determine if one function can safely inline another. */
27705 static bool
27706 rs6000_can_inline_p (tree caller, tree callee)
27708 bool ret = false;
27709 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27710 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27712 /* If callee has no option attributes, then it is ok to inline. */
27713 if (!callee_tree)
27714 ret = true;
27716 /* If caller has no option attributes, but callee does then it is not ok to
27717 inline. */
27718 else if (!caller_tree)
27719 ret = false;
27721 else
27723 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
27724 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
27726 /* Callee's options should a subset of the caller's, i.e. a vsx function
27727 can inline an altivec function but a non-vsx function can't inline a
27728 vsx function. */
27729 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
27730 == callee_opts->x_target_flags)
27731 ret = true;
27734 if (TARGET_DEBUG_TARGET)
27735 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27736 (DECL_NAME (caller)
27737 ? IDENTIFIER_POINTER (DECL_NAME (caller))
27738 : "<unknown>"),
27739 (DECL_NAME (callee)
27740 ? IDENTIFIER_POINTER (DECL_NAME (callee))
27741 : "<unknown>"),
27742 (ret ? "can" : "cannot"));
27744 return ret;
27747 /* Allocate a stack temp and fixup the address so it meets the particular
27748 memory requirements (either offetable or REG+REG addressing). */
27751 rs6000_allocate_stack_temp (enum machine_mode mode,
27752 bool offsettable_p,
27753 bool reg_reg_p)
27755 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27756 rtx addr = XEXP (stack, 0);
27757 int strict_p = (reload_in_progress || reload_completed);
27759 if (!legitimate_indirect_address_p (addr, strict_p))
27761 if (offsettable_p
27762 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27763 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27765 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27766 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27769 return stack;
27772 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27773 to such a form to deal with memory reference instructions like STFIWX that
27774 only take reg+reg addressing. */
27777 rs6000_address_for_fpconvert (rtx x)
27779 int strict_p = (reload_in_progress || reload_completed);
27780 rtx addr;
27782 gcc_assert (MEM_P (x));
27783 addr = XEXP (x, 0);
27784 if (! legitimate_indirect_address_p (addr, strict_p)
27785 && ! legitimate_indexed_address_p (addr, strict_p))
27787 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27789 rtx reg = XEXP (addr, 0);
27790 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27791 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27792 gcc_assert (REG_P (reg));
27793 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27794 addr = reg;
27796 else if (GET_CODE (addr) == PRE_MODIFY)
27798 rtx reg = XEXP (addr, 0);
27799 rtx expr = XEXP (addr, 1);
27800 gcc_assert (REG_P (reg));
27801 gcc_assert (GET_CODE (expr) == PLUS);
27802 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27803 addr = reg;
27806 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27809 return x;
27812 /* Given a memory reference, if it is not in the form for altivec memory
27813 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
27814 convert to the altivec format. */
27817 rs6000_address_for_altivec (rtx x)
27819 gcc_assert (MEM_P (x));
27820 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
27822 rtx addr = XEXP (x, 0);
27823 int strict_p = (reload_in_progress || reload_completed);
27825 if (!legitimate_indexed_address_p (addr, strict_p)
27826 && !legitimate_indirect_address_p (addr, strict_p))
27827 addr = copy_to_mode_reg (Pmode, addr);
27829 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
27830 x = change_address (x, GET_MODE (x), addr);
27833 return x;
27836 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
27838 On the RS/6000, all integer constants are acceptable, most won't be valid
27839 for particular insns, though. Only easy FP constants are acceptable. */
27841 static bool
27842 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
27844 if (rs6000_tls_referenced_p (x))
27845 return false;
27847 return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
27848 || GET_MODE (x) == VOIDmode
27849 || (TARGET_POWERPC64 && mode == DImode)
27850 || easy_fp_constant (x, mode)
27851 || easy_vector_constant (x, mode));
27855 /* A function pointer under AIX is a pointer to a data area whose first word
27856 contains the actual address of the function, whose second word contains a
27857 pointer to its TOC, and whose third word contains a value to place in the
27858 static chain register (r11). Note that if we load the static chain, our
27859 "trampoline" need not have any executable code. */
27861 void
27862 rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag)
27864 rtx func_addr;
27865 rtx toc_reg;
27866 rtx sc_reg;
27867 rtx stack_ptr;
27868 rtx stack_toc_offset;
27869 rtx stack_toc_mem;
27870 rtx func_toc_offset;
27871 rtx func_toc_mem;
27872 rtx func_sc_offset;
27873 rtx func_sc_mem;
27874 rtx insn;
27875 rtx (*call_func) (rtx, rtx, rtx, rtx);
27876 rtx (*call_value_func) (rtx, rtx, rtx, rtx, rtx);
27878 stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
27879 toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM);
27881 /* Load up address of the actual function. */
27882 func_desc = force_reg (Pmode, func_desc);
27883 func_addr = gen_reg_rtx (Pmode);
27884 emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc));
27886 if (TARGET_32BIT)
27889 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_32BIT);
27890 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_32BIT);
27891 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_32BIT);
27892 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27894 call_func = gen_call_indirect_aix32bit;
27895 call_value_func = gen_call_value_indirect_aix32bit;
27897 else
27899 call_func = gen_call_indirect_aix32bit_nor11;
27900 call_value_func = gen_call_value_indirect_aix32bit_nor11;
27903 else
27905 stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_64BIT);
27906 func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_64BIT);
27907 func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_64BIT);
27908 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27910 call_func = gen_call_indirect_aix64bit;
27911 call_value_func = gen_call_value_indirect_aix64bit;
27913 else
27915 call_func = gen_call_indirect_aix64bit_nor11;
27916 call_value_func = gen_call_value_indirect_aix64bit_nor11;
27920 /* Reserved spot to store the TOC. */
27921 stack_toc_mem = gen_frame_mem (Pmode,
27922 gen_rtx_PLUS (Pmode,
27923 stack_ptr,
27924 stack_toc_offset));
27926 gcc_assert (cfun);
27927 gcc_assert (cfun->machine);
27929 /* Can we optimize saving the TOC in the prologue or do we need to do it at
27930 every call? */
27931 if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
27932 cfun->machine->save_toc_in_prologue = true;
27934 else
27936 MEM_VOLATILE_P (stack_toc_mem) = 1;
27937 emit_move_insn (stack_toc_mem, toc_reg);
27940 /* Calculate the address to load the TOC of the called function. We don't
27941 actually load this until the split after reload. */
27942 func_toc_mem = gen_rtx_MEM (Pmode,
27943 gen_rtx_PLUS (Pmode,
27944 func_desc,
27945 func_toc_offset));
27947 /* If we have a static chain, load it up. */
27948 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
27950 func_sc_mem = gen_rtx_MEM (Pmode,
27951 gen_rtx_PLUS (Pmode,
27952 func_desc,
27953 func_sc_offset));
27955 sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
27956 emit_move_insn (sc_reg, func_sc_mem);
27959 /* Create the call. */
27960 if (value)
27961 insn = call_value_func (value, func_addr, flag, func_toc_mem,
27962 stack_toc_mem);
27963 else
27964 insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem);
27966 emit_call_insn (insn);
27969 /* Return whether we need to always update the saved TOC pointer when we update
27970 the stack pointer. */
27972 static bool
27973 rs6000_save_toc_in_prologue_p (void)
27975 return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue);
27978 #ifdef HAVE_GAS_HIDDEN
27979 # define USE_HIDDEN_LINKONCE 1
27980 #else
27981 # define USE_HIDDEN_LINKONCE 0
27982 #endif
27984 /* Fills in the label name that should be used for a 476 link stack thunk. */
27986 void
27987 get_ppc476_thunk_name (char name[32])
27989 gcc_assert (TARGET_LINK_STACK);
27991 if (USE_HIDDEN_LINKONCE)
27992 sprintf (name, "__ppc476.get_thunk");
27993 else
27994 ASM_GENERATE_INTERNAL_LABEL (name, "LPPC476_", 0);
27997 /* This function emits the simple thunk routine that is used to preserve
27998 the link stack on the 476 cpu. */
28000 static void
28001 rs6000_code_end (void)
28003 char name[32];
28004 tree decl;
28006 if (!TARGET_LINK_STACK)
28007 return;
28009 get_ppc476_thunk_name (name);
28011 decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, get_identifier (name),
28012 build_function_type_list (void_type_node, NULL_TREE));
28013 DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
28014 NULL_TREE, void_type_node);
28015 TREE_PUBLIC (decl) = 1;
28016 TREE_STATIC (decl) = 1;
28018 if (USE_HIDDEN_LINKONCE)
28020 DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
28021 targetm.asm_out.unique_section (decl, 0);
28022 switch_to_section (get_named_section (decl, NULL, 0));
28023 DECL_WEAK (decl) = 1;
28024 ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
28025 targetm.asm_out.globalize_label (asm_out_file, name);
28026 targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN);
28027 ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
28029 else
28031 switch_to_section (text_section);
28032 ASM_OUTPUT_LABEL (asm_out_file, name);
28035 DECL_INITIAL (decl) = make_node (BLOCK);
28036 current_function_decl = decl;
28037 init_function_start (decl);
28038 first_function_block_is_cold = false;
28039 /* Make sure unwind info is emitted for the thunk if needed. */
28040 final_start_function (emit_barrier (), asm_out_file, 1);
28042 fputs ("\tblr\n", asm_out_file);
28044 final_end_function ();
28045 init_insn_lengths ();
28046 free_after_compilation (cfun);
28047 set_cfun (NULL);
28048 current_function_decl = NULL;
28051 struct gcc_target targetm = TARGET_INITIALIZER;
28053 #include "gt-rs6000.h"