re PR target/35491 (wrong ABI for some struct passing with vector code)
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blobe8fad12caadac5dc8c69e2098879fecd31b08611
1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "recog.h"
35 #include "obstack.h"
36 #include "tree.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "except.h"
40 #include "function.h"
41 #include "output.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "hashtab.h"
48 #include "tm_p.h"
49 #include "target.h"
50 #include "target-def.h"
51 #include "langhooks.h"
52 #include "reload.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
55 #include "gimple.h"
56 #include "tree-flow.h"
57 #include "intl.h"
58 #include "params.h"
59 #include "tm-constrs.h"
60 #if TARGET_XCOFF
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
62 #endif
63 #if TARGET_MACHO
64 #include "gstab.h" /* for N_SLINE */
65 #endif
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
69 #endif
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
107 not in save_size */
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
112 } rs6000_stack_t;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Some local-dynamic symbol. */
119 const char *some_ld_name;
120 /* Whether the instruction chain has been scanned already. */
121 int insn_chain_scanned_p;
122 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
123 int ra_needs_full_frame;
124 /* Flags if __builtin_return_address (0) was used. */
125 int ra_need_lr;
126 /* Cache lr_save_p after expansion of builtin_eh_return. */
127 int lr_save_state;
128 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
129 varargs save area. */
130 HOST_WIDE_INT varargs_save_offset;
131 /* Temporary stack slot to use for SDmode copies. This slot is
132 64-bits wide and is allocated early enough so that the offset
133 does not overflow the 16-bit load/store offset field. */
134 rtx sdmode_stack_slot;
135 } machine_function;
137 /* Target cpu type */
139 enum processor_type rs6000_cpu;
140 struct rs6000_cpu_select rs6000_select[3] =
142 /* switch name, tune arch */
143 { (const char *)0, "--with-cpu=", 1, 1 },
144 { (const char *)0, "-mcpu=", 1, 1 },
145 { (const char *)0, "-mtune=", 1, 0 },
148 /* Always emit branch hint bits. */
149 static GTY(()) bool rs6000_always_hint;
151 /* Schedule instructions for group formation. */
152 static GTY(()) bool rs6000_sched_groups;
154 /* Align branch targets. */
155 static GTY(()) bool rs6000_align_branch_targets;
157 /* Support for -msched-costly-dep option. */
158 const char *rs6000_sched_costly_dep_str;
159 enum rs6000_dependence_cost rs6000_sched_costly_dep;
161 /* Support for -minsert-sched-nops option. */
162 const char *rs6000_sched_insert_nops_str;
163 enum rs6000_nop_insertion rs6000_sched_insert_nops;
165 /* Support targetm.vectorize.builtin_mask_for_load. */
166 static GTY(()) tree altivec_builtin_mask_for_load;
168 /* Size of long double. */
169 int rs6000_long_double_type_size;
171 /* IEEE quad extended precision long double. */
172 int rs6000_ieeequad;
174 /* Nonzero to use AltiVec ABI. */
175 int rs6000_altivec_abi;
177 /* Nonzero if we want SPE SIMD instructions. */
178 int rs6000_spe;
180 /* Nonzero if we want SPE ABI extensions. */
181 int rs6000_spe_abi;
183 /* Nonzero if floating point operations are done in the GPRs. */
184 int rs6000_float_gprs = 0;
186 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
187 int rs6000_darwin64_abi;
189 /* Set to nonzero once AIX common-mode calls have been defined. */
190 static GTY(()) int common_mode_defined;
192 /* Label number of label created for -mrelocatable, to call to so we can
193 get the address of the GOT section */
194 int rs6000_pic_labelno;
196 #ifdef USING_ELFOS_H
197 /* Which abi to adhere to */
198 const char *rs6000_abi_name;
200 /* Semantics of the small data area */
201 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
203 /* Which small data model to use */
204 const char *rs6000_sdata_name = (char *)0;
206 /* Counter for labels which are to be placed in .fixup. */
207 int fixuplabelno = 0;
208 #endif
210 /* Bit size of immediate TLS offsets and string from which it is decoded. */
211 int rs6000_tls_size = 32;
212 const char *rs6000_tls_size_string;
214 /* ABI enumeration available for subtarget to use. */
215 enum rs6000_abi rs6000_current_abi;
217 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
218 int dot_symbols;
220 /* Debug flags */
221 const char *rs6000_debug_name;
222 int rs6000_debug_stack; /* debug stack applications */
223 int rs6000_debug_arg; /* debug argument handling */
224 int rs6000_debug_reg; /* debug register classes */
225 int rs6000_debug_addr; /* debug memory addressing */
226 int rs6000_debug_cost; /* debug rtx_costs */
228 /* Specify the machine mode that pointers have. After generation of rtl, the
229 compiler makes no further distinction between pointers and any other objects
230 of this machine mode. The type is unsigned since not all things that
231 include rs6000.h also include machmode.h. */
232 unsigned rs6000_pmode;
234 /* Width in bits of a pointer. */
235 unsigned rs6000_pointer_size;
238 /* Value is TRUE if register/mode pair is acceptable. */
239 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
241 /* Maximum number of registers needed for a given register class and mode. */
242 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
244 /* How many registers are needed for a given register and mode. */
245 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
247 /* Map register number to register class. */
248 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
250 /* Reload functions based on the type and the vector unit. */
251 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
253 /* Built in types. */
254 tree rs6000_builtin_types[RS6000_BTI_MAX];
255 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
257 const char *rs6000_traceback_name;
258 static enum {
259 traceback_default = 0,
260 traceback_none,
261 traceback_part,
262 traceback_full
263 } rs6000_traceback;
265 /* Flag to say the TOC is initialized */
266 int toc_initialized;
267 char toc_label_name[10];
269 /* Cached value of rs6000_variable_issue. This is cached in
270 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
271 static short cached_can_issue_more;
273 static GTY(()) section *read_only_data_section;
274 static GTY(()) section *private_data_section;
275 static GTY(()) section *read_only_private_data_section;
276 static GTY(()) section *sdata2_section;
277 static GTY(()) section *toc_section;
279 /* Control alignment for fields within structures. */
280 /* String from -malign-XXXXX. */
281 int rs6000_alignment_flags;
283 /* Code model for 64-bit linux. */
284 enum rs6000_cmodel cmodel;
286 /* True for any options that were explicitly set. */
287 static struct {
288 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
289 bool alignment; /* True if -malign- was used. */
290 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
291 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
292 bool spe; /* True if -mspe= was used. */
293 bool float_gprs; /* True if -mfloat-gprs= was used. */
294 bool long_double; /* True if -mlong-double- was used. */
295 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
296 bool vrsave; /* True if -mvrsave was used. */
297 bool cmodel; /* True if -mcmodel was used. */
298 } rs6000_explicit_options;
300 struct builtin_description
302 /* mask is not const because we're going to alter it below. This
303 nonsense will go away when we rewrite the -march infrastructure
304 to give us more target flag bits. */
305 unsigned int mask;
306 const enum insn_code icode;
307 const char *const name;
308 const enum rs6000_builtins code;
311 /* Describe the vector unit used for modes. */
312 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
313 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
315 /* Register classes for various constraints that are based on the target
316 switches. */
317 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
319 /* Describe the alignment of a vector. */
320 int rs6000_vector_align[NUM_MACHINE_MODES];
322 /* Map selected modes to types for builtins. */
323 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
325 /* What modes to automatically generate reciprocal divide estimate (fre) and
326 reciprocal sqrt (frsqrte) for. */
327 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
329 /* Masks to determine which reciprocal esitmate instructions to generate
330 automatically. */
331 enum rs6000_recip_mask {
332 RECIP_SF_DIV = 0x001, /* Use divide estimate */
333 RECIP_DF_DIV = 0x002,
334 RECIP_V4SF_DIV = 0x004,
335 RECIP_V2DF_DIV = 0x008,
337 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
338 RECIP_DF_RSQRT = 0x020,
339 RECIP_V4SF_RSQRT = 0x040,
340 RECIP_V2DF_RSQRT = 0x080,
342 /* Various combination of flags for -mrecip=xxx. */
343 RECIP_NONE = 0,
344 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
345 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
346 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
348 RECIP_HIGH_PRECISION = RECIP_ALL,
350 /* On low precision machines like the power5, don't enable double precision
351 reciprocal square root estimate, since it isn't accurate enough. */
352 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
355 static unsigned int rs6000_recip_control;
356 static const char *rs6000_recip_name;
358 /* -mrecip options. */
359 static struct
361 const char *string; /* option name */
362 unsigned int mask; /* mask bits to set */
363 } recip_options[] = {
364 { "all", RECIP_ALL },
365 { "none", RECIP_NONE },
366 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
367 | RECIP_V2DF_DIV) },
368 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
369 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
370 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
371 | RECIP_V2DF_RSQRT) },
372 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
373 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
376 /* 2 argument gen function typedef. */
377 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
380 /* Target cpu costs. */
382 struct processor_costs {
383 const int mulsi; /* cost of SImode multiplication. */
384 const int mulsi_const; /* cost of SImode multiplication by constant. */
385 const int mulsi_const9; /* cost of SImode mult by short constant. */
386 const int muldi; /* cost of DImode multiplication. */
387 const int divsi; /* cost of SImode division. */
388 const int divdi; /* cost of DImode division. */
389 const int fp; /* cost of simple SFmode and DFmode insns. */
390 const int dmul; /* cost of DFmode multiplication (and fmadd). */
391 const int sdiv; /* cost of SFmode division (fdivs). */
392 const int ddiv; /* cost of DFmode division (fdiv). */
393 const int cache_line_size; /* cache line size in bytes. */
394 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
395 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
396 const int simultaneous_prefetches; /* number of parallel prefetch
397 operations. */
400 const struct processor_costs *rs6000_cost;
402 /* Processor costs (relative to an add) */
404 /* Instruction size costs on 32bit processors. */
405 static const
406 struct processor_costs size32_cost = {
407 COSTS_N_INSNS (1), /* mulsi */
408 COSTS_N_INSNS (1), /* mulsi_const */
409 COSTS_N_INSNS (1), /* mulsi_const9 */
410 COSTS_N_INSNS (1), /* muldi */
411 COSTS_N_INSNS (1), /* divsi */
412 COSTS_N_INSNS (1), /* divdi */
413 COSTS_N_INSNS (1), /* fp */
414 COSTS_N_INSNS (1), /* dmul */
415 COSTS_N_INSNS (1), /* sdiv */
416 COSTS_N_INSNS (1), /* ddiv */
423 /* Instruction size costs on 64bit processors. */
424 static const
425 struct processor_costs size64_cost = {
426 COSTS_N_INSNS (1), /* mulsi */
427 COSTS_N_INSNS (1), /* mulsi_const */
428 COSTS_N_INSNS (1), /* mulsi_const9 */
429 COSTS_N_INSNS (1), /* muldi */
430 COSTS_N_INSNS (1), /* divsi */
431 COSTS_N_INSNS (1), /* divdi */
432 COSTS_N_INSNS (1), /* fp */
433 COSTS_N_INSNS (1), /* dmul */
434 COSTS_N_INSNS (1), /* sdiv */
435 COSTS_N_INSNS (1), /* ddiv */
436 128,
442 /* Instruction costs on RIOS1 processors. */
443 static const
444 struct processor_costs rios1_cost = {
445 COSTS_N_INSNS (5), /* mulsi */
446 COSTS_N_INSNS (4), /* mulsi_const */
447 COSTS_N_INSNS (3), /* mulsi_const9 */
448 COSTS_N_INSNS (5), /* muldi */
449 COSTS_N_INSNS (19), /* divsi */
450 COSTS_N_INSNS (19), /* divdi */
451 COSTS_N_INSNS (2), /* fp */
452 COSTS_N_INSNS (2), /* dmul */
453 COSTS_N_INSNS (19), /* sdiv */
454 COSTS_N_INSNS (19), /* ddiv */
455 128, /* cache line size */
456 64, /* l1 cache */
457 512, /* l2 cache */
458 0, /* streams */
461 /* Instruction costs on RIOS2 processors. */
462 static const
463 struct processor_costs rios2_cost = {
464 COSTS_N_INSNS (2), /* mulsi */
465 COSTS_N_INSNS (2), /* mulsi_const */
466 COSTS_N_INSNS (2), /* mulsi_const9 */
467 COSTS_N_INSNS (2), /* muldi */
468 COSTS_N_INSNS (13), /* divsi */
469 COSTS_N_INSNS (13), /* divdi */
470 COSTS_N_INSNS (2), /* fp */
471 COSTS_N_INSNS (2), /* dmul */
472 COSTS_N_INSNS (17), /* sdiv */
473 COSTS_N_INSNS (17), /* ddiv */
474 256, /* cache line size */
475 256, /* l1 cache */
476 1024, /* l2 cache */
477 0, /* streams */
480 /* Instruction costs on RS64A processors. */
481 static const
482 struct processor_costs rs64a_cost = {
483 COSTS_N_INSNS (20), /* mulsi */
484 COSTS_N_INSNS (12), /* mulsi_const */
485 COSTS_N_INSNS (8), /* mulsi_const9 */
486 COSTS_N_INSNS (34), /* muldi */
487 COSTS_N_INSNS (65), /* divsi */
488 COSTS_N_INSNS (67), /* divdi */
489 COSTS_N_INSNS (4), /* fp */
490 COSTS_N_INSNS (4), /* dmul */
491 COSTS_N_INSNS (31), /* sdiv */
492 COSTS_N_INSNS (31), /* ddiv */
493 128, /* cache line size */
494 128, /* l1 cache */
495 2048, /* l2 cache */
496 1, /* streams */
499 /* Instruction costs on MPCCORE processors. */
500 static const
501 struct processor_costs mpccore_cost = {
502 COSTS_N_INSNS (2), /* mulsi */
503 COSTS_N_INSNS (2), /* mulsi_const */
504 COSTS_N_INSNS (2), /* mulsi_const9 */
505 COSTS_N_INSNS (2), /* muldi */
506 COSTS_N_INSNS (6), /* divsi */
507 COSTS_N_INSNS (6), /* divdi */
508 COSTS_N_INSNS (4), /* fp */
509 COSTS_N_INSNS (5), /* dmul */
510 COSTS_N_INSNS (10), /* sdiv */
511 COSTS_N_INSNS (17), /* ddiv */
512 32, /* cache line size */
513 4, /* l1 cache */
514 16, /* l2 cache */
515 1, /* streams */
518 /* Instruction costs on PPC403 processors. */
519 static const
520 struct processor_costs ppc403_cost = {
521 COSTS_N_INSNS (4), /* mulsi */
522 COSTS_N_INSNS (4), /* mulsi_const */
523 COSTS_N_INSNS (4), /* mulsi_const9 */
524 COSTS_N_INSNS (4), /* muldi */
525 COSTS_N_INSNS (33), /* divsi */
526 COSTS_N_INSNS (33), /* divdi */
527 COSTS_N_INSNS (11), /* fp */
528 COSTS_N_INSNS (11), /* dmul */
529 COSTS_N_INSNS (11), /* sdiv */
530 COSTS_N_INSNS (11), /* ddiv */
531 32, /* cache line size */
532 4, /* l1 cache */
533 16, /* l2 cache */
534 1, /* streams */
537 /* Instruction costs on PPC405 processors. */
538 static const
539 struct processor_costs ppc405_cost = {
540 COSTS_N_INSNS (5), /* mulsi */
541 COSTS_N_INSNS (4), /* mulsi_const */
542 COSTS_N_INSNS (3), /* mulsi_const9 */
543 COSTS_N_INSNS (5), /* muldi */
544 COSTS_N_INSNS (35), /* divsi */
545 COSTS_N_INSNS (35), /* divdi */
546 COSTS_N_INSNS (11), /* fp */
547 COSTS_N_INSNS (11), /* dmul */
548 COSTS_N_INSNS (11), /* sdiv */
549 COSTS_N_INSNS (11), /* ddiv */
550 32, /* cache line size */
551 16, /* l1 cache */
552 128, /* l2 cache */
553 1, /* streams */
556 /* Instruction costs on PPC440 processors. */
557 static const
558 struct processor_costs ppc440_cost = {
559 COSTS_N_INSNS (3), /* mulsi */
560 COSTS_N_INSNS (2), /* mulsi_const */
561 COSTS_N_INSNS (2), /* mulsi_const9 */
562 COSTS_N_INSNS (3), /* muldi */
563 COSTS_N_INSNS (34), /* divsi */
564 COSTS_N_INSNS (34), /* divdi */
565 COSTS_N_INSNS (5), /* fp */
566 COSTS_N_INSNS (5), /* dmul */
567 COSTS_N_INSNS (19), /* sdiv */
568 COSTS_N_INSNS (33), /* ddiv */
569 32, /* cache line size */
570 32, /* l1 cache */
571 256, /* l2 cache */
572 1, /* streams */
575 /* Instruction costs on PPC476 processors. */
576 static const
577 struct processor_costs ppc476_cost = {
578 COSTS_N_INSNS (4), /* mulsi */
579 COSTS_N_INSNS (4), /* mulsi_const */
580 COSTS_N_INSNS (4), /* mulsi_const9 */
581 COSTS_N_INSNS (4), /* muldi */
582 COSTS_N_INSNS (11), /* divsi */
583 COSTS_N_INSNS (11), /* divdi */
584 COSTS_N_INSNS (6), /* fp */
585 COSTS_N_INSNS (6), /* dmul */
586 COSTS_N_INSNS (19), /* sdiv */
587 COSTS_N_INSNS (33), /* ddiv */
588 32, /* l1 cache line size */
589 32, /* l1 cache */
590 512, /* l2 cache */
591 1, /* streams */
594 /* Instruction costs on PPC601 processors. */
595 static const
596 struct processor_costs ppc601_cost = {
597 COSTS_N_INSNS (5), /* mulsi */
598 COSTS_N_INSNS (5), /* mulsi_const */
599 COSTS_N_INSNS (5), /* mulsi_const9 */
600 COSTS_N_INSNS (5), /* muldi */
601 COSTS_N_INSNS (36), /* divsi */
602 COSTS_N_INSNS (36), /* divdi */
603 COSTS_N_INSNS (4), /* fp */
604 COSTS_N_INSNS (5), /* dmul */
605 COSTS_N_INSNS (17), /* sdiv */
606 COSTS_N_INSNS (31), /* ddiv */
607 32, /* cache line size */
608 32, /* l1 cache */
609 256, /* l2 cache */
610 1, /* streams */
613 /* Instruction costs on PPC603 processors. */
614 static const
615 struct processor_costs ppc603_cost = {
616 COSTS_N_INSNS (5), /* mulsi */
617 COSTS_N_INSNS (3), /* mulsi_const */
618 COSTS_N_INSNS (2), /* mulsi_const9 */
619 COSTS_N_INSNS (5), /* muldi */
620 COSTS_N_INSNS (37), /* divsi */
621 COSTS_N_INSNS (37), /* divdi */
622 COSTS_N_INSNS (3), /* fp */
623 COSTS_N_INSNS (4), /* dmul */
624 COSTS_N_INSNS (18), /* sdiv */
625 COSTS_N_INSNS (33), /* ddiv */
626 32, /* cache line size */
627 8, /* l1 cache */
628 64, /* l2 cache */
629 1, /* streams */
632 /* Instruction costs on PPC604 processors. */
633 static const
634 struct processor_costs ppc604_cost = {
635 COSTS_N_INSNS (4), /* mulsi */
636 COSTS_N_INSNS (4), /* mulsi_const */
637 COSTS_N_INSNS (4), /* mulsi_const9 */
638 COSTS_N_INSNS (4), /* muldi */
639 COSTS_N_INSNS (20), /* divsi */
640 COSTS_N_INSNS (20), /* divdi */
641 COSTS_N_INSNS (3), /* fp */
642 COSTS_N_INSNS (3), /* dmul */
643 COSTS_N_INSNS (18), /* sdiv */
644 COSTS_N_INSNS (32), /* ddiv */
645 32, /* cache line size */
646 16, /* l1 cache */
647 512, /* l2 cache */
648 1, /* streams */
651 /* Instruction costs on PPC604e processors. */
652 static const
653 struct processor_costs ppc604e_cost = {
654 COSTS_N_INSNS (2), /* mulsi */
655 COSTS_N_INSNS (2), /* mulsi_const */
656 COSTS_N_INSNS (2), /* mulsi_const9 */
657 COSTS_N_INSNS (2), /* muldi */
658 COSTS_N_INSNS (20), /* divsi */
659 COSTS_N_INSNS (20), /* divdi */
660 COSTS_N_INSNS (3), /* fp */
661 COSTS_N_INSNS (3), /* dmul */
662 COSTS_N_INSNS (18), /* sdiv */
663 COSTS_N_INSNS (32), /* ddiv */
664 32, /* cache line size */
665 32, /* l1 cache */
666 1024, /* l2 cache */
667 1, /* streams */
670 /* Instruction costs on PPC620 processors. */
671 static const
672 struct processor_costs ppc620_cost = {
673 COSTS_N_INSNS (5), /* mulsi */
674 COSTS_N_INSNS (4), /* mulsi_const */
675 COSTS_N_INSNS (3), /* mulsi_const9 */
676 COSTS_N_INSNS (7), /* muldi */
677 COSTS_N_INSNS (21), /* divsi */
678 COSTS_N_INSNS (37), /* divdi */
679 COSTS_N_INSNS (3), /* fp */
680 COSTS_N_INSNS (3), /* dmul */
681 COSTS_N_INSNS (18), /* sdiv */
682 COSTS_N_INSNS (32), /* ddiv */
683 128, /* cache line size */
684 32, /* l1 cache */
685 1024, /* l2 cache */
686 1, /* streams */
689 /* Instruction costs on PPC630 processors. */
690 static const
691 struct processor_costs ppc630_cost = {
692 COSTS_N_INSNS (5), /* mulsi */
693 COSTS_N_INSNS (4), /* mulsi_const */
694 COSTS_N_INSNS (3), /* mulsi_const9 */
695 COSTS_N_INSNS (7), /* muldi */
696 COSTS_N_INSNS (21), /* divsi */
697 COSTS_N_INSNS (37), /* divdi */
698 COSTS_N_INSNS (3), /* fp */
699 COSTS_N_INSNS (3), /* dmul */
700 COSTS_N_INSNS (17), /* sdiv */
701 COSTS_N_INSNS (21), /* ddiv */
702 128, /* cache line size */
703 64, /* l1 cache */
704 1024, /* l2 cache */
705 1, /* streams */
708 /* Instruction costs on Cell processor. */
709 /* COSTS_N_INSNS (1) ~ one add. */
710 static const
711 struct processor_costs ppccell_cost = {
712 COSTS_N_INSNS (9/2)+2, /* mulsi */
713 COSTS_N_INSNS (6/2), /* mulsi_const */
714 COSTS_N_INSNS (6/2), /* mulsi_const9 */
715 COSTS_N_INSNS (15/2)+2, /* muldi */
716 COSTS_N_INSNS (38/2), /* divsi */
717 COSTS_N_INSNS (70/2), /* divdi */
718 COSTS_N_INSNS (10/2), /* fp */
719 COSTS_N_INSNS (10/2), /* dmul */
720 COSTS_N_INSNS (74/2), /* sdiv */
721 COSTS_N_INSNS (74/2), /* ddiv */
722 128, /* cache line size */
723 32, /* l1 cache */
724 512, /* l2 cache */
725 6, /* streams */
728 /* Instruction costs on PPC750 and PPC7400 processors. */
729 static const
730 struct processor_costs ppc750_cost = {
731 COSTS_N_INSNS (5), /* mulsi */
732 COSTS_N_INSNS (3), /* mulsi_const */
733 COSTS_N_INSNS (2), /* mulsi_const9 */
734 COSTS_N_INSNS (5), /* muldi */
735 COSTS_N_INSNS (17), /* divsi */
736 COSTS_N_INSNS (17), /* divdi */
737 COSTS_N_INSNS (3), /* fp */
738 COSTS_N_INSNS (3), /* dmul */
739 COSTS_N_INSNS (17), /* sdiv */
740 COSTS_N_INSNS (31), /* ddiv */
741 32, /* cache line size */
742 32, /* l1 cache */
743 512, /* l2 cache */
744 1, /* streams */
747 /* Instruction costs on PPC7450 processors. */
748 static const
749 struct processor_costs ppc7450_cost = {
750 COSTS_N_INSNS (4), /* mulsi */
751 COSTS_N_INSNS (3), /* mulsi_const */
752 COSTS_N_INSNS (3), /* mulsi_const9 */
753 COSTS_N_INSNS (4), /* muldi */
754 COSTS_N_INSNS (23), /* divsi */
755 COSTS_N_INSNS (23), /* divdi */
756 COSTS_N_INSNS (5), /* fp */
757 COSTS_N_INSNS (5), /* dmul */
758 COSTS_N_INSNS (21), /* sdiv */
759 COSTS_N_INSNS (35), /* ddiv */
760 32, /* cache line size */
761 32, /* l1 cache */
762 1024, /* l2 cache */
763 1, /* streams */
766 /* Instruction costs on PPC8540 processors. */
767 static const
768 struct processor_costs ppc8540_cost = {
769 COSTS_N_INSNS (4), /* mulsi */
770 COSTS_N_INSNS (4), /* mulsi_const */
771 COSTS_N_INSNS (4), /* mulsi_const9 */
772 COSTS_N_INSNS (4), /* muldi */
773 COSTS_N_INSNS (19), /* divsi */
774 COSTS_N_INSNS (19), /* divdi */
775 COSTS_N_INSNS (4), /* fp */
776 COSTS_N_INSNS (4), /* dmul */
777 COSTS_N_INSNS (29), /* sdiv */
778 COSTS_N_INSNS (29), /* ddiv */
779 32, /* cache line size */
780 32, /* l1 cache */
781 256, /* l2 cache */
782 1, /* prefetch streams /*/
785 /* Instruction costs on E300C2 and E300C3 cores. */
786 static const
787 struct processor_costs ppce300c2c3_cost = {
788 COSTS_N_INSNS (4), /* mulsi */
789 COSTS_N_INSNS (4), /* mulsi_const */
790 COSTS_N_INSNS (4), /* mulsi_const9 */
791 COSTS_N_INSNS (4), /* muldi */
792 COSTS_N_INSNS (19), /* divsi */
793 COSTS_N_INSNS (19), /* divdi */
794 COSTS_N_INSNS (3), /* fp */
795 COSTS_N_INSNS (4), /* dmul */
796 COSTS_N_INSNS (18), /* sdiv */
797 COSTS_N_INSNS (33), /* ddiv */
799 16, /* l1 cache */
800 16, /* l2 cache */
801 1, /* prefetch streams /*/
804 /* Instruction costs on PPCE500MC processors. */
805 static const
806 struct processor_costs ppce500mc_cost = {
807 COSTS_N_INSNS (4), /* mulsi */
808 COSTS_N_INSNS (4), /* mulsi_const */
809 COSTS_N_INSNS (4), /* mulsi_const9 */
810 COSTS_N_INSNS (4), /* muldi */
811 COSTS_N_INSNS (14), /* divsi */
812 COSTS_N_INSNS (14), /* divdi */
813 COSTS_N_INSNS (8), /* fp */
814 COSTS_N_INSNS (10), /* dmul */
815 COSTS_N_INSNS (36), /* sdiv */
816 COSTS_N_INSNS (66), /* ddiv */
817 64, /* cache line size */
818 32, /* l1 cache */
819 128, /* l2 cache */
820 1, /* prefetch streams /*/
823 /* Instruction costs on PPCE500MC64 processors. */
824 static const
825 struct processor_costs ppce500mc64_cost = {
826 COSTS_N_INSNS (4), /* mulsi */
827 COSTS_N_INSNS (4), /* mulsi_const */
828 COSTS_N_INSNS (4), /* mulsi_const9 */
829 COSTS_N_INSNS (4), /* muldi */
830 COSTS_N_INSNS (14), /* divsi */
831 COSTS_N_INSNS (14), /* divdi */
832 COSTS_N_INSNS (4), /* fp */
833 COSTS_N_INSNS (10), /* dmul */
834 COSTS_N_INSNS (36), /* sdiv */
835 COSTS_N_INSNS (66), /* ddiv */
836 64, /* cache line size */
837 32, /* l1 cache */
838 128, /* l2 cache */
839 1, /* prefetch streams /*/
842 /* Instruction costs on AppliedMicro Titan processors. */
843 static const
844 struct processor_costs titan_cost = {
845 COSTS_N_INSNS (5), /* mulsi */
846 COSTS_N_INSNS (5), /* mulsi_const */
847 COSTS_N_INSNS (5), /* mulsi_const9 */
848 COSTS_N_INSNS (5), /* muldi */
849 COSTS_N_INSNS (18), /* divsi */
850 COSTS_N_INSNS (18), /* divdi */
851 COSTS_N_INSNS (10), /* fp */
852 COSTS_N_INSNS (10), /* dmul */
853 COSTS_N_INSNS (46), /* sdiv */
854 COSTS_N_INSNS (72), /* ddiv */
855 32, /* cache line size */
856 32, /* l1 cache */
857 512, /* l2 cache */
858 1, /* prefetch streams /*/
861 /* Instruction costs on POWER4 and POWER5 processors. */
862 static const
863 struct processor_costs power4_cost = {
864 COSTS_N_INSNS (3), /* mulsi */
865 COSTS_N_INSNS (2), /* mulsi_const */
866 COSTS_N_INSNS (2), /* mulsi_const9 */
867 COSTS_N_INSNS (4), /* muldi */
868 COSTS_N_INSNS (18), /* divsi */
869 COSTS_N_INSNS (34), /* divdi */
870 COSTS_N_INSNS (3), /* fp */
871 COSTS_N_INSNS (3), /* dmul */
872 COSTS_N_INSNS (17), /* sdiv */
873 COSTS_N_INSNS (17), /* ddiv */
874 128, /* cache line size */
875 32, /* l1 cache */
876 1024, /* l2 cache */
877 8, /* prefetch streams /*/
880 /* Instruction costs on POWER6 processors. */
881 static const
882 struct processor_costs power6_cost = {
883 COSTS_N_INSNS (8), /* mulsi */
884 COSTS_N_INSNS (8), /* mulsi_const */
885 COSTS_N_INSNS (8), /* mulsi_const9 */
886 COSTS_N_INSNS (8), /* muldi */
887 COSTS_N_INSNS (22), /* divsi */
888 COSTS_N_INSNS (28), /* divdi */
889 COSTS_N_INSNS (3), /* fp */
890 COSTS_N_INSNS (3), /* dmul */
891 COSTS_N_INSNS (13), /* sdiv */
892 COSTS_N_INSNS (16), /* ddiv */
893 128, /* cache line size */
894 64, /* l1 cache */
895 2048, /* l2 cache */
896 16, /* prefetch streams */
899 /* Instruction costs on POWER7 processors. */
900 static const
901 struct processor_costs power7_cost = {
902 COSTS_N_INSNS (2), /* mulsi */
903 COSTS_N_INSNS (2), /* mulsi_const */
904 COSTS_N_INSNS (2), /* mulsi_const9 */
905 COSTS_N_INSNS (2), /* muldi */
906 COSTS_N_INSNS (18), /* divsi */
907 COSTS_N_INSNS (34), /* divdi */
908 COSTS_N_INSNS (3), /* fp */
909 COSTS_N_INSNS (3), /* dmul */
910 COSTS_N_INSNS (13), /* sdiv */
911 COSTS_N_INSNS (16), /* ddiv */
912 128, /* cache line size */
913 32, /* l1 cache */
914 256, /* l2 cache */
915 12, /* prefetch streams */
918 /* Instruction costs on POWER A2 processors. */
919 static const
920 struct processor_costs ppca2_cost = {
921 COSTS_N_INSNS (16), /* mulsi */
922 COSTS_N_INSNS (16), /* mulsi_const */
923 COSTS_N_INSNS (16), /* mulsi_const9 */
924 COSTS_N_INSNS (16), /* muldi */
925 COSTS_N_INSNS (22), /* divsi */
926 COSTS_N_INSNS (28), /* divdi */
927 COSTS_N_INSNS (3), /* fp */
928 COSTS_N_INSNS (3), /* dmul */
929 COSTS_N_INSNS (59), /* sdiv */
930 COSTS_N_INSNS (72), /* ddiv */
932 16, /* l1 cache */
933 2048, /* l2 cache */
934 16, /* prefetch streams */
938 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
939 #undef RS6000_BUILTIN
940 #undef RS6000_BUILTIN_EQUATE
941 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
942 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
944 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
946 #include "rs6000-builtin.def"
949 #undef RS6000_BUILTIN
950 #undef RS6000_BUILTIN_EQUATE
953 static bool rs6000_function_ok_for_sibcall (tree, tree);
954 static const char *rs6000_invalid_within_doloop (const_rtx);
955 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
956 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
957 static rtx rs6000_generate_compare (rtx, enum machine_mode);
958 static void rs6000_emit_stack_tie (void);
959 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
960 static bool spe_func_has_64bit_regs_p (void);
961 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
962 int, HOST_WIDE_INT);
963 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
964 static unsigned rs6000_hash_constant (rtx);
965 static unsigned toc_hash_function (const void *);
966 static int toc_hash_eq (const void *, const void *);
967 static bool reg_offset_addressing_ok_p (enum machine_mode);
968 static bool virtual_stack_registers_memory_p (rtx);
969 static bool constant_pool_expr_p (rtx);
970 static bool legitimate_small_data_p (enum machine_mode, rtx);
971 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
972 static struct machine_function * rs6000_init_machine_status (void);
973 static bool rs6000_assemble_integer (rtx, unsigned int, int);
974 static bool no_global_regs_above (int, bool);
975 #ifdef HAVE_GAS_HIDDEN
976 static void rs6000_assemble_visibility (tree, int);
977 #endif
978 static int rs6000_ra_ever_killed (void);
979 static bool rs6000_attribute_takes_identifier_p (const_tree);
980 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
981 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
982 static bool rs6000_ms_bitfield_layout_p (const_tree);
983 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
984 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
985 static const char *rs6000_mangle_type (const_tree);
986 static void rs6000_set_default_type_attributes (tree);
987 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
988 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
989 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
990 enum machine_mode, bool, bool, bool);
991 static bool rs6000_reg_live_or_pic_offset_p (int);
992 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
993 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
994 static void rs6000_restore_saved_cr (rtx, int);
995 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
996 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
997 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
998 tree);
999 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
1000 static bool rs6000_return_in_memory (const_tree, const_tree);
1001 static rtx rs6000_function_value (const_tree, const_tree, bool);
1002 static void rs6000_file_start (void);
1003 #if TARGET_ELF
1004 static int rs6000_elf_reloc_rw_mask (void);
1005 static void rs6000_elf_asm_out_constructor (rtx, int);
1006 static void rs6000_elf_asm_out_destructor (rtx, int);
1007 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
1008 static void rs6000_elf_asm_init_sections (void);
1009 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
1010 unsigned HOST_WIDE_INT);
1011 static void rs6000_elf_encode_section_info (tree, rtx, int)
1012 ATTRIBUTE_UNUSED;
1013 #endif
1014 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
1015 static void rs6000_alloc_sdmode_stack_slot (void);
1016 static void rs6000_instantiate_decls (void);
1017 #if TARGET_XCOFF
1018 static void rs6000_xcoff_asm_output_anchor (rtx);
1019 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1020 static void rs6000_xcoff_asm_init_sections (void);
1021 static int rs6000_xcoff_reloc_rw_mask (void);
1022 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1023 static section *rs6000_xcoff_select_section (tree, int,
1024 unsigned HOST_WIDE_INT);
1025 static void rs6000_xcoff_unique_section (tree, int);
1026 static section *rs6000_xcoff_select_rtx_section
1027 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1028 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1029 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1030 static void rs6000_xcoff_file_start (void);
1031 static void rs6000_xcoff_file_end (void);
1032 #endif
1033 static int rs6000_variable_issue (FILE *, int, rtx, int);
1034 static int rs6000_register_move_cost (enum machine_mode,
1035 reg_class_t, reg_class_t);
1036 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
1037 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1038 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1039 static int rs6000_debug_address_cost (rtx, bool);
1040 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1041 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1042 static void rs6000_sched_init (FILE *, int, int);
1043 static bool is_microcoded_insn (rtx);
1044 static bool is_nonpipeline_insn (rtx);
1045 static bool is_cracked_insn (rtx);
1046 static bool is_branch_slot_insn (rtx);
1047 static bool is_load_insn (rtx);
1048 static rtx get_store_dest (rtx pat);
1049 static bool is_store_insn (rtx);
1050 static bool set_to_load_agen (rtx,rtx);
1051 static bool adjacent_mem_locations (rtx,rtx);
1052 static int rs6000_adjust_priority (rtx, int);
1053 static int rs6000_issue_rate (void);
1054 static bool rs6000_is_costly_dependence (dep_t, int, int);
1055 static rtx get_next_active_insn (rtx, rtx);
1056 static bool insn_terminates_group_p (rtx , enum group_termination);
1057 static bool insn_must_be_first_in_group (rtx);
1058 static bool insn_must_be_last_in_group (rtx);
1059 static bool is_costly_group (rtx *, rtx);
1060 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1061 static int redefine_groups (FILE *, int, rtx, rtx);
1062 static int pad_groups (FILE *, int, rtx, rtx);
1063 static void rs6000_sched_finish (FILE *, int);
1064 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1065 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1066 static int rs6000_use_sched_lookahead (void);
1067 static int rs6000_use_sched_lookahead_guard (rtx);
1068 static void * rs6000_alloc_sched_context (void);
1069 static void rs6000_init_sched_context (void *, bool);
1070 static void rs6000_set_sched_context (void *);
1071 static void rs6000_free_sched_context (void *);
1072 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1073 static tree rs6000_builtin_mask_for_load (void);
1074 static tree rs6000_builtin_mul_widen_even (tree);
1075 static tree rs6000_builtin_mul_widen_odd (tree);
1076 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1077 static tree rs6000_builtin_vec_perm (tree, tree *);
1078 static bool rs6000_builtin_support_vector_misalignment (enum
1079 machine_mode,
1080 const_tree,
1081 int, bool);
1082 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1083 tree, int);
1085 static void def_builtin (int, const char *, tree, int);
1086 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1087 static void rs6000_init_builtins (void);
1088 static tree rs6000_builtin_decl (unsigned, bool);
1090 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1091 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1092 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1093 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1094 static void altivec_init_builtins (void);
1095 static unsigned builtin_hash_function (const void *);
1096 static int builtin_hash_eq (const void *, const void *);
1097 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1098 enum machine_mode, enum machine_mode,
1099 enum rs6000_builtins, const char *name);
1100 static void rs6000_common_init_builtins (void);
1101 static void rs6000_init_libfuncs (void);
1103 static void paired_init_builtins (void);
1104 static rtx paired_expand_builtin (tree, rtx, bool *);
1105 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1106 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1107 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1109 static void enable_mask_for_builtins (struct builtin_description *, int,
1110 enum rs6000_builtins,
1111 enum rs6000_builtins);
1112 static void spe_init_builtins (void);
1113 static rtx spe_expand_builtin (tree, rtx, bool *);
1114 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1115 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1116 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1117 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1118 static rs6000_stack_t *rs6000_stack_info (void);
1119 static void debug_stack_info (rs6000_stack_t *);
1121 static rtx altivec_expand_builtin (tree, rtx, bool *);
1122 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1123 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1124 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1125 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1126 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1127 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1128 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1129 static rtx altivec_expand_vec_set_builtin (tree);
1130 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1131 static int get_element_number (tree, tree);
1132 static bool rs6000_handle_option (size_t, const char *, int);
1133 static void rs6000_parse_tls_size_option (void);
1134 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1135 static int first_altivec_reg_to_save (void);
1136 static unsigned int compute_vrsave_mask (void);
1137 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1138 static void is_altivec_return_reg (rtx, void *);
1139 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1140 int easy_vector_constant (rtx, enum machine_mode);
1141 static rtx rs6000_dwarf_register_span (rtx);
1142 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1143 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1144 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1145 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1146 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1147 static rtx rs6000_delegitimize_address (rtx);
1148 static rtx rs6000_tls_get_addr (void);
1149 static rtx rs6000_got_sym (void);
1150 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1151 static const char *rs6000_get_some_local_dynamic_name (void);
1152 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1153 static rtx rs6000_complex_function_value (enum machine_mode);
1154 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1155 enum machine_mode, tree);
1156 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1157 HOST_WIDE_INT, int);
1158 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1159 tree, HOST_WIDE_INT);
1160 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1161 HOST_WIDE_INT,
1162 rtx[], int *);
1163 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1164 const_tree, HOST_WIDE_INT,
1165 rtx[], int *);
1166 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1167 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1168 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1169 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1170 enum machine_mode, tree,
1171 int *, int);
1172 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1173 const_tree, bool);
1174 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1175 tree, bool);
1176 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1177 #if TARGET_MACHO
1178 static void macho_branch_islands (void);
1179 static int no_previous_def (tree function_name);
1180 static tree get_prev_label (tree function_name);
1181 static void rs6000_darwin_file_start (void);
1182 #endif
1184 static tree rs6000_build_builtin_va_list (void);
1185 static void rs6000_va_start (tree, rtx);
1186 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1187 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1188 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1189 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1190 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1191 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1192 enum machine_mode);
1193 static tree rs6000_stack_protect_fail (void);
1195 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1196 int, int *);
1198 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1199 int, int, int *);
1201 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1202 int, int *)
1203 = rs6000_legitimize_reload_address;
1205 static bool rs6000_mode_dependent_address_p (const_rtx);
1206 static bool rs6000_mode_dependent_address (const_rtx);
1207 static bool rs6000_debug_mode_dependent_address (const_rtx);
1208 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1209 = rs6000_mode_dependent_address;
1211 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1212 enum machine_mode, rtx);
1213 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1214 enum machine_mode,
1215 rtx);
1216 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1217 enum machine_mode, rtx)
1218 = rs6000_secondary_reload_class;
1220 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1221 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1222 enum reg_class);
1223 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1224 = rs6000_preferred_reload_class;
1226 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1227 enum machine_mode);
1229 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1230 enum reg_class,
1231 enum machine_mode);
1233 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1234 enum machine_mode)
1235 = rs6000_secondary_memory_needed;
1237 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1238 enum machine_mode,
1239 enum reg_class);
1240 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1241 enum machine_mode,
1242 enum reg_class);
1244 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1245 enum machine_mode,
1246 enum reg_class)
1247 = rs6000_cannot_change_mode_class;
1249 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1250 enum machine_mode,
1251 struct secondary_reload_info *);
1253 static const reg_class_t *rs6000_ira_cover_classes (void);
1255 const int INSN_NOT_AVAILABLE = -1;
1256 static enum machine_mode rs6000_eh_return_filter_mode (void);
1257 static bool rs6000_can_eliminate (const int, const int);
1258 static void rs6000_trampoline_init (rtx, tree, rtx);
1260 /* Hash table stuff for keeping track of TOC entries. */
1262 struct GTY(()) toc_hash_struct
1264 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1265 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1266 rtx key;
1267 enum machine_mode key_mode;
1268 int labelno;
1271 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1273 /* Hash table to keep track of the argument types for builtin functions. */
1275 struct GTY(()) builtin_hash_struct
1277 tree type;
1278 enum machine_mode mode[4]; /* return value + 3 arguments. */
1279 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1282 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1284 /* Default register names. */
1285 char rs6000_reg_names[][8] =
1287 "0", "1", "2", "3", "4", "5", "6", "7",
1288 "8", "9", "10", "11", "12", "13", "14", "15",
1289 "16", "17", "18", "19", "20", "21", "22", "23",
1290 "24", "25", "26", "27", "28", "29", "30", "31",
1291 "0", "1", "2", "3", "4", "5", "6", "7",
1292 "8", "9", "10", "11", "12", "13", "14", "15",
1293 "16", "17", "18", "19", "20", "21", "22", "23",
1294 "24", "25", "26", "27", "28", "29", "30", "31",
1295 "mq", "lr", "ctr","ap",
1296 "0", "1", "2", "3", "4", "5", "6", "7",
1297 "ca",
1298 /* AltiVec registers. */
1299 "0", "1", "2", "3", "4", "5", "6", "7",
1300 "8", "9", "10", "11", "12", "13", "14", "15",
1301 "16", "17", "18", "19", "20", "21", "22", "23",
1302 "24", "25", "26", "27", "28", "29", "30", "31",
1303 "vrsave", "vscr",
1304 /* SPE registers. */
1305 "spe_acc", "spefscr",
1306 /* Soft frame pointer. */
1307 "sfp"
1310 #ifdef TARGET_REGNAMES
1311 static const char alt_reg_names[][8] =
1313 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1314 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1315 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1316 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1317 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1318 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1319 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1320 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1321 "mq", "lr", "ctr", "ap",
1322 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1323 "ca",
1324 /* AltiVec registers. */
1325 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1326 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1327 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1328 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1329 "vrsave", "vscr",
1330 /* SPE registers. */
1331 "spe_acc", "spefscr",
1332 /* Soft frame pointer. */
1333 "sfp"
1335 #endif
1337 /* Table of valid machine attributes. */
1339 static const struct attribute_spec rs6000_attribute_table[] =
1341 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1342 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1343 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1344 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1345 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1346 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1347 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1348 SUBTARGET_ATTRIBUTE_TABLE,
1349 #endif
1350 { NULL, 0, 0, false, false, false, NULL }
1353 #ifndef MASK_STRICT_ALIGN
1354 #define MASK_STRICT_ALIGN 0
1355 #endif
1356 #ifndef TARGET_PROFILE_KERNEL
1357 #define TARGET_PROFILE_KERNEL 0
1358 #endif
1360 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1361 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1363 /* Initialize the GCC target structure. */
1364 #undef TARGET_ATTRIBUTE_TABLE
1365 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1366 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1367 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1368 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1369 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1371 #undef TARGET_ASM_ALIGNED_DI_OP
1372 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1374 /* Default unaligned ops are only provided for ELF. Find the ops needed
1375 for non-ELF systems. */
1376 #ifndef OBJECT_FORMAT_ELF
1377 #if TARGET_XCOFF
1378 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1379 64-bit targets. */
1380 #undef TARGET_ASM_UNALIGNED_HI_OP
1381 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1382 #undef TARGET_ASM_UNALIGNED_SI_OP
1383 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1384 #undef TARGET_ASM_UNALIGNED_DI_OP
1385 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1386 #else
1387 /* For Darwin. */
1388 #undef TARGET_ASM_UNALIGNED_HI_OP
1389 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1390 #undef TARGET_ASM_UNALIGNED_SI_OP
1391 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1392 #undef TARGET_ASM_UNALIGNED_DI_OP
1393 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1394 #undef TARGET_ASM_ALIGNED_DI_OP
1395 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1396 #endif
1397 #endif
1399 /* This hook deals with fixups for relocatable code and DI-mode objects
1400 in 64-bit code. */
1401 #undef TARGET_ASM_INTEGER
1402 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1404 #ifdef HAVE_GAS_HIDDEN
1405 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1406 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1407 #endif
1409 #undef TARGET_HAVE_TLS
1410 #define TARGET_HAVE_TLS HAVE_AS_TLS
1412 #undef TARGET_CANNOT_FORCE_CONST_MEM
1413 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1415 #undef TARGET_DELEGITIMIZE_ADDRESS
1416 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1418 #undef TARGET_ASM_FUNCTION_PROLOGUE
1419 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1420 #undef TARGET_ASM_FUNCTION_EPILOGUE
1421 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1423 #undef TARGET_LEGITIMIZE_ADDRESS
1424 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1426 #undef TARGET_SCHED_VARIABLE_ISSUE
1427 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1429 #undef TARGET_SCHED_ISSUE_RATE
1430 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1431 #undef TARGET_SCHED_ADJUST_COST
1432 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1433 #undef TARGET_SCHED_ADJUST_PRIORITY
1434 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1435 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1436 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1437 #undef TARGET_SCHED_INIT
1438 #define TARGET_SCHED_INIT rs6000_sched_init
1439 #undef TARGET_SCHED_FINISH
1440 #define TARGET_SCHED_FINISH rs6000_sched_finish
1441 #undef TARGET_SCHED_REORDER
1442 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1443 #undef TARGET_SCHED_REORDER2
1444 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1446 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1447 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1449 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1450 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1452 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1453 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1454 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1455 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1456 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1457 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1458 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1459 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1461 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1462 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1463 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1464 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1465 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1466 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1467 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1468 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1469 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1470 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1471 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1472 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1473 rs6000_builtin_support_vector_misalignment
1474 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1475 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1476 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1477 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1478 rs6000_builtin_vectorization_cost
1480 #undef TARGET_INIT_BUILTINS
1481 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1482 #undef TARGET_BUILTIN_DECL
1483 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1485 #undef TARGET_EXPAND_BUILTIN
1486 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1488 #undef TARGET_MANGLE_TYPE
1489 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1491 #undef TARGET_INIT_LIBFUNCS
1492 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1494 #if TARGET_MACHO
1495 #undef TARGET_BINDS_LOCAL_P
1496 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1497 #endif
1499 #undef TARGET_MS_BITFIELD_LAYOUT_P
1500 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1502 #undef TARGET_ASM_OUTPUT_MI_THUNK
1503 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1505 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1506 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1508 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1509 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1511 #undef TARGET_INVALID_WITHIN_DOLOOP
1512 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1514 #undef TARGET_REGISTER_MOVE_COST
1515 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1516 #undef TARGET_MEMORY_MOVE_COST
1517 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1518 #undef TARGET_RTX_COSTS
1519 #define TARGET_RTX_COSTS rs6000_rtx_costs
1520 #undef TARGET_ADDRESS_COST
1521 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1523 #undef TARGET_DWARF_REGISTER_SPAN
1524 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1526 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1527 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1529 /* On rs6000, function arguments are promoted, as are function return
1530 values. */
1531 #undef TARGET_PROMOTE_FUNCTION_MODE
1532 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1534 #undef TARGET_RETURN_IN_MEMORY
1535 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1537 #undef TARGET_SETUP_INCOMING_VARARGS
1538 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1540 /* Always strict argument naming on rs6000. */
1541 #undef TARGET_STRICT_ARGUMENT_NAMING
1542 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1543 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1544 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1545 #undef TARGET_SPLIT_COMPLEX_ARG
1546 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1547 #undef TARGET_MUST_PASS_IN_STACK
1548 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1549 #undef TARGET_PASS_BY_REFERENCE
1550 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1551 #undef TARGET_ARG_PARTIAL_BYTES
1552 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1554 #undef TARGET_BUILD_BUILTIN_VA_LIST
1555 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1557 #undef TARGET_EXPAND_BUILTIN_VA_START
1558 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1560 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1561 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1563 #undef TARGET_EH_RETURN_FILTER_MODE
1564 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1566 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1567 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1569 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1570 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1572 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1573 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1575 #undef TARGET_HANDLE_OPTION
1576 #define TARGET_HANDLE_OPTION rs6000_handle_option
1578 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1579 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1580 rs6000_builtin_vectorized_function
1582 #undef TARGET_DEFAULT_TARGET_FLAGS
1583 #define TARGET_DEFAULT_TARGET_FLAGS \
1584 (TARGET_DEFAULT)
1586 #undef TARGET_STACK_PROTECT_FAIL
1587 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1589 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1590 The PowerPC architecture requires only weak consistency among
1591 processors--that is, memory accesses between processors need not be
1592 sequentially consistent and memory accesses among processors can occur
1593 in any order. The ability to order memory accesses weakly provides
1594 opportunities for more efficient use of the system bus. Unless a
1595 dependency exists, the 604e allows read operations to precede store
1596 operations. */
1597 #undef TARGET_RELAXED_ORDERING
1598 #define TARGET_RELAXED_ORDERING true
1600 #ifdef HAVE_AS_TLS
1601 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1602 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1603 #endif
1605 /* Use a 32-bit anchor range. This leads to sequences like:
1607 addis tmp,anchor,high
1608 add dest,tmp,low
1610 where tmp itself acts as an anchor, and can be shared between
1611 accesses to the same 64k page. */
1612 #undef TARGET_MIN_ANCHOR_OFFSET
1613 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1614 #undef TARGET_MAX_ANCHOR_OFFSET
1615 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1616 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1617 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1619 #undef TARGET_BUILTIN_RECIPROCAL
1620 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1622 #undef TARGET_EXPAND_TO_RTL_HOOK
1623 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1625 #undef TARGET_INSTANTIATE_DECLS
1626 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1628 #undef TARGET_SECONDARY_RELOAD
1629 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1631 #undef TARGET_IRA_COVER_CLASSES
1632 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1634 #undef TARGET_LEGITIMATE_ADDRESS_P
1635 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1637 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1638 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1640 #undef TARGET_CAN_ELIMINATE
1641 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1643 #undef TARGET_TRAMPOLINE_INIT
1644 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1646 #undef TARGET_FUNCTION_VALUE
1647 #define TARGET_FUNCTION_VALUE rs6000_function_value
1649 struct gcc_target targetm = TARGET_INITIALIZER;
1651 /* Return number of consecutive hard regs needed starting at reg REGNO
1652 to hold something of mode MODE.
1653 This is ordinarily the length in words of a value of mode MODE
1654 but can be less for certain modes in special long registers.
1656 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1657 scalar instructions. The upper 32 bits are only available to the
1658 SIMD instructions.
1660 POWER and PowerPC GPRs hold 32 bits worth;
1661 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1663 static int
1664 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1666 unsigned HOST_WIDE_INT reg_size;
1668 if (FP_REGNO_P (regno))
1669 reg_size = (VECTOR_MEM_VSX_P (mode)
1670 ? UNITS_PER_VSX_WORD
1671 : UNITS_PER_FP_WORD);
1673 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1674 reg_size = UNITS_PER_SPE_WORD;
1676 else if (ALTIVEC_REGNO_P (regno))
1677 reg_size = UNITS_PER_ALTIVEC_WORD;
1679 /* The value returned for SCmode in the E500 double case is 2 for
1680 ABI compatibility; storing an SCmode value in a single register
1681 would require function_arg and rs6000_spe_function_arg to handle
1682 SCmode so as to pass the value correctly in a pair of
1683 registers. */
1684 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1685 && !DECIMAL_FLOAT_MODE_P (mode))
1686 reg_size = UNITS_PER_FP_WORD;
1688 else
1689 reg_size = UNITS_PER_WORD;
1691 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1694 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1695 MODE. */
1696 static int
1697 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1699 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1701 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1702 implementations. Don't allow an item to be split between a FP register
1703 and an Altivec register. */
1704 if (VECTOR_MEM_VSX_P (mode))
1706 if (FP_REGNO_P (regno))
1707 return FP_REGNO_P (last_regno);
1709 if (ALTIVEC_REGNO_P (regno))
1710 return ALTIVEC_REGNO_P (last_regno);
1713 /* The GPRs can hold any mode, but values bigger than one register
1714 cannot go past R31. */
1715 if (INT_REGNO_P (regno))
1716 return INT_REGNO_P (last_regno);
1718 /* The float registers (except for VSX vector modes) can only hold floating
1719 modes and DImode. This excludes the 32-bit decimal float mode for
1720 now. */
1721 if (FP_REGNO_P (regno))
1723 if (SCALAR_FLOAT_MODE_P (mode)
1724 && (mode != TDmode || (regno % 2) == 0)
1725 && FP_REGNO_P (last_regno))
1726 return 1;
1728 if (GET_MODE_CLASS (mode) == MODE_INT
1729 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1730 return 1;
1732 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1733 && PAIRED_VECTOR_MODE (mode))
1734 return 1;
1736 return 0;
1739 /* The CR register can only hold CC modes. */
1740 if (CR_REGNO_P (regno))
1741 return GET_MODE_CLASS (mode) == MODE_CC;
1743 if (CA_REGNO_P (regno))
1744 return mode == BImode;
1746 /* AltiVec only in AldyVec registers. */
1747 if (ALTIVEC_REGNO_P (regno))
1748 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1750 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1751 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1752 return 1;
1754 /* We cannot put TImode anywhere except general register and it must be able
1755 to fit within the register set. In the future, allow TImode in the
1756 Altivec or VSX registers. */
1758 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1761 /* Print interesting facts about registers. */
1762 static void
1763 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1765 int r, m;
1767 for (r = first_regno; r <= last_regno; ++r)
1769 const char *comma = "";
1770 int len;
1772 if (first_regno == last_regno)
1773 fprintf (stderr, "%s:\t", reg_name);
1774 else
1775 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1777 len = 8;
1778 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1779 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1781 if (len > 70)
1783 fprintf (stderr, ",\n\t");
1784 len = 8;
1785 comma = "";
1788 if (rs6000_hard_regno_nregs[m][r] > 1)
1789 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1790 rs6000_hard_regno_nregs[m][r]);
1791 else
1792 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1794 comma = ", ";
1797 if (call_used_regs[r])
1799 if (len > 70)
1801 fprintf (stderr, ",\n\t");
1802 len = 8;
1803 comma = "";
1806 len += fprintf (stderr, "%s%s", comma, "call-used");
1807 comma = ", ";
1810 if (fixed_regs[r])
1812 if (len > 70)
1814 fprintf (stderr, ",\n\t");
1815 len = 8;
1816 comma = "";
1819 len += fprintf (stderr, "%s%s", comma, "fixed");
1820 comma = ", ";
1823 if (len > 70)
1825 fprintf (stderr, ",\n\t");
1826 comma = "";
1829 fprintf (stderr, "%sregno = %d\n", comma, r);
1833 /* Print various interesting information with -mdebug=reg. */
1834 static void
1835 rs6000_debug_reg_global (void)
1837 const char *nl = (const char *)0;
1838 int m;
1839 char costly_num[20];
1840 char nop_num[20];
1841 const char *costly_str;
1842 const char *nop_str;
1844 /* Map enum rs6000_vector to string. */
1845 static const char *rs6000_debug_vector_unit[] = {
1846 "none",
1847 "altivec",
1848 "vsx",
1849 "paired",
1850 "spe",
1851 "other"
1854 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1855 LAST_VIRTUAL_REGISTER);
1856 rs6000_debug_reg_print (0, 31, "gr");
1857 rs6000_debug_reg_print (32, 63, "fp");
1858 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1859 LAST_ALTIVEC_REGNO,
1860 "vs");
1861 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1862 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1863 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1864 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1865 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1866 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1867 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1868 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1869 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1871 fprintf (stderr,
1872 "\n"
1873 "d reg_class = %s\n"
1874 "f reg_class = %s\n"
1875 "v reg_class = %s\n"
1876 "wa reg_class = %s\n"
1877 "wd reg_class = %s\n"
1878 "wf reg_class = %s\n"
1879 "ws reg_class = %s\n\n",
1880 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1881 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1882 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1883 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1884 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1885 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1886 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1888 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1889 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1891 nl = "\n";
1892 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1893 GET_MODE_NAME (m),
1894 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1895 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1898 if (nl)
1899 fputs (nl, stderr);
1901 if (rs6000_recip_control)
1903 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1905 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1906 if (rs6000_recip_bits[m])
1908 fprintf (stderr,
1909 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1910 GET_MODE_NAME (m),
1911 (RS6000_RECIP_AUTO_RE_P (m)
1912 ? "auto"
1913 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1914 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1915 ? "auto"
1916 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1919 fputs ("\n", stderr);
1922 switch (rs6000_sched_costly_dep)
1924 case max_dep_latency:
1925 costly_str = "max_dep_latency";
1926 break;
1928 case no_dep_costly:
1929 costly_str = "no_dep_costly";
1930 break;
1932 case all_deps_costly:
1933 costly_str = "all_deps_costly";
1934 break;
1936 case true_store_to_load_dep_costly:
1937 costly_str = "true_store_to_load_dep_costly";
1938 break;
1940 case store_to_load_dep_costly:
1941 costly_str = "store_to_load_dep_costly";
1942 break;
1944 default:
1945 costly_str = costly_num;
1946 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1947 break;
1950 switch (rs6000_sched_insert_nops)
1952 case sched_finish_regroup_exact:
1953 nop_str = "sched_finish_regroup_exact";
1954 break;
1956 case sched_finish_pad_groups:
1957 nop_str = "sched_finish_pad_groups";
1958 break;
1960 case sched_finish_none:
1961 nop_str = "sched_finish_none";
1962 break;
1964 default:
1965 nop_str = nop_num;
1966 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1967 break;
1970 fprintf (stderr,
1971 "always_hint = %s\n"
1972 "align_branch_targets = %s\n"
1973 "sched_restricted_insns_priority = %d\n"
1974 "sched_costly_dep = %s\n"
1975 "sched_insert_nops = %s\n\n",
1976 rs6000_always_hint ? "true" : "false",
1977 rs6000_align_branch_targets ? "true" : "false",
1978 (int)rs6000_sched_restricted_insns_priority,
1979 costly_str, nop_str);
1982 /* Initialize the various global tables that are based on register size. */
1983 static void
1984 rs6000_init_hard_regno_mode_ok (void)
1986 int r, m, c;
1987 int align64;
1988 int align32;
1990 /* Precalculate REGNO_REG_CLASS. */
1991 rs6000_regno_regclass[0] = GENERAL_REGS;
1992 for (r = 1; r < 32; ++r)
1993 rs6000_regno_regclass[r] = BASE_REGS;
1995 for (r = 32; r < 64; ++r)
1996 rs6000_regno_regclass[r] = FLOAT_REGS;
1998 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1999 rs6000_regno_regclass[r] = NO_REGS;
2001 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2002 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2004 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2005 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2006 rs6000_regno_regclass[r] = CR_REGS;
2008 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2009 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2010 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2011 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2012 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2013 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2014 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2015 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2016 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2017 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2019 /* Precalculate vector information, this must be set up before the
2020 rs6000_hard_regno_nregs_internal below. */
2021 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2023 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2024 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2025 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2028 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2029 rs6000_constraints[c] = NO_REGS;
2031 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2032 believes it can use native alignment or still uses 128-bit alignment. */
2033 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2035 align64 = 64;
2036 align32 = 32;
2038 else
2040 align64 = 128;
2041 align32 = 128;
2044 /* V2DF mode, VSX only. */
2045 if (TARGET_VSX)
2047 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2048 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2049 rs6000_vector_align[V2DFmode] = align64;
2052 /* V4SF mode, either VSX or Altivec. */
2053 if (TARGET_VSX)
2055 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2056 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2057 rs6000_vector_align[V4SFmode] = align32;
2059 else if (TARGET_ALTIVEC)
2061 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2062 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2063 rs6000_vector_align[V4SFmode] = align32;
2066 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2067 and stores. */
2068 if (TARGET_ALTIVEC)
2070 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2071 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2072 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2073 rs6000_vector_align[V4SImode] = align32;
2074 rs6000_vector_align[V8HImode] = align32;
2075 rs6000_vector_align[V16QImode] = align32;
2077 if (TARGET_VSX)
2079 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2080 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2081 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2083 else
2085 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2086 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2087 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2091 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2092 Altivec doesn't have 64-bit support. */
2093 if (TARGET_VSX)
2095 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2096 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2097 rs6000_vector_align[V2DImode] = align64;
2100 /* DFmode, see if we want to use the VSX unit. */
2101 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2103 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2104 rs6000_vector_mem[DFmode]
2105 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2106 rs6000_vector_align[DFmode] = align64;
2109 /* TODO add SPE and paired floating point vector support. */
2111 /* Register class constaints for the constraints that depend on compile
2112 switches. */
2113 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2114 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2116 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2117 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2119 if (TARGET_VSX)
2121 /* At present, we just use VSX_REGS, but we have different constraints
2122 based on the use, in case we want to fine tune the default register
2123 class used. wa = any VSX register, wf = register class to use for
2124 V4SF, wd = register class to use for V2DF, and ws = register classs to
2125 use for DF scalars. */
2126 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2127 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2128 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2129 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2130 ? VSX_REGS
2131 : FLOAT_REGS);
2134 if (TARGET_ALTIVEC)
2135 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2137 /* Set up the reload helper functions. */
2138 if (TARGET_VSX || TARGET_ALTIVEC)
2140 if (TARGET_64BIT)
2142 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2143 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2144 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2145 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2146 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2147 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2148 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2149 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2150 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2151 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2152 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2153 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2155 else
2157 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2158 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2159 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2160 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2161 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2162 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2163 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2164 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2165 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2166 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2167 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2168 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2172 /* Precalculate HARD_REGNO_NREGS. */
2173 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2174 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2175 rs6000_hard_regno_nregs[m][r]
2176 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2178 /* Precalculate HARD_REGNO_MODE_OK. */
2179 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2180 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2181 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2182 rs6000_hard_regno_mode_ok_p[m][r] = true;
2184 /* Precalculate CLASS_MAX_NREGS sizes. */
2185 for (c = 0; c < LIM_REG_CLASSES; ++c)
2187 int reg_size;
2189 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2190 reg_size = UNITS_PER_VSX_WORD;
2192 else if (c == ALTIVEC_REGS)
2193 reg_size = UNITS_PER_ALTIVEC_WORD;
2195 else if (c == FLOAT_REGS)
2196 reg_size = UNITS_PER_FP_WORD;
2198 else
2199 reg_size = UNITS_PER_WORD;
2201 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2202 rs6000_class_max_nregs[m][c]
2203 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2206 if (TARGET_E500_DOUBLE)
2207 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2209 /* Calculate which modes to automatically generate code to use a the
2210 reciprocal divide and square root instructions. In the future, possibly
2211 automatically generate the instructions even if the user did not specify
2212 -mrecip. The older machines double precision reciprocal sqrt estimate is
2213 not accurate enough. */
2214 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2215 if (TARGET_FRES)
2216 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2217 if (TARGET_FRE)
2218 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2219 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2220 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2221 if (VECTOR_UNIT_VSX_P (V2DFmode))
2222 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2224 if (TARGET_FRSQRTES)
2225 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2226 if (TARGET_FRSQRTE)
2227 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2228 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2229 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2230 if (VECTOR_UNIT_VSX_P (V2DFmode))
2231 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2233 if (rs6000_recip_control)
2235 if (!TARGET_FUSED_MADD)
2236 warning (0, "-mrecip requires -mfused-madd");
2237 if (!flag_finite_math_only)
2238 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2239 if (flag_trapping_math)
2240 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2241 if (!flag_reciprocal_math)
2242 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2243 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2244 && flag_reciprocal_math)
2246 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2247 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2248 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2250 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2251 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2252 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2254 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2255 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2256 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2258 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2259 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2260 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2262 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2263 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2264 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2266 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2267 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2268 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2270 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2271 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2272 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2274 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2275 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2276 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2280 if (TARGET_DEBUG_REG)
2281 rs6000_debug_reg_global ();
2283 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2284 fprintf (stderr,
2285 "SImode variable mult cost = %d\n"
2286 "SImode constant mult cost = %d\n"
2287 "SImode short constant mult cost = %d\n"
2288 "DImode multipliciation cost = %d\n"
2289 "SImode division cost = %d\n"
2290 "DImode division cost = %d\n"
2291 "Simple fp operation cost = %d\n"
2292 "DFmode multiplication cost = %d\n"
2293 "SFmode division cost = %d\n"
2294 "DFmode division cost = %d\n"
2295 "cache line size = %d\n"
2296 "l1 cache size = %d\n"
2297 "l2 cache size = %d\n"
2298 "simultaneous prefetches = %d\n"
2299 "\n",
2300 rs6000_cost->mulsi,
2301 rs6000_cost->mulsi_const,
2302 rs6000_cost->mulsi_const9,
2303 rs6000_cost->muldi,
2304 rs6000_cost->divsi,
2305 rs6000_cost->divdi,
2306 rs6000_cost->fp,
2307 rs6000_cost->dmul,
2308 rs6000_cost->sdiv,
2309 rs6000_cost->ddiv,
2310 rs6000_cost->cache_line_size,
2311 rs6000_cost->l1_cache_size,
2312 rs6000_cost->l2_cache_size,
2313 rs6000_cost->simultaneous_prefetches);
2316 #if TARGET_MACHO
2317 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2319 static void
2320 darwin_rs6000_override_options (void)
2322 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2323 off. */
2324 rs6000_altivec_abi = 1;
2325 TARGET_ALTIVEC_VRSAVE = 1;
2326 if (DEFAULT_ABI == ABI_DARWIN)
2328 if (MACHO_DYNAMIC_NO_PIC_P)
2330 if (flag_pic)
2331 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2332 flag_pic = 0;
2334 else if (flag_pic == 1)
2336 flag_pic = 2;
2339 if (TARGET_64BIT && ! TARGET_POWERPC64)
2341 target_flags |= MASK_POWERPC64;
2342 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2344 if (flag_mkernel)
2346 rs6000_default_long_calls = 1;
2347 target_flags |= MASK_SOFT_FLOAT;
2350 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2351 Altivec. */
2352 if (!flag_mkernel && !flag_apple_kext
2353 && TARGET_64BIT
2354 && ! (target_flags_explicit & MASK_ALTIVEC))
2355 target_flags |= MASK_ALTIVEC;
2357 /* Unless the user (not the configurer) has explicitly overridden
2358 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2359 G4 unless targetting the kernel. */
2360 if (!flag_mkernel
2361 && !flag_apple_kext
2362 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2363 && ! (target_flags_explicit & MASK_ALTIVEC)
2364 && ! rs6000_select[1].string)
2366 target_flags |= MASK_ALTIVEC;
2369 #endif
2371 /* If not otherwise specified by a target, make 'long double' equivalent to
2372 'double'. */
2374 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2375 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2376 #endif
2378 /* Override command line options. Mostly we process the processor
2379 type and sometimes adjust other TARGET_ options. */
2381 void
2382 rs6000_override_options (const char *default_cpu)
2384 size_t i, j;
2385 struct rs6000_cpu_select *ptr;
2386 int set_masks;
2388 /* Simplifications for entries below. */
2390 enum {
2391 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2392 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2395 /* This table occasionally claims that a processor does not support
2396 a particular feature even though it does, but the feature is slower
2397 than the alternative. Thus, it shouldn't be relied on as a
2398 complete description of the processor's support.
2400 Please keep this list in order, and don't forget to update the
2401 documentation in invoke.texi when adding a new processor or
2402 flag. */
2403 static struct ptt
2405 const char *const name; /* Canonical processor name. */
2406 const enum processor_type processor; /* Processor type enum value. */
2407 const int target_enable; /* Target flags to enable. */
2408 } const processor_target_table[]
2409 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2410 {"403", PROCESSOR_PPC403,
2411 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2412 {"405", PROCESSOR_PPC405,
2413 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2414 {"405fp", PROCESSOR_PPC405,
2415 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2416 {"440", PROCESSOR_PPC440,
2417 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2418 {"440fp", PROCESSOR_PPC440,
2419 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2420 {"464", PROCESSOR_PPC440,
2421 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2422 {"464fp", PROCESSOR_PPC440,
2423 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2424 {"476", PROCESSOR_PPC476,
2425 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2426 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2427 {"476fp", PROCESSOR_PPC476,
2428 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2429 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2430 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2431 {"601", PROCESSOR_PPC601,
2432 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2433 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2434 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2435 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2436 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2437 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2438 {"620", PROCESSOR_PPC620,
2439 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2440 {"630", PROCESSOR_PPC630,
2441 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2442 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2443 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2444 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2445 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2446 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2447 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2448 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2449 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2450 | MASK_ISEL},
2451 /* 8548 has a dummy entry for now. */
2452 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2453 | MASK_ISEL},
2454 {"a2", PROCESSOR_PPCA2,
2455 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2456 | MASK_CMPB | MASK_NO_UPDATE },
2457 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2458 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2459 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2460 | MASK_ISEL},
2461 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2462 | MASK_PPC_GFXOPT | MASK_ISEL},
2463 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2464 {"970", PROCESSOR_POWER4,
2465 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2466 {"cell", PROCESSOR_CELL,
2467 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2468 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2469 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2470 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2471 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2472 {"G5", PROCESSOR_POWER4,
2473 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2474 {"titan", PROCESSOR_TITAN,
2475 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2476 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2477 {"power2", PROCESSOR_POWER,
2478 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2479 {"power3", PROCESSOR_PPC630,
2480 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2481 {"power4", PROCESSOR_POWER4,
2482 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2483 | MASK_MFCRF},
2484 {"power5", PROCESSOR_POWER5,
2485 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2486 | MASK_MFCRF | MASK_POPCNTB},
2487 {"power5+", PROCESSOR_POWER5,
2488 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2489 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2490 {"power6", PROCESSOR_POWER6,
2491 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2492 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2493 | MASK_RECIP_PRECISION},
2494 {"power6x", PROCESSOR_POWER6,
2495 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2496 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2497 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2498 {"power7", PROCESSOR_POWER7,
2499 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2500 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2501 | MASK_VSX| MASK_RECIP_PRECISION}, /* Don't add MASK_ISEL by default */
2502 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2503 {"powerpc64", PROCESSOR_POWERPC64,
2504 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2505 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2506 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2507 {"rios2", PROCESSOR_RIOS2,
2508 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2509 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2510 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2511 {"rs64", PROCESSOR_RS64A,
2512 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2515 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2517 /* Some OSs don't support saving the high part of 64-bit registers on
2518 context switch. Other OSs don't support saving Altivec registers.
2519 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2520 settings; if the user wants either, the user must explicitly specify
2521 them and we won't interfere with the user's specification. */
2523 enum {
2524 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2525 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2526 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2527 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2528 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2529 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2530 | MASK_RECIP_PRECISION)
2533 /* Masks for instructions set at various powerpc ISAs. */
2534 enum {
2535 ISA_2_1_MASKS = MASK_MFCRF,
2536 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2538 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and
2539 don't add ALTIVEC, since in general it isn't a win on power6. */
2540 ISA_2_5_MASKS = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2541 | MASK_DFP),
2543 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2544 altivec is a win so enable it. */
2545 ISA_2_6_MASKS = (ISA_2_5_MASKS | MASK_ALTIVEC | MASK_POPCNTD
2546 | MASK_VSX | MASK_RECIP_PRECISION)
2549 /* Numerous experiment shows that IRA based loop pressure
2550 calculation works better for RTL loop invariant motion on targets
2551 with enough (>= 32) registers. It is an expensive optimization.
2552 So it is on only for peak performance. */
2553 if (optimize >= 3)
2554 flag_ira_loop_pressure = 1;
2556 /* Set the pointer size. */
2557 if (TARGET_64BIT)
2559 rs6000_pmode = (int)DImode;
2560 rs6000_pointer_size = 64;
2562 else
2564 rs6000_pmode = (int)SImode;
2565 rs6000_pointer_size = 32;
2568 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2569 #ifdef OS_MISSING_POWERPC64
2570 if (OS_MISSING_POWERPC64)
2571 set_masks &= ~MASK_POWERPC64;
2572 #endif
2573 #ifdef OS_MISSING_ALTIVEC
2574 if (OS_MISSING_ALTIVEC)
2575 set_masks &= ~MASK_ALTIVEC;
2576 #endif
2578 /* Don't override by the processor default if given explicitly. */
2579 set_masks &= ~target_flags_explicit;
2581 /* Identify the processor type. */
2582 rs6000_select[0].string = default_cpu;
2583 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2585 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2587 ptr = &rs6000_select[i];
2588 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2590 for (j = 0; j < ptt_size; j++)
2591 if (! strcmp (ptr->string, processor_target_table[j].name))
2593 if (ptr->set_tune_p)
2594 rs6000_cpu = processor_target_table[j].processor;
2596 if (ptr->set_arch_p)
2598 target_flags &= ~set_masks;
2599 target_flags |= (processor_target_table[j].target_enable
2600 & set_masks);
2602 break;
2605 if (j == ptt_size)
2606 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2610 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2611 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2613 if (TARGET_ALTIVEC)
2614 error ("AltiVec not supported in this target");
2615 if (TARGET_SPE)
2616 error ("Spe not supported in this target");
2619 /* Disable Cell microcode if we are optimizing for the Cell
2620 and not optimizing for size. */
2621 if (rs6000_gen_cell_microcode == -1)
2622 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2623 && !optimize_size);
2625 /* If we are optimizing big endian systems for space and it's OK to
2626 use instructions that would be microcoded on the Cell, use the
2627 load/store multiple and string instructions. */
2628 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2629 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2631 /* Don't allow -mmultiple or -mstring on little endian systems
2632 unless the cpu is a 750, because the hardware doesn't support the
2633 instructions used in little endian mode, and causes an alignment
2634 trap. The 750 does not cause an alignment trap (except when the
2635 target is unaligned). */
2637 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2639 if (TARGET_MULTIPLE)
2641 target_flags &= ~MASK_MULTIPLE;
2642 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2643 warning (0, "-mmultiple is not supported on little endian systems");
2646 if (TARGET_STRING)
2648 target_flags &= ~MASK_STRING;
2649 if ((target_flags_explicit & MASK_STRING) != 0)
2650 warning (0, "-mstring is not supported on little endian systems");
2654 /* Add some warnings for VSX. */
2655 if (TARGET_VSX)
2657 const char *msg = NULL;
2658 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2659 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2661 if (target_flags_explicit & MASK_VSX)
2662 msg = N_("-mvsx requires hardware floating point");
2663 else
2664 target_flags &= ~ MASK_VSX;
2666 else if (TARGET_PAIRED_FLOAT)
2667 msg = N_("-mvsx and -mpaired are incompatible");
2668 /* The hardware will allow VSX and little endian, but until we make sure
2669 things like vector select, etc. work don't allow VSX on little endian
2670 systems at this point. */
2671 else if (!BYTES_BIG_ENDIAN)
2672 msg = N_("-mvsx used with little endian code");
2673 else if (TARGET_AVOID_XFORM > 0)
2674 msg = N_("-mvsx needs indexed addressing");
2675 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2677 if (target_flags_explicit & MASK_VSX)
2678 msg = N_("-mvsx and -mno-altivec are incompatible");
2679 else
2680 msg = N_("-mno-altivec disables vsx");
2683 if (msg)
2685 warning (0, msg);
2686 target_flags &= ~ MASK_VSX;
2690 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2691 unless the user explicitly used the -mno-<option> to disable the code. */
2692 if (TARGET_VSX)
2693 target_flags |= (ISA_2_6_MASKS & ~target_flags_explicit);
2694 else if (TARGET_DFP)
2695 target_flags |= (ISA_2_5_MASKS & ~target_flags_explicit);
2696 else if (TARGET_ALTIVEC)
2697 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2699 /* E500mc does "better" if we inline more aggressively. Respect the
2700 user's opinion, though. */
2701 if (rs6000_block_move_inline_limit == 0
2702 && (rs6000_cpu == PROCESSOR_PPCE500MC
2703 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2704 rs6000_block_move_inline_limit = 128;
2706 /* store_one_arg depends on expand_block_move to handle at least the
2707 size of reg_parm_stack_space. */
2708 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2709 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2711 /* Set debug flags */
2712 if (rs6000_debug_name)
2714 if (! strcmp (rs6000_debug_name, "all"))
2715 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2716 = rs6000_debug_addr = rs6000_debug_cost = 1;
2717 else if (! strcmp (rs6000_debug_name, "stack"))
2718 rs6000_debug_stack = 1;
2719 else if (! strcmp (rs6000_debug_name, "arg"))
2720 rs6000_debug_arg = 1;
2721 else if (! strcmp (rs6000_debug_name, "reg"))
2722 rs6000_debug_reg = 1;
2723 else if (! strcmp (rs6000_debug_name, "addr"))
2724 rs6000_debug_addr = 1;
2725 else if (! strcmp (rs6000_debug_name, "cost"))
2726 rs6000_debug_cost = 1;
2727 else
2728 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2730 /* If the appropriate debug option is enabled, replace the target hooks
2731 with debug versions that call the real version and then prints
2732 debugging information. */
2733 if (TARGET_DEBUG_COST)
2735 targetm.rtx_costs = rs6000_debug_rtx_costs;
2736 targetm.address_cost = rs6000_debug_address_cost;
2737 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2740 if (TARGET_DEBUG_ADDR)
2742 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2743 targetm.legitimize_address = rs6000_debug_legitimize_address;
2744 rs6000_secondary_reload_class_ptr
2745 = rs6000_debug_secondary_reload_class;
2746 rs6000_secondary_memory_needed_ptr
2747 = rs6000_debug_secondary_memory_needed;
2748 rs6000_cannot_change_mode_class_ptr
2749 = rs6000_debug_cannot_change_mode_class;
2750 rs6000_preferred_reload_class_ptr
2751 = rs6000_debug_preferred_reload_class;
2752 rs6000_legitimize_reload_address_ptr
2753 = rs6000_debug_legitimize_reload_address;
2754 rs6000_mode_dependent_address_ptr
2755 = rs6000_debug_mode_dependent_address;
2759 if (rs6000_traceback_name)
2761 if (! strncmp (rs6000_traceback_name, "full", 4))
2762 rs6000_traceback = traceback_full;
2763 else if (! strncmp (rs6000_traceback_name, "part", 4))
2764 rs6000_traceback = traceback_part;
2765 else if (! strncmp (rs6000_traceback_name, "no", 2))
2766 rs6000_traceback = traceback_none;
2767 else
2768 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2769 rs6000_traceback_name);
2772 if (!rs6000_explicit_options.long_double)
2773 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2775 #ifndef POWERPC_LINUX
2776 if (!rs6000_explicit_options.ieee)
2777 rs6000_ieeequad = 1;
2778 #endif
2780 /* Enable Altivec ABI for AIX -maltivec. */
2781 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2782 rs6000_altivec_abi = 1;
2784 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2785 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2786 be explicitly overridden in either case. */
2787 if (TARGET_ELF)
2789 if (!rs6000_explicit_options.altivec_abi
2790 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2791 rs6000_altivec_abi = 1;
2793 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2794 if (!rs6000_explicit_options.vrsave)
2795 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2798 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2799 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2801 rs6000_darwin64_abi = 1;
2802 #if TARGET_MACHO
2803 darwin_one_byte_bool = 1;
2804 #endif
2805 /* Default to natural alignment, for better performance. */
2806 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2809 /* Place FP constants in the constant pool instead of TOC
2810 if section anchors enabled. */
2811 if (flag_section_anchors)
2812 TARGET_NO_FP_IN_TOC = 1;
2814 /* Handle -mtls-size option. */
2815 rs6000_parse_tls_size_option ();
2817 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2818 SUBTARGET_OVERRIDE_OPTIONS;
2819 #endif
2820 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2821 SUBSUBTARGET_OVERRIDE_OPTIONS;
2822 #endif
2823 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2824 SUB3TARGET_OVERRIDE_OPTIONS;
2825 #endif
2827 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2828 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2830 /* The e500 and e500mc do not have string instructions, and we set
2831 MASK_STRING above when optimizing for size. */
2832 if ((target_flags & MASK_STRING) != 0)
2833 target_flags = target_flags & ~MASK_STRING;
2835 else if (rs6000_select[1].string != NULL)
2837 /* For the powerpc-eabispe configuration, we set all these by
2838 default, so let's unset them if we manually set another
2839 CPU that is not the E500. */
2840 if (!rs6000_explicit_options.spe_abi)
2841 rs6000_spe_abi = 0;
2842 if (!rs6000_explicit_options.spe)
2843 rs6000_spe = 0;
2844 if (!rs6000_explicit_options.float_gprs)
2845 rs6000_float_gprs = 0;
2846 if (!(target_flags_explicit & MASK_ISEL))
2847 target_flags &= ~MASK_ISEL;
2850 /* Detect invalid option combinations with E500. */
2851 CHECK_E500_OPTIONS;
2853 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2854 && rs6000_cpu != PROCESSOR_POWER5
2855 && rs6000_cpu != PROCESSOR_POWER6
2856 && rs6000_cpu != PROCESSOR_POWER7
2857 && rs6000_cpu != PROCESSOR_PPCA2
2858 && rs6000_cpu != PROCESSOR_CELL);
2859 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2860 || rs6000_cpu == PROCESSOR_POWER5
2861 || rs6000_cpu == PROCESSOR_POWER7);
2862 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2863 || rs6000_cpu == PROCESSOR_POWER5
2864 || rs6000_cpu == PROCESSOR_POWER6
2865 || rs6000_cpu == PROCESSOR_POWER7
2866 || rs6000_cpu == PROCESSOR_PPCE500MC
2867 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2869 /* Allow debug switches to override the above settings. */
2870 if (TARGET_ALWAYS_HINT > 0)
2871 rs6000_always_hint = TARGET_ALWAYS_HINT;
2873 if (TARGET_SCHED_GROUPS > 0)
2874 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2876 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2877 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2879 rs6000_sched_restricted_insns_priority
2880 = (rs6000_sched_groups ? 1 : 0);
2882 /* Handle -msched-costly-dep option. */
2883 rs6000_sched_costly_dep
2884 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2886 if (rs6000_sched_costly_dep_str)
2888 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2889 rs6000_sched_costly_dep = no_dep_costly;
2890 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2891 rs6000_sched_costly_dep = all_deps_costly;
2892 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2893 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2894 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2895 rs6000_sched_costly_dep = store_to_load_dep_costly;
2896 else
2897 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2898 atoi (rs6000_sched_costly_dep_str));
2901 /* Handle -minsert-sched-nops option. */
2902 rs6000_sched_insert_nops
2903 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2905 if (rs6000_sched_insert_nops_str)
2907 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2908 rs6000_sched_insert_nops = sched_finish_none;
2909 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2910 rs6000_sched_insert_nops = sched_finish_pad_groups;
2911 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2912 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2913 else
2914 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2915 atoi (rs6000_sched_insert_nops_str));
2918 #ifdef TARGET_REGNAMES
2919 /* If the user desires alternate register names, copy in the
2920 alternate names now. */
2921 if (TARGET_REGNAMES)
2922 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2923 #endif
2925 /* Set aix_struct_return last, after the ABI is determined.
2926 If -maix-struct-return or -msvr4-struct-return was explicitly
2927 used, don't override with the ABI default. */
2928 if (!rs6000_explicit_options.aix_struct_ret)
2929 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2931 #if 0
2932 /* IBM XL compiler defaults to unsigned bitfields. */
2933 if (TARGET_XL_COMPAT)
2934 flag_signed_bitfields = 0;
2935 #endif
2937 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2938 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2940 if (TARGET_TOC)
2941 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2943 /* We can only guarantee the availability of DI pseudo-ops when
2944 assembling for 64-bit targets. */
2945 if (!TARGET_64BIT)
2947 targetm.asm_out.aligned_op.di = NULL;
2948 targetm.asm_out.unaligned_op.di = NULL;
2951 /* Set branch target alignment, if not optimizing for size. */
2952 if (!optimize_size)
2954 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2955 aligned 8byte to avoid misprediction by the branch predictor. */
2956 if (rs6000_cpu == PROCESSOR_TITAN
2957 || rs6000_cpu == PROCESSOR_CELL)
2959 if (align_functions <= 0)
2960 align_functions = 8;
2961 if (align_jumps <= 0)
2962 align_jumps = 8;
2963 if (align_loops <= 0)
2964 align_loops = 8;
2966 if (rs6000_align_branch_targets)
2968 if (align_functions <= 0)
2969 align_functions = 16;
2970 if (align_jumps <= 0)
2971 align_jumps = 16;
2972 if (align_loops <= 0)
2973 align_loops = 16;
2975 if (align_jumps_max_skip <= 0)
2976 align_jumps_max_skip = 15;
2977 if (align_loops_max_skip <= 0)
2978 align_loops_max_skip = 15;
2981 /* Arrange to save and restore machine status around nested functions. */
2982 init_machine_status = rs6000_init_machine_status;
2984 /* We should always be splitting complex arguments, but we can't break
2985 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2986 if (DEFAULT_ABI != ABI_AIX)
2987 targetm.calls.split_complex_arg = NULL;
2989 /* Initialize rs6000_cost with the appropriate target costs. */
2990 if (optimize_size)
2991 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2992 else
2993 switch (rs6000_cpu)
2995 case PROCESSOR_RIOS1:
2996 rs6000_cost = &rios1_cost;
2997 break;
2999 case PROCESSOR_RIOS2:
3000 rs6000_cost = &rios2_cost;
3001 break;
3003 case PROCESSOR_RS64A:
3004 rs6000_cost = &rs64a_cost;
3005 break;
3007 case PROCESSOR_MPCCORE:
3008 rs6000_cost = &mpccore_cost;
3009 break;
3011 case PROCESSOR_PPC403:
3012 rs6000_cost = &ppc403_cost;
3013 break;
3015 case PROCESSOR_PPC405:
3016 rs6000_cost = &ppc405_cost;
3017 break;
3019 case PROCESSOR_PPC440:
3020 rs6000_cost = &ppc440_cost;
3021 break;
3023 case PROCESSOR_PPC476:
3024 rs6000_cost = &ppc476_cost;
3025 break;
3027 case PROCESSOR_PPC601:
3028 rs6000_cost = &ppc601_cost;
3029 break;
3031 case PROCESSOR_PPC603:
3032 rs6000_cost = &ppc603_cost;
3033 break;
3035 case PROCESSOR_PPC604:
3036 rs6000_cost = &ppc604_cost;
3037 break;
3039 case PROCESSOR_PPC604e:
3040 rs6000_cost = &ppc604e_cost;
3041 break;
3043 case PROCESSOR_PPC620:
3044 rs6000_cost = &ppc620_cost;
3045 break;
3047 case PROCESSOR_PPC630:
3048 rs6000_cost = &ppc630_cost;
3049 break;
3051 case PROCESSOR_CELL:
3052 rs6000_cost = &ppccell_cost;
3053 break;
3055 case PROCESSOR_PPC750:
3056 case PROCESSOR_PPC7400:
3057 rs6000_cost = &ppc750_cost;
3058 break;
3060 case PROCESSOR_PPC7450:
3061 rs6000_cost = &ppc7450_cost;
3062 break;
3064 case PROCESSOR_PPC8540:
3065 rs6000_cost = &ppc8540_cost;
3066 break;
3068 case PROCESSOR_PPCE300C2:
3069 case PROCESSOR_PPCE300C3:
3070 rs6000_cost = &ppce300c2c3_cost;
3071 break;
3073 case PROCESSOR_PPCE500MC:
3074 rs6000_cost = &ppce500mc_cost;
3075 break;
3077 case PROCESSOR_PPCE500MC64:
3078 rs6000_cost = &ppce500mc64_cost;
3079 break;
3081 case PROCESSOR_TITAN:
3082 rs6000_cost = &titan_cost;
3083 break;
3085 case PROCESSOR_POWER4:
3086 case PROCESSOR_POWER5:
3087 rs6000_cost = &power4_cost;
3088 break;
3090 case PROCESSOR_POWER6:
3091 rs6000_cost = &power6_cost;
3092 break;
3094 case PROCESSOR_POWER7:
3095 rs6000_cost = &power7_cost;
3096 break;
3098 case PROCESSOR_PPCA2:
3099 rs6000_cost = &ppca2_cost;
3100 break;
3102 default:
3103 gcc_unreachable ();
3106 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
3107 set_param_value ("simultaneous-prefetches",
3108 rs6000_cost->simultaneous_prefetches);
3109 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
3110 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
3111 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
3112 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
3113 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
3114 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
3116 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3117 can be optimized to ap = __builtin_next_arg (0). */
3118 if (DEFAULT_ABI != ABI_V4)
3119 targetm.expand_builtin_va_start = NULL;
3121 /* Set up single/double float flags.
3122 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3123 then set both flags. */
3124 if (TARGET_HARD_FLOAT && TARGET_FPRS
3125 && rs6000_single_float == 0 && rs6000_double_float == 0)
3126 rs6000_single_float = rs6000_double_float = 1;
3128 /* Reset single and double FP flags if target is E500. */
3129 if (TARGET_E500)
3131 rs6000_single_float = rs6000_double_float = 0;
3132 if (TARGET_E500_SINGLE)
3133 rs6000_single_float = 1;
3134 if (TARGET_E500_DOUBLE)
3135 rs6000_single_float = rs6000_double_float = 1;
3138 /* If not explicitly specified via option, decide whether to generate indexed
3139 load/store instructions. */
3140 if (TARGET_AVOID_XFORM == -1)
3141 /* Avoid indexed addressing when targeting Power6 in order to avoid
3142 the DERAT mispredict penalty. */
3143 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3145 /* Set the -mrecip options. */
3146 if (rs6000_recip_name)
3148 char *p = ASTRDUP (rs6000_recip_name);
3149 char *q;
3150 unsigned int mask, i;
3151 bool invert;
3153 while ((q = strtok (p, ",")) != NULL)
3155 p = NULL;
3156 if (*q == '!')
3158 invert = true;
3159 q++;
3161 else
3162 invert = false;
3164 if (!strcmp (q, "default"))
3165 mask = ((TARGET_RECIP_PRECISION)
3166 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3167 else
3169 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3170 if (!strcmp (q, recip_options[i].string))
3172 mask = recip_options[i].mask;
3173 break;
3176 if (i == ARRAY_SIZE (recip_options))
3178 error ("Unknown option for -mrecip=%s", q);
3179 invert = false;
3180 mask = 0;
3184 if (invert)
3185 rs6000_recip_control &= ~mask;
3186 else
3187 rs6000_recip_control |= mask;
3191 rs6000_init_hard_regno_mode_ok ();
3194 /* Implement targetm.vectorize.builtin_mask_for_load. */
3195 static tree
3196 rs6000_builtin_mask_for_load (void)
3198 if (TARGET_ALTIVEC || TARGET_VSX)
3199 return altivec_builtin_mask_for_load;
3200 else
3201 return 0;
3204 /* Implement targetm.vectorize.builtin_conversion.
3205 Returns a decl of a function that implements conversion of an integer vector
3206 into a floating-point vector, or vice-versa. DEST_TYPE is the
3207 destination type and SRC_TYPE the source type of the conversion.
3208 Return NULL_TREE if it is not available. */
3209 static tree
3210 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3212 enum tree_code code = (enum tree_code) tcode;
3214 switch (code)
3216 case FIX_TRUNC_EXPR:
3217 switch (TYPE_MODE (dest_type))
3219 case V2DImode:
3220 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3221 return NULL_TREE;
3223 return TYPE_UNSIGNED (dest_type)
3224 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3225 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3227 case V4SImode:
3228 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3229 return NULL_TREE;
3231 return TYPE_UNSIGNED (dest_type)
3232 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3233 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3235 default:
3236 return NULL_TREE;
3239 case FLOAT_EXPR:
3240 switch (TYPE_MODE (src_type))
3242 case V2DImode:
3243 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3244 return NULL_TREE;
3246 return TYPE_UNSIGNED (src_type)
3247 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3248 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3250 case V4SImode:
3251 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3252 return NULL_TREE;
3254 return TYPE_UNSIGNED (src_type)
3255 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3256 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3258 default:
3259 return NULL_TREE;
3262 default:
3263 return NULL_TREE;
3267 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3268 static tree
3269 rs6000_builtin_mul_widen_even (tree type)
3271 if (!TARGET_ALTIVEC)
3272 return NULL_TREE;
3274 switch (TYPE_MODE (type))
3276 case V8HImode:
3277 return TYPE_UNSIGNED (type)
3278 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3279 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3281 case V16QImode:
3282 return TYPE_UNSIGNED (type)
3283 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3284 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3285 default:
3286 return NULL_TREE;
3290 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3291 static tree
3292 rs6000_builtin_mul_widen_odd (tree type)
3294 if (!TARGET_ALTIVEC)
3295 return NULL_TREE;
3297 switch (TYPE_MODE (type))
3299 case V8HImode:
3300 return TYPE_UNSIGNED (type)
3301 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3302 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3304 case V16QImode:
3305 return TYPE_UNSIGNED (type)
3306 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3307 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3308 default:
3309 return NULL_TREE;
3314 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3315 after applying N number of iterations. This routine does not determine
3316 how may iterations are required to reach desired alignment. */
3318 static bool
3319 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3321 if (is_packed)
3322 return false;
3324 if (TARGET_32BIT)
3326 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3327 return true;
3329 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3330 return true;
3332 return false;
3334 else
3336 if (TARGET_MACHO)
3337 return false;
3339 /* Assuming that all other types are naturally aligned. CHECKME! */
3340 return true;
3344 /* Return true if the vector misalignment factor is supported by the
3345 target. */
3346 bool
3347 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3348 const_tree type,
3349 int misalignment,
3350 bool is_packed)
3352 if (TARGET_VSX)
3354 /* Return if movmisalign pattern is not supported for this mode. */
3355 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3356 return false;
3358 if (misalignment == -1)
3360 /* Misalignment factor is unknown at compile time but we know
3361 it's word aligned. */
3362 if (rs6000_vector_alignment_reachable (type, is_packed))
3364 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3366 if (element_size == 64 || element_size == 32)
3367 return true;
3370 return false;
3373 /* VSX supports word-aligned vector. */
3374 if (misalignment % 4 == 0)
3375 return true;
3377 return false;
3380 /* Implement targetm.vectorize.builtin_vec_perm. */
3381 tree
3382 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3384 tree inner_type = TREE_TYPE (type);
3385 bool uns_p = TYPE_UNSIGNED (inner_type);
3386 tree d;
3388 *mask_element_type = unsigned_char_type_node;
3390 switch (TYPE_MODE (type))
3392 case V16QImode:
3393 d = (uns_p
3394 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3395 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3396 break;
3398 case V8HImode:
3399 d = (uns_p
3400 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3401 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3402 break;
3404 case V4SImode:
3405 d = (uns_p
3406 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3407 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3408 break;
3410 case V4SFmode:
3411 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3412 break;
3414 case V2DFmode:
3415 if (!TARGET_ALLOW_DF_PERMUTE)
3416 return NULL_TREE;
3418 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3419 break;
3421 case V2DImode:
3422 if (!TARGET_ALLOW_DF_PERMUTE)
3423 return NULL_TREE;
3425 d = (uns_p
3426 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3427 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3428 break;
3430 default:
3431 return NULL_TREE;
3434 gcc_assert (d);
3435 return d;
3439 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3440 static int
3441 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3442 tree vectype, int misalign)
3444 unsigned elements;
3446 switch (type_of_cost)
3448 case scalar_stmt:
3449 case scalar_load:
3450 case scalar_store:
3451 case vector_stmt:
3452 case vector_load:
3453 case vector_store:
3454 case vec_to_scalar:
3455 case scalar_to_vec:
3456 case cond_branch_not_taken:
3457 case vec_perm:
3458 return 1;
3460 case cond_branch_taken:
3461 return 3;
3463 case unaligned_load:
3464 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3466 elements = TYPE_VECTOR_SUBPARTS (vectype);
3467 if (elements == 2)
3468 /* Double word aligned. */
3469 return 2;
3471 if (elements == 4)
3473 switch (misalign)
3475 case 8:
3476 /* Double word aligned. */
3477 return 2;
3479 case -1:
3480 /* Unknown misalignment. */
3481 case 4:
3482 case 12:
3483 /* Word aligned. */
3484 return 22;
3486 default:
3487 gcc_unreachable ();
3492 if (TARGET_ALTIVEC)
3493 /* Misaligned loads are not supported. */
3494 gcc_unreachable ();
3496 return 2;
3498 case unaligned_store:
3499 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3501 elements = TYPE_VECTOR_SUBPARTS (vectype);
3502 if (elements == 2)
3503 /* Double word aligned. */
3504 return 2;
3506 if (elements == 4)
3508 switch (misalign)
3510 case 8:
3511 /* Double word aligned. */
3512 return 2;
3514 case -1:
3515 /* Unknown misalignment. */
3516 case 4:
3517 case 12:
3518 /* Word aligned. */
3519 return 23;
3521 default:
3522 gcc_unreachable ();
3527 if (TARGET_ALTIVEC)
3528 /* Misaligned stores are not supported. */
3529 gcc_unreachable ();
3531 return 2;
3533 default:
3534 gcc_unreachable ();
3538 /* Handle generic options of the form -mfoo=yes/no.
3539 NAME is the option name.
3540 VALUE is the option value.
3541 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3542 whether the option value is 'yes' or 'no' respectively. */
3543 static void
3544 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3546 if (value == 0)
3547 return;
3548 else if (!strcmp (value, "yes"))
3549 *flag = 1;
3550 else if (!strcmp (value, "no"))
3551 *flag = 0;
3552 else
3553 error ("unknown -m%s= option specified: '%s'", name, value);
3556 /* Validate and record the size specified with the -mtls-size option. */
3558 static void
3559 rs6000_parse_tls_size_option (void)
3561 if (rs6000_tls_size_string == 0)
3562 return;
3563 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3564 rs6000_tls_size = 16;
3565 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3566 rs6000_tls_size = 32;
3567 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3568 rs6000_tls_size = 64;
3569 else
3570 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3573 void
3574 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3576 if (DEFAULT_ABI == ABI_DARWIN)
3577 /* The Darwin libraries never set errno, so we might as well
3578 avoid calling them when that's the only reason we would. */
3579 flag_errno_math = 0;
3581 /* Double growth factor to counter reduced min jump length. */
3582 set_param_value ("max-grow-copy-bb-insns", 16);
3584 /* Enable section anchors by default.
3585 Skip section anchors for Objective C and Objective C++
3586 until front-ends fixed. */
3587 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3588 flag_section_anchors = 2;
3591 static enum fpu_type_t
3592 rs6000_parse_fpu_option (const char *option)
3594 if (!strcmp("none", option)) return FPU_NONE;
3595 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3596 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3597 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3598 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3599 error("unknown value %s for -mfpu", option);
3600 return FPU_NONE;
3603 /* Returns a function decl for a vectorized version of the builtin function
3604 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3605 if it is not available. */
3607 static tree
3608 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3609 tree type_in)
3611 enum machine_mode in_mode, out_mode;
3612 int in_n, out_n;
3614 if (TREE_CODE (type_out) != VECTOR_TYPE
3615 || TREE_CODE (type_in) != VECTOR_TYPE
3616 || !TARGET_VECTORIZE_BUILTINS)
3617 return NULL_TREE;
3619 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3620 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3621 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3622 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3624 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3626 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3627 switch (fn)
3629 case BUILT_IN_COPYSIGN:
3630 if (VECTOR_UNIT_VSX_P (V2DFmode)
3631 && out_mode == DFmode && out_n == 2
3632 && in_mode == DFmode && in_n == 2)
3633 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3634 break;
3635 case BUILT_IN_COPYSIGNF:
3636 if (out_mode != SFmode || out_n != 4
3637 || in_mode != SFmode || in_n != 4)
3638 break;
3639 if (VECTOR_UNIT_VSX_P (V4SFmode))
3640 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3641 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3642 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3643 break;
3644 case BUILT_IN_SQRT:
3645 if (VECTOR_UNIT_VSX_P (V2DFmode)
3646 && out_mode == DFmode && out_n == 2
3647 && in_mode == DFmode && in_n == 2)
3648 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3649 break;
3650 case BUILT_IN_SQRTF:
3651 if (VECTOR_UNIT_VSX_P (V4SFmode)
3652 && out_mode == SFmode && out_n == 4
3653 && in_mode == SFmode && in_n == 4)
3654 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3655 break;
3656 case BUILT_IN_CEIL:
3657 if (VECTOR_UNIT_VSX_P (V2DFmode)
3658 && out_mode == DFmode && out_n == 2
3659 && in_mode == DFmode && in_n == 2)
3660 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3661 break;
3662 case BUILT_IN_CEILF:
3663 if (out_mode != SFmode || out_n != 4
3664 || in_mode != SFmode || in_n != 4)
3665 break;
3666 if (VECTOR_UNIT_VSX_P (V4SFmode))
3667 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3668 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3669 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3670 break;
3671 case BUILT_IN_FLOOR:
3672 if (VECTOR_UNIT_VSX_P (V2DFmode)
3673 && out_mode == DFmode && out_n == 2
3674 && in_mode == DFmode && in_n == 2)
3675 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3676 break;
3677 case BUILT_IN_FLOORF:
3678 if (out_mode != SFmode || out_n != 4
3679 || in_mode != SFmode || in_n != 4)
3680 break;
3681 if (VECTOR_UNIT_VSX_P (V4SFmode))
3682 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3683 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3684 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3685 break;
3686 case BUILT_IN_TRUNC:
3687 if (VECTOR_UNIT_VSX_P (V2DFmode)
3688 && out_mode == DFmode && out_n == 2
3689 && in_mode == DFmode && in_n == 2)
3690 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3691 break;
3692 case BUILT_IN_TRUNCF:
3693 if (out_mode != SFmode || out_n != 4
3694 || in_mode != SFmode || in_n != 4)
3695 break;
3696 if (VECTOR_UNIT_VSX_P (V4SFmode))
3697 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3698 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3699 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3700 break;
3701 case BUILT_IN_NEARBYINT:
3702 if (VECTOR_UNIT_VSX_P (V2DFmode)
3703 && flag_unsafe_math_optimizations
3704 && out_mode == DFmode && out_n == 2
3705 && in_mode == DFmode && in_n == 2)
3706 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3707 break;
3708 case BUILT_IN_NEARBYINTF:
3709 if (VECTOR_UNIT_VSX_P (V4SFmode)
3710 && flag_unsafe_math_optimizations
3711 && out_mode == SFmode && out_n == 4
3712 && in_mode == SFmode && in_n == 4)
3713 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3714 break;
3715 case BUILT_IN_RINT:
3716 if (VECTOR_UNIT_VSX_P (V2DFmode)
3717 && !flag_trapping_math
3718 && out_mode == DFmode && out_n == 2
3719 && in_mode == DFmode && in_n == 2)
3720 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3721 break;
3722 case BUILT_IN_RINTF:
3723 if (VECTOR_UNIT_VSX_P (V4SFmode)
3724 && !flag_trapping_math
3725 && out_mode == SFmode && out_n == 4
3726 && in_mode == SFmode && in_n == 4)
3727 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3728 break;
3729 default:
3730 break;
3734 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3736 enum rs6000_builtins fn
3737 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3738 switch (fn)
3740 case RS6000_BUILTIN_RSQRTF:
3741 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3742 && out_mode == SFmode && out_n == 4
3743 && in_mode == SFmode && in_n == 4)
3744 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3745 break;
3746 case RS6000_BUILTIN_RSQRT:
3747 if (VECTOR_UNIT_VSX_P (V2DFmode)
3748 && out_mode == DFmode && out_n == 2
3749 && in_mode == DFmode && in_n == 2)
3750 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3751 break;
3752 case RS6000_BUILTIN_RECIPF:
3753 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3754 && out_mode == SFmode && out_n == 4
3755 && in_mode == SFmode && in_n == 4)
3756 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3757 break;
3758 case RS6000_BUILTIN_RECIP:
3759 if (VECTOR_UNIT_VSX_P (V2DFmode)
3760 && out_mode == DFmode && out_n == 2
3761 && in_mode == DFmode && in_n == 2)
3762 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3763 break;
3764 default:
3765 break;
3769 return NULL_TREE;
3773 /* Implement TARGET_HANDLE_OPTION. */
3775 static bool
3776 rs6000_handle_option (size_t code, const char *arg, int value)
3778 enum fpu_type_t fpu_type = FPU_NONE;
3779 int isel;
3781 switch (code)
3783 case OPT_mno_power:
3784 target_flags &= ~(MASK_POWER | MASK_POWER2
3785 | MASK_MULTIPLE | MASK_STRING);
3786 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3787 | MASK_MULTIPLE | MASK_STRING);
3788 break;
3789 case OPT_mno_powerpc:
3790 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3791 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3792 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3793 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3794 break;
3795 case OPT_mfull_toc:
3796 target_flags &= ~MASK_MINIMAL_TOC;
3797 TARGET_NO_FP_IN_TOC = 0;
3798 TARGET_NO_SUM_IN_TOC = 0;
3799 target_flags_explicit |= MASK_MINIMAL_TOC;
3800 #ifdef TARGET_USES_SYSV4_OPT
3801 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3802 just the same as -mminimal-toc. */
3803 target_flags |= MASK_MINIMAL_TOC;
3804 target_flags_explicit |= MASK_MINIMAL_TOC;
3805 #endif
3806 break;
3808 #ifdef TARGET_USES_SYSV4_OPT
3809 case OPT_mtoc:
3810 /* Make -mtoc behave like -mminimal-toc. */
3811 target_flags |= MASK_MINIMAL_TOC;
3812 target_flags_explicit |= MASK_MINIMAL_TOC;
3813 break;
3814 #endif
3816 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
3817 case OPT_mcmodel_:
3818 if (strcmp (arg, "small") == 0)
3819 cmodel = CMODEL_SMALL;
3820 else if (strcmp (arg, "large") == 0)
3821 cmodel = CMODEL_LARGE;
3822 else
3824 error ("invalid option for -mcmodel: '%s'", arg);
3825 return false;
3827 rs6000_explicit_options.cmodel = true;
3828 #endif
3830 #ifdef TARGET_USES_AIX64_OPT
3831 case OPT_maix64:
3832 #else
3833 case OPT_m64:
3834 #endif
3835 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3836 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3837 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3838 break;
3840 #ifdef TARGET_USES_AIX64_OPT
3841 case OPT_maix32:
3842 #else
3843 case OPT_m32:
3844 #endif
3845 target_flags &= ~MASK_POWERPC64;
3846 target_flags_explicit |= MASK_POWERPC64;
3847 break;
3849 case OPT_minsert_sched_nops_:
3850 rs6000_sched_insert_nops_str = arg;
3851 break;
3853 case OPT_mminimal_toc:
3854 if (value == 1)
3856 TARGET_NO_FP_IN_TOC = 0;
3857 TARGET_NO_SUM_IN_TOC = 0;
3859 break;
3861 case OPT_mpower:
3862 if (value == 1)
3864 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3865 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3867 break;
3869 case OPT_mpower2:
3870 if (value == 1)
3872 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3873 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3875 break;
3877 case OPT_mpowerpc_gpopt:
3878 case OPT_mpowerpc_gfxopt:
3879 if (value == 1)
3881 target_flags |= MASK_POWERPC;
3882 target_flags_explicit |= MASK_POWERPC;
3884 break;
3886 case OPT_maix_struct_return:
3887 case OPT_msvr4_struct_return:
3888 rs6000_explicit_options.aix_struct_ret = true;
3889 break;
3891 case OPT_mvrsave:
3892 rs6000_explicit_options.vrsave = true;
3893 TARGET_ALTIVEC_VRSAVE = value;
3894 break;
3896 case OPT_mvrsave_:
3897 rs6000_explicit_options.vrsave = true;
3898 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3899 break;
3901 case OPT_misel_:
3902 target_flags_explicit |= MASK_ISEL;
3903 isel = 0;
3904 rs6000_parse_yes_no_option ("isel", arg, &isel);
3905 if (isel)
3906 target_flags |= MASK_ISEL;
3907 else
3908 target_flags &= ~MASK_ISEL;
3909 break;
3911 case OPT_mspe:
3912 rs6000_explicit_options.spe = true;
3913 rs6000_spe = value;
3914 break;
3916 case OPT_mspe_:
3917 rs6000_explicit_options.spe = true;
3918 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3919 break;
3921 case OPT_mdebug_:
3922 rs6000_debug_name = arg;
3923 break;
3925 #ifdef TARGET_USES_SYSV4_OPT
3926 case OPT_mcall_:
3927 rs6000_abi_name = arg;
3928 break;
3930 case OPT_msdata_:
3931 rs6000_sdata_name = arg;
3932 break;
3934 case OPT_mtls_size_:
3935 rs6000_tls_size_string = arg;
3936 break;
3938 case OPT_mrelocatable:
3939 if (value == 1)
3941 target_flags |= MASK_MINIMAL_TOC;
3942 target_flags_explicit |= MASK_MINIMAL_TOC;
3943 TARGET_NO_FP_IN_TOC = 1;
3945 break;
3947 case OPT_mrelocatable_lib:
3948 if (value == 1)
3950 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3951 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3952 TARGET_NO_FP_IN_TOC = 1;
3954 else
3956 target_flags &= ~MASK_RELOCATABLE;
3957 target_flags_explicit |= MASK_RELOCATABLE;
3959 break;
3960 #endif
3962 case OPT_mabi_:
3963 if (!strcmp (arg, "altivec"))
3965 rs6000_explicit_options.altivec_abi = true;
3966 rs6000_altivec_abi = 1;
3968 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3969 rs6000_spe_abi = 0;
3971 else if (! strcmp (arg, "no-altivec"))
3973 rs6000_explicit_options.altivec_abi = true;
3974 rs6000_altivec_abi = 0;
3976 else if (! strcmp (arg, "spe"))
3978 rs6000_explicit_options.spe_abi = true;
3979 rs6000_spe_abi = 1;
3980 rs6000_altivec_abi = 0;
3981 if (!TARGET_SPE_ABI)
3982 error ("not configured for ABI: '%s'", arg);
3984 else if (! strcmp (arg, "no-spe"))
3986 rs6000_explicit_options.spe_abi = true;
3987 rs6000_spe_abi = 0;
3990 /* These are here for testing during development only, do not
3991 document in the manual please. */
3992 else if (! strcmp (arg, "d64"))
3994 rs6000_darwin64_abi = 1;
3995 warning (0, "Using darwin64 ABI");
3997 else if (! strcmp (arg, "d32"))
3999 rs6000_darwin64_abi = 0;
4000 warning (0, "Using old darwin ABI");
4003 else if (! strcmp (arg, "ibmlongdouble"))
4005 rs6000_explicit_options.ieee = true;
4006 rs6000_ieeequad = 0;
4007 warning (0, "Using IBM extended precision long double");
4009 else if (! strcmp (arg, "ieeelongdouble"))
4011 rs6000_explicit_options.ieee = true;
4012 rs6000_ieeequad = 1;
4013 warning (0, "Using IEEE extended precision long double");
4016 else
4018 error ("unknown ABI specified: '%s'", arg);
4019 return false;
4021 break;
4023 case OPT_mcpu_:
4024 rs6000_select[1].string = arg;
4025 break;
4027 case OPT_mtune_:
4028 rs6000_select[2].string = arg;
4029 break;
4031 case OPT_mtraceback_:
4032 rs6000_traceback_name = arg;
4033 break;
4035 case OPT_mfloat_gprs_:
4036 rs6000_explicit_options.float_gprs = true;
4037 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4038 rs6000_float_gprs = 1;
4039 else if (! strcmp (arg, "double"))
4040 rs6000_float_gprs = 2;
4041 else if (! strcmp (arg, "no"))
4042 rs6000_float_gprs = 0;
4043 else
4045 error ("invalid option for -mfloat-gprs: '%s'", arg);
4046 return false;
4048 break;
4050 case OPT_mlong_double_:
4051 rs6000_explicit_options.long_double = true;
4052 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4053 if (value != 64 && value != 128)
4055 error ("Unknown switch -mlong-double-%s", arg);
4056 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4057 return false;
4059 else
4060 rs6000_long_double_type_size = value;
4061 break;
4063 case OPT_msched_costly_dep_:
4064 rs6000_sched_costly_dep_str = arg;
4065 break;
4067 case OPT_malign_:
4068 rs6000_explicit_options.alignment = true;
4069 if (! strcmp (arg, "power"))
4071 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4072 some C library functions, so warn about it. The flag may be
4073 useful for performance studies from time to time though, so
4074 don't disable it entirely. */
4075 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4076 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4077 " it is incompatible with the installed C and C++ libraries");
4078 rs6000_alignment_flags = MASK_ALIGN_POWER;
4080 else if (! strcmp (arg, "natural"))
4081 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4082 else
4084 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4085 return false;
4087 break;
4089 case OPT_msingle_float:
4090 if (!TARGET_SINGLE_FPU)
4091 warning (0, "-msingle-float option equivalent to -mhard-float");
4092 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4093 rs6000_double_float = 0;
4094 target_flags &= ~MASK_SOFT_FLOAT;
4095 target_flags_explicit |= MASK_SOFT_FLOAT;
4096 break;
4098 case OPT_mdouble_float:
4099 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4100 rs6000_single_float = 1;
4101 target_flags &= ~MASK_SOFT_FLOAT;
4102 target_flags_explicit |= MASK_SOFT_FLOAT;
4103 break;
4105 case OPT_msimple_fpu:
4106 if (!TARGET_SINGLE_FPU)
4107 warning (0, "-msimple-fpu option ignored");
4108 break;
4110 case OPT_mhard_float:
4111 /* -mhard_float implies -msingle-float and -mdouble-float. */
4112 rs6000_single_float = rs6000_double_float = 1;
4113 break;
4115 case OPT_msoft_float:
4116 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4117 rs6000_single_float = rs6000_double_float = 0;
4118 break;
4120 case OPT_mfpu_:
4121 fpu_type = rs6000_parse_fpu_option(arg);
4122 if (fpu_type != FPU_NONE)
4123 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4125 target_flags &= ~MASK_SOFT_FLOAT;
4126 target_flags_explicit |= MASK_SOFT_FLOAT;
4127 rs6000_xilinx_fpu = 1;
4128 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4129 rs6000_single_float = 1;
4130 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4131 rs6000_single_float = rs6000_double_float = 1;
4132 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4133 rs6000_simple_fpu = 1;
4135 else
4137 /* -mfpu=none is equivalent to -msoft-float */
4138 target_flags |= MASK_SOFT_FLOAT;
4139 target_flags_explicit |= MASK_SOFT_FLOAT;
4140 rs6000_single_float = rs6000_double_float = 0;
4143 case OPT_mrecip:
4144 rs6000_recip_name = (value) ? "default" : "none";
4145 break;
4147 case OPT_mrecip_:
4148 rs6000_recip_name = arg;
4149 break;
4151 return true;
4154 /* Do anything needed at the start of the asm file. */
4156 static void
4157 rs6000_file_start (void)
4159 size_t i;
4160 char buffer[80];
4161 const char *start = buffer;
4162 struct rs6000_cpu_select *ptr;
4163 const char *default_cpu = TARGET_CPU_DEFAULT;
4164 FILE *file = asm_out_file;
4166 default_file_start ();
4168 #ifdef TARGET_BI_ARCH
4169 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4170 default_cpu = 0;
4171 #endif
4173 if (flag_verbose_asm)
4175 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4176 rs6000_select[0].string = default_cpu;
4178 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4180 ptr = &rs6000_select[i];
4181 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4183 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4184 start = "";
4188 if (PPC405_ERRATUM77)
4190 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4191 start = "";
4194 #ifdef USING_ELFOS_H
4195 switch (rs6000_sdata)
4197 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4198 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4199 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4200 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4203 if (rs6000_sdata && g_switch_value)
4205 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4206 g_switch_value);
4207 start = "";
4209 #endif
4211 if (*start == '\0')
4212 putc ('\n', file);
4215 #ifdef HAVE_AS_GNU_ATTRIBUTE
4216 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4218 fprintf (file, "\t.gnu_attribute 4, %d\n",
4219 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4220 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4221 : 2));
4222 fprintf (file, "\t.gnu_attribute 8, %d\n",
4223 (TARGET_ALTIVEC_ABI ? 2
4224 : TARGET_SPE_ABI ? 3
4225 : 1));
4226 fprintf (file, "\t.gnu_attribute 12, %d\n",
4227 aix_struct_return ? 2 : 1);
4230 #endif
4232 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4234 switch_to_section (toc_section);
4235 switch_to_section (text_section);
4240 /* Return nonzero if this function is known to have a null epilogue. */
4243 direct_return (void)
4245 if (reload_completed)
4247 rs6000_stack_t *info = rs6000_stack_info ();
4249 if (info->first_gp_reg_save == 32
4250 && info->first_fp_reg_save == 64
4251 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4252 && ! info->lr_save_p
4253 && ! info->cr_save_p
4254 && info->vrsave_mask == 0
4255 && ! info->push_p)
4256 return 1;
4259 return 0;
4262 /* Return the number of instructions it takes to form a constant in an
4263 integer register. */
4266 num_insns_constant_wide (HOST_WIDE_INT value)
4268 /* signed constant loadable with {cal|addi} */
4269 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4270 return 1;
4272 /* constant loadable with {cau|addis} */
4273 else if ((value & 0xffff) == 0
4274 && (value >> 31 == -1 || value >> 31 == 0))
4275 return 1;
4277 #if HOST_BITS_PER_WIDE_INT == 64
4278 else if (TARGET_POWERPC64)
4280 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4281 HOST_WIDE_INT high = value >> 31;
4283 if (high == 0 || high == -1)
4284 return 2;
4286 high >>= 1;
4288 if (low == 0)
4289 return num_insns_constant_wide (high) + 1;
4290 else if (high == 0)
4291 return num_insns_constant_wide (low) + 1;
4292 else
4293 return (num_insns_constant_wide (high)
4294 + num_insns_constant_wide (low) + 1);
4296 #endif
4298 else
4299 return 2;
4303 num_insns_constant (rtx op, enum machine_mode mode)
4305 HOST_WIDE_INT low, high;
4307 switch (GET_CODE (op))
4309 case CONST_INT:
4310 #if HOST_BITS_PER_WIDE_INT == 64
4311 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4312 && mask64_operand (op, mode))
4313 return 2;
4314 else
4315 #endif
4316 return num_insns_constant_wide (INTVAL (op));
4318 case CONST_DOUBLE:
4319 if (mode == SFmode || mode == SDmode)
4321 long l;
4322 REAL_VALUE_TYPE rv;
4324 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4325 if (DECIMAL_FLOAT_MODE_P (mode))
4326 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4327 else
4328 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4329 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4332 if (mode == VOIDmode || mode == DImode)
4334 high = CONST_DOUBLE_HIGH (op);
4335 low = CONST_DOUBLE_LOW (op);
4337 else
4339 long l[2];
4340 REAL_VALUE_TYPE rv;
4342 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4343 if (DECIMAL_FLOAT_MODE_P (mode))
4344 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4345 else
4346 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4347 high = l[WORDS_BIG_ENDIAN == 0];
4348 low = l[WORDS_BIG_ENDIAN != 0];
4351 if (TARGET_32BIT)
4352 return (num_insns_constant_wide (low)
4353 + num_insns_constant_wide (high));
4354 else
4356 if ((high == 0 && low >= 0)
4357 || (high == -1 && low < 0))
4358 return num_insns_constant_wide (low);
4360 else if (mask64_operand (op, mode))
4361 return 2;
4363 else if (low == 0)
4364 return num_insns_constant_wide (high) + 1;
4366 else
4367 return (num_insns_constant_wide (high)
4368 + num_insns_constant_wide (low) + 1);
4371 default:
4372 gcc_unreachable ();
4376 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4377 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4378 corresponding element of the vector, but for V4SFmode and V2SFmode,
4379 the corresponding "float" is interpreted as an SImode integer. */
4381 HOST_WIDE_INT
4382 const_vector_elt_as_int (rtx op, unsigned int elt)
4384 rtx tmp = CONST_VECTOR_ELT (op, elt);
4385 if (GET_MODE (op) == V4SFmode
4386 || GET_MODE (op) == V2SFmode)
4387 tmp = gen_lowpart (SImode, tmp);
4388 return INTVAL (tmp);
4391 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4392 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4393 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4394 all items are set to the same value and contain COPIES replicas of the
4395 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4396 operand and the others are set to the value of the operand's msb. */
4398 static bool
4399 vspltis_constant (rtx op, unsigned step, unsigned copies)
4401 enum machine_mode mode = GET_MODE (op);
4402 enum machine_mode inner = GET_MODE_INNER (mode);
4404 unsigned i;
4405 unsigned nunits = GET_MODE_NUNITS (mode);
4406 unsigned bitsize = GET_MODE_BITSIZE (inner);
4407 unsigned mask = GET_MODE_MASK (inner);
4409 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4410 HOST_WIDE_INT splat_val = val;
4411 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4413 /* Construct the value to be splatted, if possible. If not, return 0. */
4414 for (i = 2; i <= copies; i *= 2)
4416 HOST_WIDE_INT small_val;
4417 bitsize /= 2;
4418 small_val = splat_val >> bitsize;
4419 mask >>= bitsize;
4420 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4421 return false;
4422 splat_val = small_val;
4425 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4426 if (EASY_VECTOR_15 (splat_val))
4429 /* Also check if we can splat, and then add the result to itself. Do so if
4430 the value is positive, of if the splat instruction is using OP's mode;
4431 for splat_val < 0, the splat and the add should use the same mode. */
4432 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4433 && (splat_val >= 0 || (step == 1 && copies == 1)))
4436 /* Also check if are loading up the most significant bit which can be done by
4437 loading up -1 and shifting the value left by -1. */
4438 else if (EASY_VECTOR_MSB (splat_val, inner))
4441 else
4442 return false;
4444 /* Check if VAL is present in every STEP-th element, and the
4445 other elements are filled with its most significant bit. */
4446 for (i = 0; i < nunits - 1; ++i)
4448 HOST_WIDE_INT desired_val;
4449 if (((i + 1) & (step - 1)) == 0)
4450 desired_val = val;
4451 else
4452 desired_val = msb_val;
4454 if (desired_val != const_vector_elt_as_int (op, i))
4455 return false;
4458 return true;
4462 /* Return true if OP is of the given MODE and can be synthesized
4463 with a vspltisb, vspltish or vspltisw. */
4465 bool
4466 easy_altivec_constant (rtx op, enum machine_mode mode)
4468 unsigned step, copies;
4470 if (mode == VOIDmode)
4471 mode = GET_MODE (op);
4472 else if (mode != GET_MODE (op))
4473 return false;
4475 /* Start with a vspltisw. */
4476 step = GET_MODE_NUNITS (mode) / 4;
4477 copies = 1;
4479 if (vspltis_constant (op, step, copies))
4480 return true;
4482 /* Then try with a vspltish. */
4483 if (step == 1)
4484 copies <<= 1;
4485 else
4486 step >>= 1;
4488 if (vspltis_constant (op, step, copies))
4489 return true;
4491 /* And finally a vspltisb. */
4492 if (step == 1)
4493 copies <<= 1;
4494 else
4495 step >>= 1;
4497 if (vspltis_constant (op, step, copies))
4498 return true;
4500 return false;
4503 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4504 result is OP. Abort if it is not possible. */
4507 gen_easy_altivec_constant (rtx op)
4509 enum machine_mode mode = GET_MODE (op);
4510 int nunits = GET_MODE_NUNITS (mode);
4511 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4512 unsigned step = nunits / 4;
4513 unsigned copies = 1;
4515 /* Start with a vspltisw. */
4516 if (vspltis_constant (op, step, copies))
4517 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4519 /* Then try with a vspltish. */
4520 if (step == 1)
4521 copies <<= 1;
4522 else
4523 step >>= 1;
4525 if (vspltis_constant (op, step, copies))
4526 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4528 /* And finally a vspltisb. */
4529 if (step == 1)
4530 copies <<= 1;
4531 else
4532 step >>= 1;
4534 if (vspltis_constant (op, step, copies))
4535 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4537 gcc_unreachable ();
4540 const char *
4541 output_vec_const_move (rtx *operands)
4543 int cst, cst2;
4544 enum machine_mode mode;
4545 rtx dest, vec;
4547 dest = operands[0];
4548 vec = operands[1];
4549 mode = GET_MODE (dest);
4551 if (TARGET_VSX && zero_constant (vec, mode))
4552 return "xxlxor %x0,%x0,%x0";
4554 if (TARGET_ALTIVEC)
4556 rtx splat_vec;
4557 if (zero_constant (vec, mode))
4558 return "vxor %0,%0,%0";
4560 splat_vec = gen_easy_altivec_constant (vec);
4561 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4562 operands[1] = XEXP (splat_vec, 0);
4563 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4564 return "#";
4566 switch (GET_MODE (splat_vec))
4568 case V4SImode:
4569 return "vspltisw %0,%1";
4571 case V8HImode:
4572 return "vspltish %0,%1";
4574 case V16QImode:
4575 return "vspltisb %0,%1";
4577 default:
4578 gcc_unreachable ();
4582 gcc_assert (TARGET_SPE);
4584 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4585 pattern of V1DI, V4HI, and V2SF.
4587 FIXME: We should probably return # and add post reload
4588 splitters for these, but this way is so easy ;-). */
4589 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4590 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4591 operands[1] = CONST_VECTOR_ELT (vec, 0);
4592 operands[2] = CONST_VECTOR_ELT (vec, 1);
4593 if (cst == cst2)
4594 return "li %0,%1\n\tevmergelo %0,%0,%0";
4595 else
4596 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4599 /* Initialize TARGET of vector PAIRED to VALS. */
4601 void
4602 paired_expand_vector_init (rtx target, rtx vals)
4604 enum machine_mode mode = GET_MODE (target);
4605 int n_elts = GET_MODE_NUNITS (mode);
4606 int n_var = 0;
4607 rtx x, new_rtx, tmp, constant_op, op1, op2;
4608 int i;
4610 for (i = 0; i < n_elts; ++i)
4612 x = XVECEXP (vals, 0, i);
4613 if (!CONSTANT_P (x))
4614 ++n_var;
4616 if (n_var == 0)
4618 /* Load from constant pool. */
4619 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4620 return;
4623 if (n_var == 2)
4625 /* The vector is initialized only with non-constants. */
4626 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4627 XVECEXP (vals, 0, 1));
4629 emit_move_insn (target, new_rtx);
4630 return;
4633 /* One field is non-constant and the other one is a constant. Load the
4634 constant from the constant pool and use ps_merge instruction to
4635 construct the whole vector. */
4636 op1 = XVECEXP (vals, 0, 0);
4637 op2 = XVECEXP (vals, 0, 1);
4639 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4641 tmp = gen_reg_rtx (GET_MODE (constant_op));
4642 emit_move_insn (tmp, constant_op);
4644 if (CONSTANT_P (op1))
4645 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4646 else
4647 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4649 emit_move_insn (target, new_rtx);
4652 void
4653 paired_expand_vector_move (rtx operands[])
4655 rtx op0 = operands[0], op1 = operands[1];
4657 emit_move_insn (op0, op1);
4660 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4661 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4662 operands for the relation operation COND. This is a recursive
4663 function. */
4665 static void
4666 paired_emit_vector_compare (enum rtx_code rcode,
4667 rtx dest, rtx op0, rtx op1,
4668 rtx cc_op0, rtx cc_op1)
4670 rtx tmp = gen_reg_rtx (V2SFmode);
4671 rtx tmp1, max, min;
4673 gcc_assert (TARGET_PAIRED_FLOAT);
4674 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4676 switch (rcode)
4678 case LT:
4679 case LTU:
4680 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4681 return;
4682 case GE:
4683 case GEU:
4684 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4685 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4686 return;
4687 case LE:
4688 case LEU:
4689 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4690 return;
4691 case GT:
4692 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4693 return;
4694 case EQ:
4695 tmp1 = gen_reg_rtx (V2SFmode);
4696 max = gen_reg_rtx (V2SFmode);
4697 min = gen_reg_rtx (V2SFmode);
4698 gen_reg_rtx (V2SFmode);
4700 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4701 emit_insn (gen_selv2sf4
4702 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4703 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4704 emit_insn (gen_selv2sf4
4705 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4706 emit_insn (gen_subv2sf3 (tmp1, min, max));
4707 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4708 return;
4709 case NE:
4710 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4711 return;
4712 case UNLE:
4713 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4714 return;
4715 case UNLT:
4716 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4717 return;
4718 case UNGE:
4719 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4720 return;
4721 case UNGT:
4722 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4723 return;
4724 default:
4725 gcc_unreachable ();
4728 return;
4731 /* Emit vector conditional expression.
4732 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4733 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4736 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4737 rtx cond, rtx cc_op0, rtx cc_op1)
4739 enum rtx_code rcode = GET_CODE (cond);
4741 if (!TARGET_PAIRED_FLOAT)
4742 return 0;
4744 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4746 return 1;
4749 /* Initialize vector TARGET to VALS. */
4751 void
4752 rs6000_expand_vector_init (rtx target, rtx vals)
4754 enum machine_mode mode = GET_MODE (target);
4755 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4756 int n_elts = GET_MODE_NUNITS (mode);
4757 int n_var = 0, one_var = -1;
4758 bool all_same = true, all_const_zero = true;
4759 rtx x, mem;
4760 int i;
4762 for (i = 0; i < n_elts; ++i)
4764 x = XVECEXP (vals, 0, i);
4765 if (!CONSTANT_P (x))
4766 ++n_var, one_var = i;
4767 else if (x != CONST0_RTX (inner_mode))
4768 all_const_zero = false;
4770 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4771 all_same = false;
4774 if (n_var == 0)
4776 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4777 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4778 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4780 /* Zero register. */
4781 emit_insn (gen_rtx_SET (VOIDmode, target,
4782 gen_rtx_XOR (mode, target, target)));
4783 return;
4785 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4787 /* Splat immediate. */
4788 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4789 return;
4791 else
4793 /* Load from constant pool. */
4794 emit_move_insn (target, const_vec);
4795 return;
4799 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4800 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4802 if (all_same)
4804 rtx element = XVECEXP (vals, 0, 0);
4805 if (mode == V2DFmode)
4806 emit_insn (gen_vsx_splat_v2df (target, element));
4807 else
4808 emit_insn (gen_vsx_splat_v2di (target, element));
4810 else
4812 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4813 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4814 if (mode == V2DFmode)
4815 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4816 else
4817 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4819 return;
4822 /* With single precision floating point on VSX, know that internally single
4823 precision is actually represented as a double, and either make 2 V2DF
4824 vectors, and convert these vectors to single precision, or do one
4825 conversion, and splat the result to the other elements. */
4826 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4828 if (all_same)
4830 rtx freg = gen_reg_rtx (V4SFmode);
4831 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4833 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4834 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4836 else
4838 rtx dbl_even = gen_reg_rtx (V2DFmode);
4839 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4840 rtx flt_even = gen_reg_rtx (V4SFmode);
4841 rtx flt_odd = gen_reg_rtx (V4SFmode);
4843 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4844 copy_to_reg (XVECEXP (vals, 0, 0)),
4845 copy_to_reg (XVECEXP (vals, 0, 1))));
4846 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4847 copy_to_reg (XVECEXP (vals, 0, 2)),
4848 copy_to_reg (XVECEXP (vals, 0, 3))));
4849 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4850 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4851 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4853 return;
4856 /* Store value to stack temp. Load vector element. Splat. However, splat
4857 of 64-bit items is not supported on Altivec. */
4858 if (all_same && GET_MODE_SIZE (mode) <= 4)
4860 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4861 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4862 XVECEXP (vals, 0, 0));
4863 x = gen_rtx_UNSPEC (VOIDmode,
4864 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4865 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4866 gen_rtvec (2,
4867 gen_rtx_SET (VOIDmode,
4868 target, mem),
4869 x)));
4870 x = gen_rtx_VEC_SELECT (inner_mode, target,
4871 gen_rtx_PARALLEL (VOIDmode,
4872 gen_rtvec (1, const0_rtx)));
4873 emit_insn (gen_rtx_SET (VOIDmode, target,
4874 gen_rtx_VEC_DUPLICATE (mode, x)));
4875 return;
4878 /* One field is non-constant. Load constant then overwrite
4879 varying field. */
4880 if (n_var == 1)
4882 rtx copy = copy_rtx (vals);
4884 /* Load constant part of vector, substitute neighboring value for
4885 varying element. */
4886 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4887 rs6000_expand_vector_init (target, copy);
4889 /* Insert variable. */
4890 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4891 return;
4894 /* Construct the vector in memory one field at a time
4895 and load the whole vector. */
4896 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4897 for (i = 0; i < n_elts; i++)
4898 emit_move_insn (adjust_address_nv (mem, inner_mode,
4899 i * GET_MODE_SIZE (inner_mode)),
4900 XVECEXP (vals, 0, i));
4901 emit_move_insn (target, mem);
4904 /* Set field ELT of TARGET to VAL. */
4906 void
4907 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4909 enum machine_mode mode = GET_MODE (target);
4910 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4911 rtx reg = gen_reg_rtx (mode);
4912 rtx mask, mem, x;
4913 int width = GET_MODE_SIZE (inner_mode);
4914 int i;
4916 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4918 rtx (*set_func) (rtx, rtx, rtx, rtx)
4919 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4920 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4921 return;
4924 /* Load single variable value. */
4925 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4926 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4927 x = gen_rtx_UNSPEC (VOIDmode,
4928 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4929 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4930 gen_rtvec (2,
4931 gen_rtx_SET (VOIDmode,
4932 reg, mem),
4933 x)));
4935 /* Linear sequence. */
4936 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4937 for (i = 0; i < 16; ++i)
4938 XVECEXP (mask, 0, i) = GEN_INT (i);
4940 /* Set permute mask to insert element into target. */
4941 for (i = 0; i < width; ++i)
4942 XVECEXP (mask, 0, elt*width + i)
4943 = GEN_INT (i + 0x10);
4944 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4945 x = gen_rtx_UNSPEC (mode,
4946 gen_rtvec (3, target, reg,
4947 force_reg (V16QImode, x)),
4948 UNSPEC_VPERM);
4949 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4952 /* Extract field ELT from VEC into TARGET. */
4954 void
4955 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4957 enum machine_mode mode = GET_MODE (vec);
4958 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4959 rtx mem, x;
4961 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4963 rtx (*extract_func) (rtx, rtx, rtx)
4964 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4965 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4966 return;
4969 /* Allocate mode-sized buffer. */
4970 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4972 /* Add offset to field within buffer matching vector element. */
4973 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4975 /* Store single field into mode-sized buffer. */
4976 x = gen_rtx_UNSPEC (VOIDmode,
4977 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4978 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4979 gen_rtvec (2,
4980 gen_rtx_SET (VOIDmode,
4981 mem, vec),
4982 x)));
4983 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4986 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4987 implement ANDing by the mask IN. */
4988 void
4989 build_mask64_2_operands (rtx in, rtx *out)
4991 #if HOST_BITS_PER_WIDE_INT >= 64
4992 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4993 int shift;
4995 gcc_assert (GET_CODE (in) == CONST_INT);
4997 c = INTVAL (in);
4998 if (c & 1)
5000 /* Assume c initially something like 0x00fff000000fffff. The idea
5001 is to rotate the word so that the middle ^^^^^^ group of zeros
5002 is at the MS end and can be cleared with an rldicl mask. We then
5003 rotate back and clear off the MS ^^ group of zeros with a
5004 second rldicl. */
5005 c = ~c; /* c == 0xff000ffffff00000 */
5006 lsb = c & -c; /* lsb == 0x0000000000100000 */
5007 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5008 c = ~c; /* c == 0x00fff000000fffff */
5009 c &= -lsb; /* c == 0x00fff00000000000 */
5010 lsb = c & -c; /* lsb == 0x0000100000000000 */
5011 c = ~c; /* c == 0xff000fffffffffff */
5012 c &= -lsb; /* c == 0xff00000000000000 */
5013 shift = 0;
5014 while ((lsb >>= 1) != 0)
5015 shift++; /* shift == 44 on exit from loop */
5016 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5017 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5018 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5020 else
5022 /* Assume c initially something like 0xff000f0000000000. The idea
5023 is to rotate the word so that the ^^^ middle group of zeros
5024 is at the LS end and can be cleared with an rldicr mask. We then
5025 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5026 a second rldicr. */
5027 lsb = c & -c; /* lsb == 0x0000010000000000 */
5028 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5029 c = ~c; /* c == 0x00fff0ffffffffff */
5030 c &= -lsb; /* c == 0x00fff00000000000 */
5031 lsb = c & -c; /* lsb == 0x0000100000000000 */
5032 c = ~c; /* c == 0xff000fffffffffff */
5033 c &= -lsb; /* c == 0xff00000000000000 */
5034 shift = 0;
5035 while ((lsb >>= 1) != 0)
5036 shift++; /* shift == 44 on exit from loop */
5037 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5038 m1 >>= shift; /* m1 == 0x0000000000000fff */
5039 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5042 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5043 masks will be all 1's. We are guaranteed more than one transition. */
5044 out[0] = GEN_INT (64 - shift);
5045 out[1] = GEN_INT (m1);
5046 out[2] = GEN_INT (shift);
5047 out[3] = GEN_INT (m2);
5048 #else
5049 (void)in;
5050 (void)out;
5051 gcc_unreachable ();
5052 #endif
5055 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5057 bool
5058 invalid_e500_subreg (rtx op, enum machine_mode mode)
5060 if (TARGET_E500_DOUBLE)
5062 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5063 subreg:TI and reg:TF. Decimal float modes are like integer
5064 modes (only low part of each register used) for this
5065 purpose. */
5066 if (GET_CODE (op) == SUBREG
5067 && (mode == SImode || mode == DImode || mode == TImode
5068 || mode == DDmode || mode == TDmode)
5069 && REG_P (SUBREG_REG (op))
5070 && (GET_MODE (SUBREG_REG (op)) == DFmode
5071 || GET_MODE (SUBREG_REG (op)) == TFmode))
5072 return true;
5074 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5075 reg:TI. */
5076 if (GET_CODE (op) == SUBREG
5077 && (mode == DFmode || mode == TFmode)
5078 && REG_P (SUBREG_REG (op))
5079 && (GET_MODE (SUBREG_REG (op)) == DImode
5080 || GET_MODE (SUBREG_REG (op)) == TImode
5081 || GET_MODE (SUBREG_REG (op)) == DDmode
5082 || GET_MODE (SUBREG_REG (op)) == TDmode))
5083 return true;
5086 if (TARGET_SPE
5087 && GET_CODE (op) == SUBREG
5088 && mode == SImode
5089 && REG_P (SUBREG_REG (op))
5090 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5091 return true;
5093 return false;
5096 /* AIX increases natural record alignment to doubleword if the first
5097 field is an FP double while the FP fields remain word aligned. */
5099 unsigned int
5100 rs6000_special_round_type_align (tree type, unsigned int computed,
5101 unsigned int specified)
5103 unsigned int align = MAX (computed, specified);
5104 tree field = TYPE_FIELDS (type);
5106 /* Skip all non field decls */
5107 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5108 field = DECL_CHAIN (field);
5110 if (field != NULL && field != type)
5112 type = TREE_TYPE (field);
5113 while (TREE_CODE (type) == ARRAY_TYPE)
5114 type = TREE_TYPE (type);
5116 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5117 align = MAX (align, 64);
5120 return align;
5123 /* Darwin increases record alignment to the natural alignment of
5124 the first field. */
5126 unsigned int
5127 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5128 unsigned int specified)
5130 unsigned int align = MAX (computed, specified);
5132 if (TYPE_PACKED (type))
5133 return align;
5135 /* Find the first field, looking down into aggregates. */
5136 do {
5137 tree field = TYPE_FIELDS (type);
5138 /* Skip all non field decls */
5139 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5140 field = DECL_CHAIN (field);
5141 if (! field)
5142 break;
5143 /* A packed field does not contribute any extra alignment. */
5144 if (DECL_PACKED (field))
5145 return align;
5146 type = TREE_TYPE (field);
5147 while (TREE_CODE (type) == ARRAY_TYPE)
5148 type = TREE_TYPE (type);
5149 } while (AGGREGATE_TYPE_P (type));
5151 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5152 align = MAX (align, TYPE_ALIGN (type));
5154 return align;
5157 /* Return 1 for an operand in small memory on V.4/eabi. */
5160 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5161 enum machine_mode mode ATTRIBUTE_UNUSED)
5163 #if TARGET_ELF
5164 rtx sym_ref;
5166 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5167 return 0;
5169 if (DEFAULT_ABI != ABI_V4)
5170 return 0;
5172 /* Vector and float memory instructions have a limited offset on the
5173 SPE, so using a vector or float variable directly as an operand is
5174 not useful. */
5175 if (TARGET_SPE
5176 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5177 return 0;
5179 if (GET_CODE (op) == SYMBOL_REF)
5180 sym_ref = op;
5182 else if (GET_CODE (op) != CONST
5183 || GET_CODE (XEXP (op, 0)) != PLUS
5184 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5185 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5186 return 0;
5188 else
5190 rtx sum = XEXP (op, 0);
5191 HOST_WIDE_INT summand;
5193 /* We have to be careful here, because it is the referenced address
5194 that must be 32k from _SDA_BASE_, not just the symbol. */
5195 summand = INTVAL (XEXP (sum, 1));
5196 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5197 return 0;
5199 sym_ref = XEXP (sum, 0);
5202 return SYMBOL_REF_SMALL_P (sym_ref);
5203 #else
5204 return 0;
5205 #endif
5208 /* Return true if either operand is a general purpose register. */
5210 bool
5211 gpr_or_gpr_p (rtx op0, rtx op1)
5213 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5214 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5218 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5220 static bool
5221 reg_offset_addressing_ok_p (enum machine_mode mode)
5223 switch (mode)
5225 case V16QImode:
5226 case V8HImode:
5227 case V4SFmode:
5228 case V4SImode:
5229 case V2DFmode:
5230 case V2DImode:
5231 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5232 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5233 return false;
5234 break;
5236 case V4HImode:
5237 case V2SImode:
5238 case V1DImode:
5239 case V2SFmode:
5240 /* Paired vector modes. Only reg+reg addressing is valid. */
5241 if (TARGET_PAIRED_FLOAT)
5242 return false;
5243 break;
5245 default:
5246 break;
5249 return true;
5252 static bool
5253 virtual_stack_registers_memory_p (rtx op)
5255 int regnum;
5257 if (GET_CODE (op) == REG)
5258 regnum = REGNO (op);
5260 else if (GET_CODE (op) == PLUS
5261 && GET_CODE (XEXP (op, 0)) == REG
5262 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5263 regnum = REGNO (XEXP (op, 0));
5265 else
5266 return false;
5268 return (regnum >= FIRST_VIRTUAL_REGISTER
5269 && regnum <= LAST_VIRTUAL_REGISTER);
5272 static bool
5273 constant_pool_expr_p (rtx op)
5275 rtx base, offset;
5277 split_const (op, &base, &offset);
5278 return (GET_CODE (base) == SYMBOL_REF
5279 && CONSTANT_POOL_ADDRESS_P (base)
5280 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5283 static rtx tocrel_base, tocrel_offset;
5285 bool
5286 toc_relative_expr_p (rtx op)
5288 if (GET_CODE (op) != CONST)
5289 return false;
5291 split_const (op, &tocrel_base, &tocrel_offset);
5292 return (GET_CODE (tocrel_base) == UNSPEC
5293 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5296 bool
5297 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5299 return (TARGET_TOC
5300 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5301 && GET_CODE (XEXP (x, 0)) == REG
5302 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5303 || ((TARGET_MINIMAL_TOC
5304 || TARGET_CMODEL != CMODEL_SMALL)
5305 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5306 && toc_relative_expr_p (XEXP (x, 1)));
5309 static bool
5310 legitimate_small_data_p (enum machine_mode mode, rtx x)
5312 return (DEFAULT_ABI == ABI_V4
5313 && !flag_pic && !TARGET_TOC
5314 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5315 && small_data_operand (x, mode));
5318 /* SPE offset addressing is limited to 5-bits worth of double words. */
5319 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5321 bool
5322 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5324 unsigned HOST_WIDE_INT offset, extra;
5326 if (GET_CODE (x) != PLUS)
5327 return false;
5328 if (GET_CODE (XEXP (x, 0)) != REG)
5329 return false;
5330 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5331 return false;
5332 if (!reg_offset_addressing_ok_p (mode))
5333 return virtual_stack_registers_memory_p (x);
5334 if (legitimate_constant_pool_address_p (x, strict))
5335 return true;
5336 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5337 return false;
5339 offset = INTVAL (XEXP (x, 1));
5340 extra = 0;
5341 switch (mode)
5343 case V4HImode:
5344 case V2SImode:
5345 case V1DImode:
5346 case V2SFmode:
5347 /* SPE vector modes. */
5348 return SPE_CONST_OFFSET_OK (offset);
5350 case DFmode:
5351 if (TARGET_E500_DOUBLE)
5352 return SPE_CONST_OFFSET_OK (offset);
5354 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5355 addressing. */
5356 if (VECTOR_MEM_VSX_P (DFmode))
5357 return false;
5359 case DDmode:
5360 case DImode:
5361 /* On e500v2, we may have:
5363 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5365 Which gets addressed with evldd instructions. */
5366 if (TARGET_E500_DOUBLE)
5367 return SPE_CONST_OFFSET_OK (offset);
5369 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5370 extra = 4;
5371 else if (offset & 3)
5372 return false;
5373 break;
5375 case TFmode:
5376 if (TARGET_E500_DOUBLE)
5377 return (SPE_CONST_OFFSET_OK (offset)
5378 && SPE_CONST_OFFSET_OK (offset + 8));
5380 case TDmode:
5381 case TImode:
5382 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5383 extra = 12;
5384 else if (offset & 3)
5385 return false;
5386 else
5387 extra = 8;
5388 break;
5390 default:
5391 break;
5394 offset += 0x8000;
5395 return (offset < 0x10000) && (offset + extra < 0x10000);
5398 bool
5399 legitimate_indexed_address_p (rtx x, int strict)
5401 rtx op0, op1;
5403 if (GET_CODE (x) != PLUS)
5404 return false;
5406 op0 = XEXP (x, 0);
5407 op1 = XEXP (x, 1);
5409 /* Recognize the rtl generated by reload which we know will later be
5410 replaced with proper base and index regs. */
5411 if (!strict
5412 && reload_in_progress
5413 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5414 && REG_P (op1))
5415 return true;
5417 return (REG_P (op0) && REG_P (op1)
5418 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5419 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5420 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5421 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5424 bool
5425 avoiding_indexed_address_p (enum machine_mode mode)
5427 /* Avoid indexed addressing for modes that have non-indexed
5428 load/store instruction forms. */
5429 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5432 inline bool
5433 legitimate_indirect_address_p (rtx x, int strict)
5435 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5438 bool
5439 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5441 if (!TARGET_MACHO || !flag_pic
5442 || mode != SImode || GET_CODE (x) != MEM)
5443 return false;
5444 x = XEXP (x, 0);
5446 if (GET_CODE (x) != LO_SUM)
5447 return false;
5448 if (GET_CODE (XEXP (x, 0)) != REG)
5449 return false;
5450 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5451 return false;
5452 x = XEXP (x, 1);
5454 return CONSTANT_P (x);
5457 static bool
5458 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5460 if (GET_CODE (x) != LO_SUM)
5461 return false;
5462 if (GET_CODE (XEXP (x, 0)) != REG)
5463 return false;
5464 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5465 return false;
5466 /* Restrict addressing for DI because of our SUBREG hackery. */
5467 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5468 || mode == DDmode || mode == TDmode
5469 || mode == DImode))
5470 return false;
5471 x = XEXP (x, 1);
5473 if (TARGET_ELF || TARGET_MACHO)
5475 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5476 return false;
5477 if (TARGET_TOC)
5478 return false;
5479 if (GET_MODE_NUNITS (mode) != 1)
5480 return false;
5481 if (GET_MODE_BITSIZE (mode) > 64
5482 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5483 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5484 && (mode == DFmode || mode == DDmode))))
5485 return false;
5487 return CONSTANT_P (x);
5490 return false;
5494 /* Try machine-dependent ways of modifying an illegitimate address
5495 to be legitimate. If we find one, return the new, valid address.
5496 This is used from only one place: `memory_address' in explow.c.
5498 OLDX is the address as it was before break_out_memory_refs was
5499 called. In some cases it is useful to look at this to decide what
5500 needs to be done.
5502 It is always safe for this function to do nothing. It exists to
5503 recognize opportunities to optimize the output.
5505 On RS/6000, first check for the sum of a register with a constant
5506 integer that is out of range. If so, generate code to add the
5507 constant with the low-order 16 bits masked to the register and force
5508 this result into another register (this can be done with `cau').
5509 Then generate an address of REG+(CONST&0xffff), allowing for the
5510 possibility of bit 16 being a one.
5512 Then check for the sum of a register and something not constant, try to
5513 load the other things into a register and return the sum. */
5515 static rtx
5516 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5517 enum machine_mode mode)
5519 unsigned int extra = 0;
5521 if (!reg_offset_addressing_ok_p (mode))
5523 if (virtual_stack_registers_memory_p (x))
5524 return x;
5526 /* In theory we should not be seeing addresses of the form reg+0,
5527 but just in case it is generated, optimize it away. */
5528 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5529 return force_reg (Pmode, XEXP (x, 0));
5531 /* Make sure both operands are registers. */
5532 else if (GET_CODE (x) == PLUS)
5533 return gen_rtx_PLUS (Pmode,
5534 force_reg (Pmode, XEXP (x, 0)),
5535 force_reg (Pmode, XEXP (x, 1)));
5536 else
5537 return force_reg (Pmode, x);
5539 if (GET_CODE (x) == SYMBOL_REF)
5541 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5542 if (model != 0)
5543 return rs6000_legitimize_tls_address (x, model);
5546 switch (mode)
5548 case DFmode:
5549 case DDmode:
5550 extra = 4;
5551 break;
5552 case DImode:
5553 if (!TARGET_POWERPC64)
5554 extra = 4;
5555 break;
5556 case TFmode:
5557 case TDmode:
5558 extra = 12;
5559 break;
5560 case TImode:
5561 extra = TARGET_POWERPC64 ? 8 : 12;
5562 break;
5563 default:
5564 break;
5567 if (GET_CODE (x) == PLUS
5568 && GET_CODE (XEXP (x, 0)) == REG
5569 && GET_CODE (XEXP (x, 1)) == CONST_INT
5570 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5571 >= 0x10000 - extra)
5572 && !((TARGET_POWERPC64
5573 && (mode == DImode || mode == TImode)
5574 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5575 || SPE_VECTOR_MODE (mode)
5576 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5577 || mode == DImode || mode == DDmode
5578 || mode == TDmode))))
5580 HOST_WIDE_INT high_int, low_int;
5581 rtx sum;
5582 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5583 if (low_int >= 0x8000 - extra)
5584 low_int = 0;
5585 high_int = INTVAL (XEXP (x, 1)) - low_int;
5586 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5587 GEN_INT (high_int)), 0);
5588 return plus_constant (sum, low_int);
5590 else if (GET_CODE (x) == PLUS
5591 && GET_CODE (XEXP (x, 0)) == REG
5592 && GET_CODE (XEXP (x, 1)) != CONST_INT
5593 && GET_MODE_NUNITS (mode) == 1
5594 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5595 || TARGET_POWERPC64
5596 || ((mode != DImode && mode != DFmode && mode != DDmode)
5597 || (TARGET_E500_DOUBLE && mode != DDmode)))
5598 && (TARGET_POWERPC64 || mode != DImode)
5599 && !avoiding_indexed_address_p (mode)
5600 && mode != TImode
5601 && mode != TFmode
5602 && mode != TDmode)
5604 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5605 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5607 else if (SPE_VECTOR_MODE (mode)
5608 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5609 || mode == DDmode || mode == TDmode
5610 || mode == DImode)))
5612 if (mode == DImode)
5613 return x;
5614 /* We accept [reg + reg] and [reg + OFFSET]. */
5616 if (GET_CODE (x) == PLUS)
5618 rtx op1 = XEXP (x, 0);
5619 rtx op2 = XEXP (x, 1);
5620 rtx y;
5622 op1 = force_reg (Pmode, op1);
5624 if (GET_CODE (op2) != REG
5625 && (GET_CODE (op2) != CONST_INT
5626 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5627 || (GET_MODE_SIZE (mode) > 8
5628 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5629 op2 = force_reg (Pmode, op2);
5631 /* We can't always do [reg + reg] for these, because [reg +
5632 reg + offset] is not a legitimate addressing mode. */
5633 y = gen_rtx_PLUS (Pmode, op1, op2);
5635 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5636 return force_reg (Pmode, y);
5637 else
5638 return y;
5641 return force_reg (Pmode, x);
5643 else if (TARGET_ELF
5644 && TARGET_32BIT
5645 && TARGET_NO_TOC
5646 && ! flag_pic
5647 && GET_CODE (x) != CONST_INT
5648 && GET_CODE (x) != CONST_DOUBLE
5649 && CONSTANT_P (x)
5650 && GET_MODE_NUNITS (mode) == 1
5651 && (GET_MODE_BITSIZE (mode) <= 32
5652 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5653 && (mode == DFmode || mode == DDmode))))
5655 rtx reg = gen_reg_rtx (Pmode);
5656 emit_insn (gen_elf_high (reg, x));
5657 return gen_rtx_LO_SUM (Pmode, reg, x);
5659 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5660 && ! flag_pic
5661 #if TARGET_MACHO
5662 && ! MACHO_DYNAMIC_NO_PIC_P
5663 #endif
5664 && GET_CODE (x) != CONST_INT
5665 && GET_CODE (x) != CONST_DOUBLE
5666 && CONSTANT_P (x)
5667 && GET_MODE_NUNITS (mode) == 1
5668 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5669 || (mode != DFmode && mode != DDmode))
5670 && mode != DImode
5671 && mode != TImode)
5673 rtx reg = gen_reg_rtx (Pmode);
5674 emit_insn (gen_macho_high (reg, x));
5675 return gen_rtx_LO_SUM (Pmode, reg, x);
5677 else if (TARGET_TOC
5678 && GET_CODE (x) == SYMBOL_REF
5679 && constant_pool_expr_p (x)
5680 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5682 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5683 return create_TOC_reference (x, reg);
5685 else
5686 return x;
5689 /* Debug version of rs6000_legitimize_address. */
5690 static rtx
5691 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5693 rtx ret;
5694 rtx insns;
5696 start_sequence ();
5697 ret = rs6000_legitimize_address (x, oldx, mode);
5698 insns = get_insns ();
5699 end_sequence ();
5701 if (ret != x)
5703 fprintf (stderr,
5704 "\nrs6000_legitimize_address: mode %s, old code %s, "
5705 "new code %s, modified\n",
5706 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5707 GET_RTX_NAME (GET_CODE (ret)));
5709 fprintf (stderr, "Original address:\n");
5710 debug_rtx (x);
5712 fprintf (stderr, "oldx:\n");
5713 debug_rtx (oldx);
5715 fprintf (stderr, "New address:\n");
5716 debug_rtx (ret);
5718 if (insns)
5720 fprintf (stderr, "Insns added:\n");
5721 debug_rtx_list (insns, 20);
5724 else
5726 fprintf (stderr,
5727 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5728 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5730 debug_rtx (x);
5733 if (insns)
5734 emit_insn (insns);
5736 return ret;
5739 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5740 We need to emit DTP-relative relocations. */
5742 static void
5743 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5745 switch (size)
5747 case 4:
5748 fputs ("\t.long\t", file);
5749 break;
5750 case 8:
5751 fputs (DOUBLE_INT_ASM_OP, file);
5752 break;
5753 default:
5754 gcc_unreachable ();
5756 output_addr_const (file, x);
5757 fputs ("@dtprel+0x8000", file);
5760 /* In the name of slightly smaller debug output, and to cater to
5761 general assembler lossage, recognize various UNSPEC sequences
5762 and turn them back into a direct symbol reference. */
5764 static rtx
5765 rs6000_delegitimize_address (rtx orig_x)
5767 rtx x, y;
5769 orig_x = delegitimize_mem_from_attrs (orig_x);
5770 x = orig_x;
5771 if (MEM_P (x))
5772 x = XEXP (x, 0);
5774 if ((GET_CODE (x) == PLUS
5775 || GET_CODE (x) == LO_SUM)
5776 && GET_CODE (XEXP (x, 0)) == REG
5777 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5778 || TARGET_MINIMAL_TOC
5779 || TARGET_CMODEL != CMODEL_SMALL)
5780 && GET_CODE (XEXP (x, 1)) == CONST)
5782 y = XEXP (XEXP (x, 1), 0);
5783 if (GET_CODE (y) == UNSPEC
5784 && XINT (y, 1) == UNSPEC_TOCREL)
5786 y = XVECEXP (y, 0, 0);
5787 if (!MEM_P (orig_x))
5788 return y;
5789 else
5790 return replace_equiv_address_nv (orig_x, y);
5794 if (TARGET_MACHO
5795 && GET_CODE (orig_x) == LO_SUM
5796 && GET_CODE (XEXP (x, 1)) == CONST)
5798 y = XEXP (XEXP (x, 1), 0);
5799 if (GET_CODE (y) == UNSPEC
5800 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5801 return XVECEXP (y, 0, 0);
5804 return orig_x;
5807 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5809 static GTY(()) rtx rs6000_tls_symbol;
5810 static rtx
5811 rs6000_tls_get_addr (void)
5813 if (!rs6000_tls_symbol)
5814 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5816 return rs6000_tls_symbol;
5819 /* Construct the SYMBOL_REF for TLS GOT references. */
5821 static GTY(()) rtx rs6000_got_symbol;
5822 static rtx
5823 rs6000_got_sym (void)
5825 if (!rs6000_got_symbol)
5827 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5828 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5829 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5832 return rs6000_got_symbol;
5835 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5836 this (thread-local) address. */
5838 static rtx
5839 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5841 rtx dest, insn;
5843 dest = gen_reg_rtx (Pmode);
5844 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5846 rtx tlsreg;
5848 if (TARGET_64BIT)
5850 tlsreg = gen_rtx_REG (Pmode, 13);
5851 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5853 else
5855 tlsreg = gen_rtx_REG (Pmode, 2);
5856 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5858 emit_insn (insn);
5860 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5862 rtx tlsreg, tmp;
5864 tmp = gen_reg_rtx (Pmode);
5865 if (TARGET_64BIT)
5867 tlsreg = gen_rtx_REG (Pmode, 13);
5868 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5870 else
5872 tlsreg = gen_rtx_REG (Pmode, 2);
5873 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5875 emit_insn (insn);
5876 if (TARGET_64BIT)
5877 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5878 else
5879 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5880 emit_insn (insn);
5882 else
5884 rtx r3, got, tga, tmp1, tmp2, call_insn;
5886 /* We currently use relocations like @got@tlsgd for tls, which
5887 means the linker will handle allocation of tls entries, placing
5888 them in the .got section. So use a pointer to the .got section,
5889 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5890 or to secondary GOT sections used by 32-bit -fPIC. */
5891 if (TARGET_64BIT)
5892 got = gen_rtx_REG (Pmode, 2);
5893 else
5895 if (flag_pic == 1)
5896 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5897 else
5899 rtx gsym = rs6000_got_sym ();
5900 got = gen_reg_rtx (Pmode);
5901 if (flag_pic == 0)
5902 rs6000_emit_move (got, gsym, Pmode);
5903 else
5905 rtx mem, lab, last;
5907 tmp1 = gen_reg_rtx (Pmode);
5908 tmp2 = gen_reg_rtx (Pmode);
5909 mem = gen_const_mem (Pmode, tmp1);
5910 lab = gen_label_rtx ();
5911 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5912 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5913 emit_move_insn (tmp2, mem);
5914 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5915 set_unique_reg_note (last, REG_EQUAL, gsym);
5920 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5922 r3 = gen_rtx_REG (Pmode, 3);
5923 tga = rs6000_tls_get_addr ();
5924 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
5926 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5927 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5928 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5929 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5930 else if (DEFAULT_ABI == ABI_V4)
5931 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5932 else
5933 gcc_unreachable ();
5934 call_insn = last_call_insn ();
5935 PATTERN (call_insn) = insn;
5936 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5937 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5938 pic_offset_table_rtx);
5940 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5942 r3 = gen_rtx_REG (Pmode, 3);
5943 tga = rs6000_tls_get_addr ();
5944 tmp1 = gen_reg_rtx (Pmode);
5945 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
5947 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5948 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5949 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5950 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5951 else if (DEFAULT_ABI == ABI_V4)
5952 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5953 else
5954 gcc_unreachable ();
5955 call_insn = last_call_insn ();
5956 PATTERN (call_insn) = insn;
5957 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5958 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5959 pic_offset_table_rtx);
5961 if (rs6000_tls_size == 16)
5963 if (TARGET_64BIT)
5964 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5965 else
5966 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5968 else if (rs6000_tls_size == 32)
5970 tmp2 = gen_reg_rtx (Pmode);
5971 if (TARGET_64BIT)
5972 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5973 else
5974 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5975 emit_insn (insn);
5976 if (TARGET_64BIT)
5977 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5978 else
5979 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5981 else
5983 tmp2 = gen_reg_rtx (Pmode);
5984 if (TARGET_64BIT)
5985 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5986 else
5987 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5988 emit_insn (insn);
5989 insn = gen_rtx_SET (Pmode, dest,
5990 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5992 emit_insn (insn);
5994 else
5996 /* IE, or 64-bit offset LE. */
5997 tmp2 = gen_reg_rtx (Pmode);
5998 if (TARGET_64BIT)
5999 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6000 else
6001 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6002 emit_insn (insn);
6003 if (TARGET_64BIT)
6004 insn = gen_tls_tls_64 (dest, tmp2, addr);
6005 else
6006 insn = gen_tls_tls_32 (dest, tmp2, addr);
6007 emit_insn (insn);
6011 return dest;
6014 /* Return 1 if X contains a thread-local symbol. */
6016 bool
6017 rs6000_tls_referenced_p (rtx x)
6019 if (! TARGET_HAVE_TLS)
6020 return false;
6022 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6025 /* Return 1 if *X is a thread-local symbol. This is the same as
6026 rs6000_tls_symbol_ref except for the type of the unused argument. */
6028 static int
6029 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6031 return RS6000_SYMBOL_REF_TLS_P (*x);
6034 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6035 replace the input X, or the original X if no replacement is called for.
6036 The output parameter *WIN is 1 if the calling macro should goto WIN,
6037 0 if it should not.
6039 For RS/6000, we wish to handle large displacements off a base
6040 register by splitting the addend across an addiu/addis and the mem insn.
6041 This cuts number of extra insns needed from 3 to 1.
6043 On Darwin, we use this to generate code for floating point constants.
6044 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6045 The Darwin code is inside #if TARGET_MACHO because only then are the
6046 machopic_* functions defined. */
6047 static rtx
6048 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6049 int opnum, int type,
6050 int ind_levels ATTRIBUTE_UNUSED, int *win)
6052 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6054 /* We must recognize output that we have already generated ourselves. */
6055 if (GET_CODE (x) == PLUS
6056 && GET_CODE (XEXP (x, 0)) == PLUS
6057 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6058 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6059 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6061 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6062 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6063 opnum, (enum reload_type)type);
6064 *win = 1;
6065 return x;
6068 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6069 if (GET_CODE (x) == LO_SUM
6070 && GET_CODE (XEXP (x, 0)) == HIGH)
6072 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6073 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6074 opnum, (enum reload_type)type);
6075 *win = 1;
6076 return x;
6079 #if TARGET_MACHO
6080 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6081 && GET_CODE (x) == LO_SUM
6082 && GET_CODE (XEXP (x, 0)) == PLUS
6083 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6084 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6085 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6086 && machopic_operand_p (XEXP (x, 1)))
6088 /* Result of previous invocation of this function on Darwin
6089 floating point constant. */
6090 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6091 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6092 opnum, (enum reload_type)type);
6093 *win = 1;
6094 return x;
6096 #endif
6098 if (TARGET_CMODEL != CMODEL_SMALL
6099 && GET_CODE (x) == LO_SUM
6100 && GET_CODE (XEXP (x, 0)) == PLUS
6101 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6102 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6103 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6104 && GET_CODE (XEXP (x, 1)) == CONST
6105 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6106 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6107 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6109 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6110 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6111 opnum, (enum reload_type) type);
6112 *win = 1;
6113 return x;
6116 /* Force ld/std non-word aligned offset into base register by wrapping
6117 in offset 0. */
6118 if (GET_CODE (x) == PLUS
6119 && GET_CODE (XEXP (x, 0)) == REG
6120 && REGNO (XEXP (x, 0)) < 32
6121 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6122 && GET_CODE (XEXP (x, 1)) == CONST_INT
6123 && reg_offset_p
6124 && (INTVAL (XEXP (x, 1)) & 3) != 0
6125 && VECTOR_MEM_NONE_P (mode)
6126 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6127 && TARGET_POWERPC64)
6129 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6130 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6131 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6132 opnum, (enum reload_type) type);
6133 *win = 1;
6134 return x;
6137 if (GET_CODE (x) == PLUS
6138 && GET_CODE (XEXP (x, 0)) == REG
6139 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6140 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6141 && GET_CODE (XEXP (x, 1)) == CONST_INT
6142 && reg_offset_p
6143 && !SPE_VECTOR_MODE (mode)
6144 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6145 || mode == DDmode || mode == TDmode
6146 || mode == DImode))
6147 && VECTOR_MEM_NONE_P (mode))
6149 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6150 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6151 HOST_WIDE_INT high
6152 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6154 /* Check for 32-bit overflow. */
6155 if (high + low != val)
6157 *win = 0;
6158 return x;
6161 /* Reload the high part into a base reg; leave the low part
6162 in the mem directly. */
6164 x = gen_rtx_PLUS (GET_MODE (x),
6165 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6166 GEN_INT (high)),
6167 GEN_INT (low));
6169 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6170 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6171 opnum, (enum reload_type)type);
6172 *win = 1;
6173 return x;
6176 if (GET_CODE (x) == SYMBOL_REF
6177 && reg_offset_p
6178 && VECTOR_MEM_NONE_P (mode)
6179 && !SPE_VECTOR_MODE (mode)
6180 #if TARGET_MACHO
6181 && DEFAULT_ABI == ABI_DARWIN
6182 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6183 #else
6184 && DEFAULT_ABI == ABI_V4
6185 && !flag_pic
6186 #endif
6187 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6188 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6189 without fprs. */
6190 && mode != TFmode
6191 && mode != TDmode
6192 && (mode != DImode || TARGET_POWERPC64)
6193 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6194 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6196 #if TARGET_MACHO
6197 if (flag_pic)
6199 rtx offset = machopic_gen_offset (x);
6200 x = gen_rtx_LO_SUM (GET_MODE (x),
6201 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6202 gen_rtx_HIGH (Pmode, offset)), offset);
6204 else
6205 #endif
6206 x = gen_rtx_LO_SUM (GET_MODE (x),
6207 gen_rtx_HIGH (Pmode, x), x);
6209 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6210 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6211 opnum, (enum reload_type)type);
6212 *win = 1;
6213 return x;
6216 /* Reload an offset address wrapped by an AND that represents the
6217 masking of the lower bits. Strip the outer AND and let reload
6218 convert the offset address into an indirect address. For VSX,
6219 force reload to create the address with an AND in a separate
6220 register, because we can't guarantee an altivec register will
6221 be used. */
6222 if (VECTOR_MEM_ALTIVEC_P (mode)
6223 && GET_CODE (x) == AND
6224 && GET_CODE (XEXP (x, 0)) == PLUS
6225 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6226 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6227 && GET_CODE (XEXP (x, 1)) == CONST_INT
6228 && INTVAL (XEXP (x, 1)) == -16)
6230 x = XEXP (x, 0);
6231 *win = 1;
6232 return x;
6235 if (TARGET_TOC
6236 && reg_offset_p
6237 && GET_CODE (x) == SYMBOL_REF
6238 && constant_pool_expr_p (x)
6239 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6241 x = create_TOC_reference (x, NULL_RTX);
6242 if (TARGET_CMODEL != CMODEL_SMALL)
6243 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6244 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6245 opnum, (enum reload_type) type);
6246 *win = 1;
6247 return x;
6249 *win = 0;
6250 return x;
6253 /* Debug version of rs6000_legitimize_reload_address. */
6254 static rtx
6255 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6256 int opnum, int type,
6257 int ind_levels, int *win)
6259 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6260 ind_levels, win);
6261 fprintf (stderr,
6262 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6263 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6264 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6265 debug_rtx (x);
6267 if (x == ret)
6268 fprintf (stderr, "Same address returned\n");
6269 else if (!ret)
6270 fprintf (stderr, "NULL returned\n");
6271 else
6273 fprintf (stderr, "New address:\n");
6274 debug_rtx (ret);
6277 return ret;
6280 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6281 that is a valid memory address for an instruction.
6282 The MODE argument is the machine mode for the MEM expression
6283 that wants to use this address.
6285 On the RS/6000, there are four valid address: a SYMBOL_REF that
6286 refers to a constant pool entry of an address (or the sum of it
6287 plus a constant), a short (16-bit signed) constant plus a register,
6288 the sum of two registers, or a register indirect, possibly with an
6289 auto-increment. For DFmode, DDmode and DImode with a constant plus
6290 register, we must ensure that both words are addressable or PowerPC64
6291 with offset word aligned.
6293 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6294 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6295 because adjacent memory cells are accessed by adding word-sized offsets
6296 during assembly output. */
6297 bool
6298 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6300 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6302 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6303 if (VECTOR_MEM_ALTIVEC_P (mode)
6304 && GET_CODE (x) == AND
6305 && GET_CODE (XEXP (x, 1)) == CONST_INT
6306 && INTVAL (XEXP (x, 1)) == -16)
6307 x = XEXP (x, 0);
6309 if (RS6000_SYMBOL_REF_TLS_P (x))
6310 return 0;
6311 if (legitimate_indirect_address_p (x, reg_ok_strict))
6312 return 1;
6313 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6314 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6315 && !SPE_VECTOR_MODE (mode)
6316 && mode != TFmode
6317 && mode != TDmode
6318 /* Restrict addressing for DI because of our SUBREG hackery. */
6319 && !(TARGET_E500_DOUBLE
6320 && (mode == DFmode || mode == DDmode || mode == DImode))
6321 && TARGET_UPDATE
6322 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6323 return 1;
6324 if (virtual_stack_registers_memory_p (x))
6325 return 1;
6326 if (reg_offset_p && legitimate_small_data_p (mode, x))
6327 return 1;
6328 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6329 return 1;
6330 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6331 if (! reg_ok_strict
6332 && reg_offset_p
6333 && GET_CODE (x) == PLUS
6334 && GET_CODE (XEXP (x, 0)) == REG
6335 && (XEXP (x, 0) == virtual_stack_vars_rtx
6336 || XEXP (x, 0) == arg_pointer_rtx)
6337 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6338 return 1;
6339 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6340 return 1;
6341 if (mode != TImode
6342 && mode != TFmode
6343 && mode != TDmode
6344 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6345 || TARGET_POWERPC64
6346 || (mode != DFmode && mode != DDmode)
6347 || (TARGET_E500_DOUBLE && mode != DDmode))
6348 && (TARGET_POWERPC64 || mode != DImode)
6349 && !avoiding_indexed_address_p (mode)
6350 && legitimate_indexed_address_p (x, reg_ok_strict))
6351 return 1;
6352 if (GET_CODE (x) == PRE_MODIFY
6353 && mode != TImode
6354 && mode != TFmode
6355 && mode != TDmode
6356 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6357 || TARGET_POWERPC64
6358 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6359 && (TARGET_POWERPC64 || mode != DImode)
6360 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6361 && !SPE_VECTOR_MODE (mode)
6362 /* Restrict addressing for DI because of our SUBREG hackery. */
6363 && !(TARGET_E500_DOUBLE
6364 && (mode == DFmode || mode == DDmode || mode == DImode))
6365 && TARGET_UPDATE
6366 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6367 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6368 || (!avoiding_indexed_address_p (mode)
6369 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6370 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6371 return 1;
6372 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6373 return 1;
6374 return 0;
6377 /* Debug version of rs6000_legitimate_address_p. */
6378 static bool
6379 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6380 bool reg_ok_strict)
6382 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6383 fprintf (stderr,
6384 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6385 "strict = %d, code = %s\n",
6386 ret ? "true" : "false",
6387 GET_MODE_NAME (mode),
6388 reg_ok_strict,
6389 GET_RTX_NAME (GET_CODE (x)));
6390 debug_rtx (x);
6392 return ret;
6395 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6397 static bool
6398 rs6000_mode_dependent_address_p (const_rtx addr)
6400 return rs6000_mode_dependent_address_ptr (addr);
6403 /* Go to LABEL if ADDR (a legitimate address expression)
6404 has an effect that depends on the machine mode it is used for.
6406 On the RS/6000 this is true of all integral offsets (since AltiVec
6407 and VSX modes don't allow them) or is a pre-increment or decrement.
6409 ??? Except that due to conceptual problems in offsettable_address_p
6410 we can't really report the problems of integral offsets. So leave
6411 this assuming that the adjustable offset must be valid for the
6412 sub-words of a TFmode operand, which is what we had before. */
6414 static bool
6415 rs6000_mode_dependent_address (const_rtx addr)
6417 switch (GET_CODE (addr))
6419 case PLUS:
6420 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6421 is considered a legitimate address before reload, so there
6422 are no offset restrictions in that case. Note that this
6423 condition is safe in strict mode because any address involving
6424 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6425 been rejected as illegitimate. */
6426 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6427 && XEXP (addr, 0) != arg_pointer_rtx
6428 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6430 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6431 return val + 12 + 0x8000 >= 0x10000;
6433 break;
6435 case LO_SUM:
6436 /* Anything in the constant pool is sufficiently aligned that
6437 all bytes have the same high part address. */
6438 return !legitimate_constant_pool_address_p (addr, false);
6440 /* Auto-increment cases are now treated generically in recog.c. */
6441 case PRE_MODIFY:
6442 return TARGET_UPDATE;
6444 /* AND is only allowed in Altivec loads. */
6445 case AND:
6446 return true;
6448 default:
6449 break;
6452 return false;
6455 /* Debug version of rs6000_mode_dependent_address. */
6456 static bool
6457 rs6000_debug_mode_dependent_address (const_rtx addr)
6459 bool ret = rs6000_mode_dependent_address (addr);
6461 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6462 ret ? "true" : "false");
6463 debug_rtx (addr);
6465 return ret;
6468 /* Implement FIND_BASE_TERM. */
6471 rs6000_find_base_term (rtx op)
6473 rtx base, offset;
6475 split_const (op, &base, &offset);
6476 if (GET_CODE (base) == UNSPEC)
6477 switch (XINT (base, 1))
6479 case UNSPEC_TOCREL:
6480 case UNSPEC_MACHOPIC_OFFSET:
6481 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6482 for aliasing purposes. */
6483 return XVECEXP (base, 0, 0);
6486 return op;
6489 /* More elaborate version of recog's offsettable_memref_p predicate
6490 that works around the ??? note of rs6000_mode_dependent_address.
6491 In particular it accepts
6493 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6495 in 32-bit mode, that the recog predicate rejects. */
6497 bool
6498 rs6000_offsettable_memref_p (rtx op)
6500 if (!MEM_P (op))
6501 return false;
6503 /* First mimic offsettable_memref_p. */
6504 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6505 return true;
6507 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6508 the latter predicate knows nothing about the mode of the memory
6509 reference and, therefore, assumes that it is the largest supported
6510 mode (TFmode). As a consequence, legitimate offsettable memory
6511 references are rejected. rs6000_legitimate_offset_address_p contains
6512 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6513 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6516 /* Change register usage conditional on target flags. */
6517 void
6518 rs6000_conditional_register_usage (void)
6520 int i;
6522 /* Set MQ register fixed (already call_used) if not POWER
6523 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6524 be allocated. */
6525 if (! TARGET_POWER)
6526 fixed_regs[64] = 1;
6528 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6529 if (TARGET_64BIT)
6530 fixed_regs[13] = call_used_regs[13]
6531 = call_really_used_regs[13] = 1;
6533 /* Conditionally disable FPRs. */
6534 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6535 for (i = 32; i < 64; i++)
6536 fixed_regs[i] = call_used_regs[i]
6537 = call_really_used_regs[i] = 1;
6539 /* The TOC register is not killed across calls in a way that is
6540 visible to the compiler. */
6541 if (DEFAULT_ABI == ABI_AIX)
6542 call_really_used_regs[2] = 0;
6544 if (DEFAULT_ABI == ABI_V4
6545 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6546 && flag_pic == 2)
6547 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6549 if (DEFAULT_ABI == ABI_V4
6550 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6551 && flag_pic == 1)
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 (DEFAULT_ABI == ABI_DARWIN
6557 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6558 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6559 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6560 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6562 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6563 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6564 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6566 if (TARGET_SPE)
6568 global_regs[SPEFSCR_REGNO] = 1;
6569 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6570 registers in prologues and epilogues. We no longer use r14
6571 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6572 pool for link-compatibility with older versions of GCC. Once
6573 "old" code has died out, we can return r14 to the allocation
6574 pool. */
6575 fixed_regs[14]
6576 = call_used_regs[14]
6577 = call_really_used_regs[14] = 1;
6580 if (!TARGET_ALTIVEC && !TARGET_VSX)
6582 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6583 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6584 call_really_used_regs[VRSAVE_REGNO] = 1;
6587 if (TARGET_ALTIVEC || TARGET_VSX)
6588 global_regs[VSCR_REGNO] = 1;
6590 if (TARGET_ALTIVEC_ABI)
6592 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6593 call_used_regs[i] = call_really_used_regs[i] = 1;
6595 /* AIX reserves VR20:31 in non-extended ABI mode. */
6596 if (TARGET_XCOFF)
6597 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6598 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6602 /* Try to output insns to set TARGET equal to the constant C if it can
6603 be done in less than N insns. Do all computations in MODE.
6604 Returns the place where the output has been placed if it can be
6605 done and the insns have been emitted. If it would take more than N
6606 insns, zero is returned and no insns and emitted. */
6609 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6610 rtx source, int n ATTRIBUTE_UNUSED)
6612 rtx result, insn, set;
6613 HOST_WIDE_INT c0, c1;
6615 switch (mode)
6617 case QImode:
6618 case HImode:
6619 if (dest == NULL)
6620 dest = gen_reg_rtx (mode);
6621 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6622 return dest;
6624 case SImode:
6625 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6627 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6628 GEN_INT (INTVAL (source)
6629 & (~ (HOST_WIDE_INT) 0xffff))));
6630 emit_insn (gen_rtx_SET (VOIDmode, dest,
6631 gen_rtx_IOR (SImode, copy_rtx (result),
6632 GEN_INT (INTVAL (source) & 0xffff))));
6633 result = dest;
6634 break;
6636 case DImode:
6637 switch (GET_CODE (source))
6639 case CONST_INT:
6640 c0 = INTVAL (source);
6641 c1 = -(c0 < 0);
6642 break;
6644 case CONST_DOUBLE:
6645 #if HOST_BITS_PER_WIDE_INT >= 64
6646 c0 = CONST_DOUBLE_LOW (source);
6647 c1 = -(c0 < 0);
6648 #else
6649 c0 = CONST_DOUBLE_LOW (source);
6650 c1 = CONST_DOUBLE_HIGH (source);
6651 #endif
6652 break;
6654 default:
6655 gcc_unreachable ();
6658 result = rs6000_emit_set_long_const (dest, c0, c1);
6659 break;
6661 default:
6662 gcc_unreachable ();
6665 insn = get_last_insn ();
6666 set = single_set (insn);
6667 if (! CONSTANT_P (SET_SRC (set)))
6668 set_unique_reg_note (insn, REG_EQUAL, source);
6670 return result;
6673 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6674 fall back to a straight forward decomposition. We do this to avoid
6675 exponential run times encountered when looking for longer sequences
6676 with rs6000_emit_set_const. */
6677 static rtx
6678 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6680 if (!TARGET_POWERPC64)
6682 rtx operand1, operand2;
6684 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6685 DImode);
6686 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6687 DImode);
6688 emit_move_insn (operand1, GEN_INT (c1));
6689 emit_move_insn (operand2, GEN_INT (c2));
6691 else
6693 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6695 ud1 = c1 & 0xffff;
6696 ud2 = (c1 & 0xffff0000) >> 16;
6697 #if HOST_BITS_PER_WIDE_INT >= 64
6698 c2 = c1 >> 32;
6699 #endif
6700 ud3 = c2 & 0xffff;
6701 ud4 = (c2 & 0xffff0000) >> 16;
6703 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6704 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6706 if (ud1 & 0x8000)
6707 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6708 else
6709 emit_move_insn (dest, GEN_INT (ud1));
6712 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6713 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6715 if (ud2 & 0x8000)
6716 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6717 - 0x80000000));
6718 else
6719 emit_move_insn (dest, GEN_INT (ud2 << 16));
6720 if (ud1 != 0)
6721 emit_move_insn (copy_rtx (dest),
6722 gen_rtx_IOR (DImode, copy_rtx (dest),
6723 GEN_INT (ud1)));
6725 else if (ud3 == 0 && ud4 == 0)
6727 gcc_assert (ud2 & 0x8000);
6728 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6729 - 0x80000000));
6730 if (ud1 != 0)
6731 emit_move_insn (copy_rtx (dest),
6732 gen_rtx_IOR (DImode, copy_rtx (dest),
6733 GEN_INT (ud1)));
6734 emit_move_insn (copy_rtx (dest),
6735 gen_rtx_ZERO_EXTEND (DImode,
6736 gen_lowpart (SImode,
6737 copy_rtx (dest))));
6739 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6740 || (ud4 == 0 && ! (ud3 & 0x8000)))
6742 if (ud3 & 0x8000)
6743 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6744 - 0x80000000));
6745 else
6746 emit_move_insn (dest, GEN_INT (ud3 << 16));
6748 if (ud2 != 0)
6749 emit_move_insn (copy_rtx (dest),
6750 gen_rtx_IOR (DImode, copy_rtx (dest),
6751 GEN_INT (ud2)));
6752 emit_move_insn (copy_rtx (dest),
6753 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6754 GEN_INT (16)));
6755 if (ud1 != 0)
6756 emit_move_insn (copy_rtx (dest),
6757 gen_rtx_IOR (DImode, copy_rtx (dest),
6758 GEN_INT (ud1)));
6760 else
6762 if (ud4 & 0x8000)
6763 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6764 - 0x80000000));
6765 else
6766 emit_move_insn (dest, GEN_INT (ud4 << 16));
6768 if (ud3 != 0)
6769 emit_move_insn (copy_rtx (dest),
6770 gen_rtx_IOR (DImode, copy_rtx (dest),
6771 GEN_INT (ud3)));
6773 emit_move_insn (copy_rtx (dest),
6774 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6775 GEN_INT (32)));
6776 if (ud2 != 0)
6777 emit_move_insn (copy_rtx (dest),
6778 gen_rtx_IOR (DImode, copy_rtx (dest),
6779 GEN_INT (ud2 << 16)));
6780 if (ud1 != 0)
6781 emit_move_insn (copy_rtx (dest),
6782 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6785 return dest;
6788 /* Helper for the following. Get rid of [r+r] memory refs
6789 in cases where it won't work (TImode, TFmode, TDmode). */
6791 static void
6792 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6794 if (reload_in_progress)
6795 return;
6797 if (GET_CODE (operands[0]) == MEM
6798 && GET_CODE (XEXP (operands[0], 0)) != REG
6799 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
6800 operands[0]
6801 = replace_equiv_address (operands[0],
6802 copy_addr_to_reg (XEXP (operands[0], 0)));
6804 if (GET_CODE (operands[1]) == MEM
6805 && GET_CODE (XEXP (operands[1], 0)) != REG
6806 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
6807 operands[1]
6808 = replace_equiv_address (operands[1],
6809 copy_addr_to_reg (XEXP (operands[1], 0)));
6812 /* Emit a move from SOURCE to DEST in mode MODE. */
6813 void
6814 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6816 rtx operands[2];
6817 operands[0] = dest;
6818 operands[1] = source;
6820 if (TARGET_DEBUG_ADDR)
6822 fprintf (stderr,
6823 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6824 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6825 GET_MODE_NAME (mode),
6826 reload_in_progress,
6827 reload_completed,
6828 can_create_pseudo_p ());
6829 debug_rtx (dest);
6830 fprintf (stderr, "source:\n");
6831 debug_rtx (source);
6834 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6835 if (GET_CODE (operands[1]) == CONST_DOUBLE
6836 && ! FLOAT_MODE_P (mode)
6837 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6839 /* FIXME. This should never happen. */
6840 /* Since it seems that it does, do the safe thing and convert
6841 to a CONST_INT. */
6842 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6844 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6845 || FLOAT_MODE_P (mode)
6846 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6847 || CONST_DOUBLE_LOW (operands[1]) < 0)
6848 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6849 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6851 /* Check if GCC is setting up a block move that will end up using FP
6852 registers as temporaries. We must make sure this is acceptable. */
6853 if (GET_CODE (operands[0]) == MEM
6854 && GET_CODE (operands[1]) == MEM
6855 && mode == DImode
6856 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6857 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6858 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6859 ? 32 : MEM_ALIGN (operands[0])))
6860 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6861 ? 32
6862 : MEM_ALIGN (operands[1]))))
6863 && ! MEM_VOLATILE_P (operands [0])
6864 && ! MEM_VOLATILE_P (operands [1]))
6866 emit_move_insn (adjust_address (operands[0], SImode, 0),
6867 adjust_address (operands[1], SImode, 0));
6868 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6869 adjust_address (copy_rtx (operands[1]), SImode, 4));
6870 return;
6873 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6874 && !gpc_reg_operand (operands[1], mode))
6875 operands[1] = force_reg (mode, operands[1]);
6877 if (mode == SFmode && ! TARGET_POWERPC
6878 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6879 && GET_CODE (operands[0]) == MEM)
6881 int regnum;
6883 if (reload_in_progress || reload_completed)
6884 regnum = true_regnum (operands[1]);
6885 else if (GET_CODE (operands[1]) == REG)
6886 regnum = REGNO (operands[1]);
6887 else
6888 regnum = -1;
6890 /* If operands[1] is a register, on POWER it may have
6891 double-precision data in it, so truncate it to single
6892 precision. */
6893 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6895 rtx newreg;
6896 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6897 : gen_reg_rtx (mode));
6898 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6899 operands[1] = newreg;
6903 /* Recognize the case where operand[1] is a reference to thread-local
6904 data and load its address to a register. */
6905 if (rs6000_tls_referenced_p (operands[1]))
6907 enum tls_model model;
6908 rtx tmp = operands[1];
6909 rtx addend = NULL;
6911 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6913 addend = XEXP (XEXP (tmp, 0), 1);
6914 tmp = XEXP (XEXP (tmp, 0), 0);
6917 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6918 model = SYMBOL_REF_TLS_MODEL (tmp);
6919 gcc_assert (model != 0);
6921 tmp = rs6000_legitimize_tls_address (tmp, model);
6922 if (addend)
6924 tmp = gen_rtx_PLUS (mode, tmp, addend);
6925 tmp = force_operand (tmp, operands[0]);
6927 operands[1] = tmp;
6930 /* Handle the case where reload calls us with an invalid address. */
6931 if (reload_in_progress && mode == Pmode
6932 && (! general_operand (operands[1], mode)
6933 || ! nonimmediate_operand (operands[0], mode)))
6934 goto emit_set;
6936 /* 128-bit constant floating-point values on Darwin should really be
6937 loaded as two parts. */
6938 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6939 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6941 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6942 know how to get a DFmode SUBREG of a TFmode. */
6943 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6944 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6945 simplify_gen_subreg (imode, operands[1], mode, 0),
6946 imode);
6947 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6948 GET_MODE_SIZE (imode)),
6949 simplify_gen_subreg (imode, operands[1], mode,
6950 GET_MODE_SIZE (imode)),
6951 imode);
6952 return;
6955 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6956 cfun->machine->sdmode_stack_slot =
6957 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6959 if (reload_in_progress
6960 && mode == SDmode
6961 && MEM_P (operands[0])
6962 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6963 && REG_P (operands[1]))
6965 if (FP_REGNO_P (REGNO (operands[1])))
6967 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6968 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6969 emit_insn (gen_movsd_store (mem, operands[1]));
6971 else if (INT_REGNO_P (REGNO (operands[1])))
6973 rtx mem = adjust_address_nv (operands[0], mode, 4);
6974 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6975 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6977 else
6978 gcc_unreachable();
6979 return;
6981 if (reload_in_progress
6982 && mode == SDmode
6983 && REG_P (operands[0])
6984 && MEM_P (operands[1])
6985 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6987 if (FP_REGNO_P (REGNO (operands[0])))
6989 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6990 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6991 emit_insn (gen_movsd_load (operands[0], mem));
6993 else if (INT_REGNO_P (REGNO (operands[0])))
6995 rtx mem = adjust_address_nv (operands[1], mode, 4);
6996 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6997 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6999 else
7000 gcc_unreachable();
7001 return;
7004 /* FIXME: In the long term, this switch statement should go away
7005 and be replaced by a sequence of tests based on things like
7006 mode == Pmode. */
7007 switch (mode)
7009 case HImode:
7010 case QImode:
7011 if (CONSTANT_P (operands[1])
7012 && GET_CODE (operands[1]) != CONST_INT)
7013 operands[1] = force_const_mem (mode, operands[1]);
7014 break;
7016 case TFmode:
7017 case TDmode:
7018 rs6000_eliminate_indexed_memrefs (operands);
7019 /* fall through */
7021 case DFmode:
7022 case DDmode:
7023 case SFmode:
7024 case SDmode:
7025 if (CONSTANT_P (operands[1])
7026 && ! easy_fp_constant (operands[1], mode))
7027 operands[1] = force_const_mem (mode, operands[1]);
7028 break;
7030 case V16QImode:
7031 case V8HImode:
7032 case V4SFmode:
7033 case V4SImode:
7034 case V4HImode:
7035 case V2SFmode:
7036 case V2SImode:
7037 case V1DImode:
7038 case V2DFmode:
7039 case V2DImode:
7040 if (CONSTANT_P (operands[1])
7041 && !easy_vector_constant (operands[1], mode))
7042 operands[1] = force_const_mem (mode, operands[1]);
7043 break;
7045 case SImode:
7046 case DImode:
7047 /* Use default pattern for address of ELF small data */
7048 if (TARGET_ELF
7049 && mode == Pmode
7050 && DEFAULT_ABI == ABI_V4
7051 && (GET_CODE (operands[1]) == SYMBOL_REF
7052 || GET_CODE (operands[1]) == CONST)
7053 && small_data_operand (operands[1], mode))
7055 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7056 return;
7059 if (DEFAULT_ABI == ABI_V4
7060 && mode == Pmode && mode == SImode
7061 && flag_pic == 1 && got_operand (operands[1], mode))
7063 emit_insn (gen_movsi_got (operands[0], operands[1]));
7064 return;
7067 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7068 && TARGET_NO_TOC
7069 && ! flag_pic
7070 && mode == Pmode
7071 && CONSTANT_P (operands[1])
7072 && GET_CODE (operands[1]) != HIGH
7073 && GET_CODE (operands[1]) != CONST_INT)
7075 rtx target = (!can_create_pseudo_p ()
7076 ? operands[0]
7077 : gen_reg_rtx (mode));
7079 /* If this is a function address on -mcall-aixdesc,
7080 convert it to the address of the descriptor. */
7081 if (DEFAULT_ABI == ABI_AIX
7082 && GET_CODE (operands[1]) == SYMBOL_REF
7083 && XSTR (operands[1], 0)[0] == '.')
7085 const char *name = XSTR (operands[1], 0);
7086 rtx new_ref;
7087 while (*name == '.')
7088 name++;
7089 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7090 CONSTANT_POOL_ADDRESS_P (new_ref)
7091 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7092 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7093 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7094 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7095 operands[1] = new_ref;
7098 if (DEFAULT_ABI == ABI_DARWIN)
7100 #if TARGET_MACHO
7101 if (MACHO_DYNAMIC_NO_PIC_P)
7103 /* Take care of any required data indirection. */
7104 operands[1] = rs6000_machopic_legitimize_pic_address (
7105 operands[1], mode, operands[0]);
7106 if (operands[0] != operands[1])
7107 emit_insn (gen_rtx_SET (VOIDmode,
7108 operands[0], operands[1]));
7109 return;
7111 #endif
7112 emit_insn (gen_macho_high (target, operands[1]));
7113 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7114 return;
7117 emit_insn (gen_elf_high (target, operands[1]));
7118 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7119 return;
7122 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7123 and we have put it in the TOC, we just need to make a TOC-relative
7124 reference to it. */
7125 if (TARGET_TOC
7126 && GET_CODE (operands[1]) == SYMBOL_REF
7127 && constant_pool_expr_p (operands[1])
7128 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7129 get_pool_mode (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]) != CONST_INT
7144 && ! easy_fp_constant (operands[1], mode))
7145 || (GET_CODE (operands[1]) == CONST_INT
7146 && (num_insns_constant (operands[1], mode)
7147 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7148 || (GET_CODE (operands[0]) == REG
7149 && FP_REGNO_P (REGNO (operands[0]))))
7150 && GET_CODE (operands[1]) != HIGH
7151 && ! legitimate_constant_pool_address_p (operands[1], false)
7152 && ! toc_relative_expr_p (operands[1])
7153 && (TARGET_CMODEL == CMODEL_SMALL
7154 || can_create_pseudo_p ()
7155 || (REG_P (operands[0])
7156 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7159 #if TARGET_MACHO
7160 /* Darwin uses a special PIC legitimizer. */
7161 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7163 operands[1] =
7164 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7165 operands[0]);
7166 if (operands[0] != operands[1])
7167 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7168 return;
7170 #endif
7172 /* If we are to limit the number of things we put in the TOC and
7173 this is a symbol plus a constant we can add in one insn,
7174 just put the symbol in the TOC and add the constant. Don't do
7175 this if reload is in progress. */
7176 if (GET_CODE (operands[1]) == CONST
7177 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7178 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7179 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7180 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7181 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7182 && ! side_effects_p (operands[0]))
7184 rtx sym =
7185 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7186 rtx other = XEXP (XEXP (operands[1], 0), 1);
7188 sym = force_reg (mode, sym);
7189 emit_insn (gen_add3_insn (operands[0], sym, other));
7190 return;
7193 operands[1] = force_const_mem (mode, operands[1]);
7195 if (TARGET_TOC
7196 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7197 && constant_pool_expr_p (XEXP (operands[1], 0))
7198 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7199 get_pool_constant (XEXP (operands[1], 0)),
7200 get_pool_mode (XEXP (operands[1], 0))))
7202 rtx tocref;
7203 rtx reg = NULL_RTX;
7204 if (TARGET_CMODEL != CMODEL_SMALL)
7206 if (can_create_pseudo_p ())
7207 reg = gen_reg_rtx (Pmode);
7208 else
7209 reg = operands[0];
7211 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7212 operands[1] = gen_const_mem (mode, tocref);
7213 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7216 break;
7218 case TImode:
7219 rs6000_eliminate_indexed_memrefs (operands);
7221 if (TARGET_POWER)
7223 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7224 gen_rtvec (2,
7225 gen_rtx_SET (VOIDmode,
7226 operands[0], operands[1]),
7227 gen_rtx_CLOBBER (VOIDmode,
7228 gen_rtx_SCRATCH (SImode)))));
7229 return;
7231 break;
7233 default:
7234 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7237 /* Above, we may have called force_const_mem which may have returned
7238 an invalid address. If we can, fix this up; otherwise, reload will
7239 have to deal with it. */
7240 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7241 operands[1] = validize_mem (operands[1]);
7243 emit_set:
7244 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7247 /* Nonzero if we can use a floating-point register to pass this arg. */
7248 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7249 (SCALAR_FLOAT_MODE_P (MODE) \
7250 && (CUM)->fregno <= FP_ARG_MAX_REG \
7251 && TARGET_HARD_FLOAT && TARGET_FPRS)
7253 /* Nonzero if we can use an AltiVec register to pass this arg. */
7254 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7255 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7256 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7257 && TARGET_ALTIVEC_ABI \
7258 && (NAMED))
7260 /* Return a nonzero value to say to return the function value in
7261 memory, just as large structures are always returned. TYPE will be
7262 the data type of the value, and FNTYPE will be the type of the
7263 function doing the returning, or @code{NULL} for libcalls.
7265 The AIX ABI for the RS/6000 specifies that all structures are
7266 returned in memory. The Darwin ABI does the same. The SVR4 ABI
7267 specifies that structures <= 8 bytes are returned in r3/r4, but a
7268 draft put them in memory, and GCC used to implement the draft
7269 instead of the final standard. Therefore, aix_struct_return
7270 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7271 compatibility can change DRAFT_V4_STRUCT_RET to override the
7272 default, and -m switches get the final word. See
7273 rs6000_override_options for more details.
7275 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7276 long double support is enabled. These values are returned in memory.
7278 int_size_in_bytes returns -1 for variable size objects, which go in
7279 memory always. The cast to unsigned makes -1 > 8. */
7281 static bool
7282 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7284 /* In the darwin64 abi, try to use registers for larger structs
7285 if possible. */
7286 if (rs6000_darwin64_abi
7287 && TREE_CODE (type) == RECORD_TYPE
7288 && int_size_in_bytes (type) > 0)
7290 CUMULATIVE_ARGS valcum;
7291 rtx valret;
7293 valcum.words = 0;
7294 valcum.fregno = FP_ARG_MIN_REG;
7295 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7296 /* Do a trial code generation as if this were going to be passed
7297 as an argument; if any part goes in memory, we return NULL. */
7298 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
7299 if (valret)
7300 return false;
7301 /* Otherwise fall through to more conventional ABI rules. */
7304 if (AGGREGATE_TYPE_P (type)
7305 && (aix_struct_return
7306 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7307 return true;
7309 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7310 modes only exist for GCC vector types if -maltivec. */
7311 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7312 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7313 return false;
7315 /* Return synthetic vectors in memory. */
7316 if (TREE_CODE (type) == VECTOR_TYPE
7317 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7319 static bool warned_for_return_big_vectors = false;
7320 if (!warned_for_return_big_vectors)
7322 warning (0, "GCC vector returned by reference: "
7323 "non-standard ABI extension with no compatibility guarantee");
7324 warned_for_return_big_vectors = true;
7326 return true;
7329 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7330 return true;
7332 return false;
7335 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7336 for a call to a function whose data type is FNTYPE.
7337 For a library call, FNTYPE is 0.
7339 For incoming args we set the number of arguments in the prototype large
7340 so we never return a PARALLEL. */
7342 void
7343 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7344 rtx libname ATTRIBUTE_UNUSED, int incoming,
7345 int libcall, int n_named_args)
7347 static CUMULATIVE_ARGS zero_cumulative;
7349 *cum = zero_cumulative;
7350 cum->words = 0;
7351 cum->fregno = FP_ARG_MIN_REG;
7352 cum->vregno = ALTIVEC_ARG_MIN_REG;
7353 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7354 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7355 ? CALL_LIBCALL : CALL_NORMAL);
7356 cum->sysv_gregno = GP_ARG_MIN_REG;
7357 cum->stdarg = fntype
7358 && (TYPE_ARG_TYPES (fntype) != 0
7359 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
7360 != void_type_node));
7362 cum->nargs_prototype = 0;
7363 if (incoming || cum->prototype)
7364 cum->nargs_prototype = n_named_args;
7366 /* Check for a longcall attribute. */
7367 if ((!fntype && rs6000_default_long_calls)
7368 || (fntype
7369 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7370 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7371 cum->call_cookie |= CALL_LONG;
7373 if (TARGET_DEBUG_ARG)
7375 fprintf (stderr, "\ninit_cumulative_args:");
7376 if (fntype)
7378 tree ret_type = TREE_TYPE (fntype);
7379 fprintf (stderr, " ret code = %s,",
7380 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7383 if (cum->call_cookie & CALL_LONG)
7384 fprintf (stderr, " longcall,");
7386 fprintf (stderr, " proto = %d, nargs = %d\n",
7387 cum->prototype, cum->nargs_prototype);
7390 if (fntype
7391 && !TARGET_ALTIVEC
7392 && TARGET_ALTIVEC_ABI
7393 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7395 error ("cannot return value in vector register because"
7396 " altivec instructions are disabled, use -maltivec"
7397 " to enable them");
7401 /* Return true if TYPE must be passed on the stack and not in registers. */
7403 static bool
7404 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7406 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7407 return must_pass_in_stack_var_size (mode, type);
7408 else
7409 return must_pass_in_stack_var_size_or_pad (mode, type);
7412 /* If defined, a C expression which determines whether, and in which
7413 direction, to pad out an argument with extra space. The value
7414 should be of type `enum direction': either `upward' to pad above
7415 the argument, `downward' to pad below, or `none' to inhibit
7416 padding.
7418 For the AIX ABI structs are always stored left shifted in their
7419 argument slot. */
7421 enum direction
7422 function_arg_padding (enum machine_mode mode, const_tree type)
7424 #ifndef AGGREGATE_PADDING_FIXED
7425 #define AGGREGATE_PADDING_FIXED 0
7426 #endif
7427 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7428 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7429 #endif
7431 if (!AGGREGATE_PADDING_FIXED)
7433 /* GCC used to pass structures of the same size as integer types as
7434 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7435 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7436 passed padded downward, except that -mstrict-align further
7437 muddied the water in that multi-component structures of 2 and 4
7438 bytes in size were passed padded upward.
7440 The following arranges for best compatibility with previous
7441 versions of gcc, but removes the -mstrict-align dependency. */
7442 if (BYTES_BIG_ENDIAN)
7444 HOST_WIDE_INT size = 0;
7446 if (mode == BLKmode)
7448 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7449 size = int_size_in_bytes (type);
7451 else
7452 size = GET_MODE_SIZE (mode);
7454 if (size == 1 || size == 2 || size == 4)
7455 return downward;
7457 return upward;
7460 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7462 if (type != 0 && AGGREGATE_TYPE_P (type))
7463 return upward;
7466 /* Fall back to the default. */
7467 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7470 /* If defined, a C expression that gives the alignment boundary, in bits,
7471 of an argument with the specified mode and type. If it is not defined,
7472 PARM_BOUNDARY is used for all arguments.
7474 V.4 wants long longs and doubles to be double word aligned. Just
7475 testing the mode size is a boneheaded way to do this as it means
7476 that other types such as complex int are also double word aligned.
7477 However, we're stuck with this because changing the ABI might break
7478 existing library interfaces.
7480 Doubleword align SPE vectors.
7481 Quadword align Altivec vectors.
7482 Quadword align large synthetic vector types. */
7485 function_arg_boundary (enum machine_mode mode, tree type)
7487 if (DEFAULT_ABI == ABI_V4
7488 && (GET_MODE_SIZE (mode) == 8
7489 || (TARGET_HARD_FLOAT
7490 && TARGET_FPRS
7491 && (mode == TFmode || mode == TDmode))))
7492 return 64;
7493 else if (SPE_VECTOR_MODE (mode)
7494 || (type && TREE_CODE (type) == VECTOR_TYPE
7495 && int_size_in_bytes (type) >= 8
7496 && int_size_in_bytes (type) < 16))
7497 return 64;
7498 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7499 || (type && TREE_CODE (type) == VECTOR_TYPE
7500 && int_size_in_bytes (type) >= 16))
7501 return 128;
7502 else if (rs6000_darwin64_abi && mode == BLKmode
7503 && type && TYPE_ALIGN (type) > 64)
7504 return 128;
7505 else
7506 return PARM_BOUNDARY;
7509 /* For a function parm of MODE and TYPE, return the starting word in
7510 the parameter area. NWORDS of the parameter area are already used. */
7512 static unsigned int
7513 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
7515 unsigned int align;
7516 unsigned int parm_offset;
7518 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7519 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7520 return nwords + (-(parm_offset + nwords) & align);
7523 /* Compute the size (in words) of a function argument. */
7525 static unsigned long
7526 rs6000_arg_size (enum machine_mode mode, tree type)
7528 unsigned long size;
7530 if (mode != BLKmode)
7531 size = GET_MODE_SIZE (mode);
7532 else
7533 size = int_size_in_bytes (type);
7535 if (TARGET_32BIT)
7536 return (size + 3) >> 2;
7537 else
7538 return (size + 7) >> 3;
7541 /* Use this to flush pending int fields. */
7543 static void
7544 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7545 HOST_WIDE_INT bitpos, int final)
7547 unsigned int startbit, endbit;
7548 int intregs, intoffset;
7549 enum machine_mode mode;
7551 /* Handle the situations where a float is taking up the first half
7552 of the GPR, and the other half is empty (typically due to
7553 alignment restrictions). We can detect this by a 8-byte-aligned
7554 int field, or by seeing that this is the final flush for this
7555 argument. Count the word and continue on. */
7556 if (cum->floats_in_gpr == 1
7557 && (cum->intoffset % 64 == 0
7558 || (cum->intoffset == -1 && final)))
7560 cum->words++;
7561 cum->floats_in_gpr = 0;
7564 if (cum->intoffset == -1)
7565 return;
7567 intoffset = cum->intoffset;
7568 cum->intoffset = -1;
7569 cum->floats_in_gpr = 0;
7571 if (intoffset % BITS_PER_WORD != 0)
7573 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7574 MODE_INT, 0);
7575 if (mode == BLKmode)
7577 /* We couldn't find an appropriate mode, which happens,
7578 e.g., in packed structs when there are 3 bytes to load.
7579 Back intoffset back to the beginning of the word in this
7580 case. */
7581 intoffset = intoffset & -BITS_PER_WORD;
7585 startbit = intoffset & -BITS_PER_WORD;
7586 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7587 intregs = (endbit - startbit) / BITS_PER_WORD;
7588 cum->words += intregs;
7589 /* words should be unsigned. */
7590 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7592 int pad = (endbit/BITS_PER_WORD) - cum->words;
7593 cum->words += pad;
7597 /* The darwin64 ABI calls for us to recurse down through structs,
7598 looking for elements passed in registers. Unfortunately, we have
7599 to track int register count here also because of misalignments
7600 in powerpc alignment mode. */
7602 static void
7603 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7604 tree type,
7605 HOST_WIDE_INT startbitpos)
7607 tree f;
7609 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7610 if (TREE_CODE (f) == FIELD_DECL)
7612 HOST_WIDE_INT bitpos = startbitpos;
7613 tree ftype = TREE_TYPE (f);
7614 enum machine_mode mode;
7615 if (ftype == error_mark_node)
7616 continue;
7617 mode = TYPE_MODE (ftype);
7619 if (DECL_SIZE (f) != 0
7620 && host_integerp (bit_position (f), 1))
7621 bitpos += int_bit_position (f);
7623 /* ??? FIXME: else assume zero offset. */
7625 if (TREE_CODE (ftype) == RECORD_TYPE)
7626 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7627 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7629 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7630 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7631 /* Single-precision floats present a special problem for
7632 us, because they are smaller than an 8-byte GPR, and so
7633 the structure-packing rules combined with the standard
7634 varargs behavior mean that we want to pack float/float
7635 and float/int combinations into a single register's
7636 space. This is complicated by the arg advance flushing,
7637 which works on arbitrarily large groups of int-type
7638 fields. */
7639 if (mode == SFmode)
7641 if (cum->floats_in_gpr == 1)
7643 /* Two floats in a word; count the word and reset
7644 the float count. */
7645 cum->words++;
7646 cum->floats_in_gpr = 0;
7648 else if (bitpos % 64 == 0)
7650 /* A float at the beginning of an 8-byte word;
7651 count it and put off adjusting cum->words until
7652 we see if a arg advance flush is going to do it
7653 for us. */
7654 cum->floats_in_gpr++;
7656 else
7658 /* The float is at the end of a word, preceded
7659 by integer fields, so the arg advance flush
7660 just above has already set cum->words and
7661 everything is taken care of. */
7664 else
7665 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7667 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7669 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7670 cum->vregno++;
7671 cum->words += 2;
7673 else if (cum->intoffset == -1)
7674 cum->intoffset = bitpos;
7678 /* Update the data in CUM to advance over an argument
7679 of mode MODE and data type TYPE.
7680 (TYPE is null for libcalls where that information may not be available.)
7682 Note that for args passed by reference, function_arg will be called
7683 with MODE and TYPE set to that of the pointer to the arg, not the arg
7684 itself. */
7686 void
7687 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7688 tree type, int named, int depth)
7690 int size;
7692 /* Only tick off an argument if we're not recursing. */
7693 if (depth == 0)
7694 cum->nargs_prototype--;
7696 if (TARGET_ALTIVEC_ABI
7697 && (ALTIVEC_VECTOR_MODE (mode)
7698 || VSX_VECTOR_MODE (mode)
7699 || (type && TREE_CODE (type) == VECTOR_TYPE
7700 && int_size_in_bytes (type) == 16)))
7702 bool stack = false;
7704 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7706 cum->vregno++;
7707 if (!TARGET_ALTIVEC)
7708 error ("cannot pass argument in vector register because"
7709 " altivec instructions are disabled, use -maltivec"
7710 " to enable them");
7712 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7713 even if it is going to be passed in a vector register.
7714 Darwin does the same for variable-argument functions. */
7715 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7716 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7717 stack = true;
7719 else
7720 stack = true;
7722 if (stack)
7724 int align;
7726 /* Vector parameters must be 16-byte aligned. This places
7727 them at 2 mod 4 in terms of words in 32-bit mode, since
7728 the parameter save area starts at offset 24 from the
7729 stack. In 64-bit mode, they just have to start on an
7730 even word, since the parameter save area is 16-byte
7731 aligned. Space for GPRs is reserved even if the argument
7732 will be passed in memory. */
7733 if (TARGET_32BIT)
7734 align = (2 - cum->words) & 3;
7735 else
7736 align = cum->words & 1;
7737 cum->words += align + rs6000_arg_size (mode, type);
7739 if (TARGET_DEBUG_ARG)
7741 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7742 cum->words, align);
7743 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7744 cum->nargs_prototype, cum->prototype,
7745 GET_MODE_NAME (mode));
7749 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7750 && !cum->stdarg
7751 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7752 cum->sysv_gregno++;
7754 else if (rs6000_darwin64_abi
7755 && mode == BLKmode
7756 && TREE_CODE (type) == RECORD_TYPE
7757 && (size = int_size_in_bytes (type)) > 0)
7759 /* Variable sized types have size == -1 and are
7760 treated as if consisting entirely of ints.
7761 Pad to 16 byte boundary if needed. */
7762 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7763 && (cum->words % 2) != 0)
7764 cum->words++;
7765 /* For varargs, we can just go up by the size of the struct. */
7766 if (!named)
7767 cum->words += (size + 7) / 8;
7768 else
7770 /* It is tempting to say int register count just goes up by
7771 sizeof(type)/8, but this is wrong in a case such as
7772 { int; double; int; } [powerpc alignment]. We have to
7773 grovel through the fields for these too. */
7774 cum->intoffset = 0;
7775 cum->floats_in_gpr = 0;
7776 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7777 rs6000_darwin64_record_arg_advance_flush (cum,
7778 size * BITS_PER_UNIT, 1);
7780 if (TARGET_DEBUG_ARG)
7782 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
7783 cum->words, TYPE_ALIGN (type), size);
7784 fprintf (stderr,
7785 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi BLK)\n",
7786 cum->nargs_prototype, cum->prototype,
7787 GET_MODE_NAME (mode));
7790 else if (DEFAULT_ABI == ABI_V4)
7792 if (TARGET_HARD_FLOAT && TARGET_FPRS
7793 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7794 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7795 || (mode == TFmode && !TARGET_IEEEQUAD)
7796 || mode == SDmode || mode == DDmode || mode == TDmode))
7798 /* _Decimal128 must use an even/odd register pair. This assumes
7799 that the register number is odd when fregno is odd. */
7800 if (mode == TDmode && (cum->fregno % 2) == 1)
7801 cum->fregno++;
7803 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7804 <= FP_ARG_V4_MAX_REG)
7805 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7806 else
7808 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7809 if (mode == DFmode || mode == TFmode
7810 || mode == DDmode || mode == TDmode)
7811 cum->words += cum->words & 1;
7812 cum->words += rs6000_arg_size (mode, type);
7815 else
7817 int n_words = rs6000_arg_size (mode, type);
7818 int gregno = cum->sysv_gregno;
7820 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7821 (r7,r8) or (r9,r10). As does any other 2 word item such
7822 as complex int due to a historical mistake. */
7823 if (n_words == 2)
7824 gregno += (1 - gregno) & 1;
7826 /* Multi-reg args are not split between registers and stack. */
7827 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7829 /* Long long and SPE vectors are aligned on the stack.
7830 So are other 2 word items such as complex int due to
7831 a historical mistake. */
7832 if (n_words == 2)
7833 cum->words += cum->words & 1;
7834 cum->words += n_words;
7837 /* Note: continuing to accumulate gregno past when we've started
7838 spilling to the stack indicates the fact that we've started
7839 spilling to the stack to expand_builtin_saveregs. */
7840 cum->sysv_gregno = gregno + n_words;
7843 if (TARGET_DEBUG_ARG)
7845 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7846 cum->words, cum->fregno);
7847 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7848 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7849 fprintf (stderr, "mode = %4s, named = %d\n",
7850 GET_MODE_NAME (mode), named);
7853 else
7855 int n_words = rs6000_arg_size (mode, type);
7856 int start_words = cum->words;
7857 int align_words = rs6000_parm_start (mode, type, start_words);
7859 cum->words = align_words + n_words;
7861 if (SCALAR_FLOAT_MODE_P (mode)
7862 && TARGET_HARD_FLOAT && TARGET_FPRS)
7864 /* _Decimal128 must be passed in an even/odd float register pair.
7865 This assumes that the register number is odd when fregno is
7866 odd. */
7867 if (mode == TDmode && (cum->fregno % 2) == 1)
7868 cum->fregno++;
7869 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7872 if (TARGET_DEBUG_ARG)
7874 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7875 cum->words, cum->fregno);
7876 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7877 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7878 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7879 named, align_words - start_words, depth);
7884 static rtx
7885 spe_build_register_parallel (enum machine_mode mode, int gregno)
7887 rtx r1, r3, r5, r7;
7889 switch (mode)
7891 case DFmode:
7892 r1 = gen_rtx_REG (DImode, gregno);
7893 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7894 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7896 case DCmode:
7897 case TFmode:
7898 r1 = gen_rtx_REG (DImode, gregno);
7899 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7900 r3 = gen_rtx_REG (DImode, gregno + 2);
7901 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7902 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7904 case TCmode:
7905 r1 = gen_rtx_REG (DImode, gregno);
7906 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7907 r3 = gen_rtx_REG (DImode, gregno + 2);
7908 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7909 r5 = gen_rtx_REG (DImode, gregno + 4);
7910 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7911 r7 = gen_rtx_REG (DImode, gregno + 6);
7912 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7913 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7915 default:
7916 gcc_unreachable ();
7920 /* Determine where to put a SIMD argument on the SPE. */
7921 static rtx
7922 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7923 tree type)
7925 int gregno = cum->sysv_gregno;
7927 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7928 are passed and returned in a pair of GPRs for ABI compatibility. */
7929 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7930 || mode == DCmode || mode == TCmode))
7932 int n_words = rs6000_arg_size (mode, type);
7934 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7935 if (mode == DFmode)
7936 gregno += (1 - gregno) & 1;
7938 /* Multi-reg args are not split between registers and stack. */
7939 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7940 return NULL_RTX;
7942 return spe_build_register_parallel (mode, gregno);
7944 if (cum->stdarg)
7946 int n_words = rs6000_arg_size (mode, type);
7948 /* SPE vectors are put in odd registers. */
7949 if (n_words == 2 && (gregno & 1) == 0)
7950 gregno += 1;
7952 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7954 rtx r1, r2;
7955 enum machine_mode m = SImode;
7957 r1 = gen_rtx_REG (m, gregno);
7958 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7959 r2 = gen_rtx_REG (m, gregno + 1);
7960 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7961 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7963 else
7964 return NULL_RTX;
7966 else
7968 if (gregno <= GP_ARG_MAX_REG)
7969 return gen_rtx_REG (mode, gregno);
7970 else
7971 return NULL_RTX;
7975 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7976 structure between cum->intoffset and bitpos to integer registers. */
7978 static void
7979 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7980 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7982 enum machine_mode mode;
7983 unsigned int regno;
7984 unsigned int startbit, endbit;
7985 int this_regno, intregs, intoffset;
7986 rtx reg;
7988 if (cum->intoffset == -1)
7989 return;
7991 intoffset = cum->intoffset;
7992 cum->intoffset = -1;
7994 /* If this is the trailing part of a word, try to only load that
7995 much into the register. Otherwise load the whole register. Note
7996 that in the latter case we may pick up unwanted bits. It's not a
7997 problem at the moment but may wish to revisit. */
7999 if (intoffset % BITS_PER_WORD != 0)
8001 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8002 MODE_INT, 0);
8003 if (mode == BLKmode)
8005 /* We couldn't find an appropriate mode, which happens,
8006 e.g., in packed structs when there are 3 bytes to load.
8007 Back intoffset back to the beginning of the word in this
8008 case. */
8009 intoffset = intoffset & -BITS_PER_WORD;
8010 mode = word_mode;
8013 else
8014 mode = word_mode;
8016 startbit = intoffset & -BITS_PER_WORD;
8017 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8018 intregs = (endbit - startbit) / BITS_PER_WORD;
8019 this_regno = cum->words + intoffset / BITS_PER_WORD;
8021 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8022 cum->use_stack = 1;
8024 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8025 if (intregs <= 0)
8026 return;
8028 intoffset /= BITS_PER_UNIT;
8031 regno = GP_ARG_MIN_REG + this_regno;
8032 reg = gen_rtx_REG (mode, regno);
8033 rvec[(*k)++] =
8034 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8036 this_regno += 1;
8037 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8038 mode = word_mode;
8039 intregs -= 1;
8041 while (intregs > 0);
8044 /* Recursive workhorse for the following. */
8046 static void
8047 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8048 HOST_WIDE_INT startbitpos, rtx rvec[],
8049 int *k)
8051 tree f;
8053 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8054 if (TREE_CODE (f) == FIELD_DECL)
8056 HOST_WIDE_INT bitpos = startbitpos;
8057 tree ftype = TREE_TYPE (f);
8058 enum machine_mode mode;
8059 if (ftype == error_mark_node)
8060 continue;
8061 mode = TYPE_MODE (ftype);
8063 if (DECL_SIZE (f) != 0
8064 && host_integerp (bit_position (f), 1))
8065 bitpos += int_bit_position (f);
8067 /* ??? FIXME: else assume zero offset. */
8069 if (TREE_CODE (ftype) == RECORD_TYPE)
8070 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8071 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8073 #if 0
8074 switch (mode)
8076 case SCmode: mode = SFmode; break;
8077 case DCmode: mode = DFmode; break;
8078 case TCmode: mode = TFmode; break;
8079 default: break;
8081 #endif
8082 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8083 rvec[(*k)++]
8084 = gen_rtx_EXPR_LIST (VOIDmode,
8085 gen_rtx_REG (mode, cum->fregno++),
8086 GEN_INT (bitpos / BITS_PER_UNIT));
8087 if (mode == TFmode || mode == TDmode)
8088 cum->fregno++;
8090 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8092 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8093 rvec[(*k)++]
8094 = gen_rtx_EXPR_LIST (VOIDmode,
8095 gen_rtx_REG (mode, cum->vregno++),
8096 GEN_INT (bitpos / BITS_PER_UNIT));
8098 else if (cum->intoffset == -1)
8099 cum->intoffset = bitpos;
8103 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8104 the register(s) to be used for each field and subfield of a struct
8105 being passed by value, along with the offset of where the
8106 register's value may be found in the block. FP fields go in FP
8107 register, vector fields go in vector registers, and everything
8108 else goes in int registers, packed as in memory.
8110 This code is also used for function return values. RETVAL indicates
8111 whether this is the case.
8113 Much of this is taken from the SPARC V9 port, which has a similar
8114 calling convention. */
8116 static rtx
8117 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8118 int named, bool retval)
8120 rtx rvec[FIRST_PSEUDO_REGISTER];
8121 int k = 1, kbase = 1;
8122 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8123 /* This is a copy; modifications are not visible to our caller. */
8124 CUMULATIVE_ARGS copy_cum = *orig_cum;
8125 CUMULATIVE_ARGS *cum = &copy_cum;
8127 /* Pad to 16 byte boundary if needed. */
8128 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8129 && (cum->words % 2) != 0)
8130 cum->words++;
8132 cum->intoffset = 0;
8133 cum->use_stack = 0;
8134 cum->named = named;
8136 /* Put entries into rvec[] for individual FP and vector fields, and
8137 for the chunks of memory that go in int regs. Note we start at
8138 element 1; 0 is reserved for an indication of using memory, and
8139 may or may not be filled in below. */
8140 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8141 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8143 /* If any part of the struct went on the stack put all of it there.
8144 This hack is because the generic code for
8145 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8146 parts of the struct are not at the beginning. */
8147 if (cum->use_stack)
8149 if (retval)
8150 return NULL_RTX; /* doesn't go in registers at all */
8151 kbase = 0;
8152 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8154 if (k > 1 || cum->use_stack)
8155 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8156 else
8157 return NULL_RTX;
8160 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8162 static rtx
8163 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
8165 int n_units;
8166 int i, k;
8167 rtx rvec[GP_ARG_NUM_REG + 1];
8169 if (align_words >= GP_ARG_NUM_REG)
8170 return NULL_RTX;
8172 n_units = rs6000_arg_size (mode, type);
8174 /* Optimize the simple case where the arg fits in one gpr, except in
8175 the case of BLKmode due to assign_parms assuming that registers are
8176 BITS_PER_WORD wide. */
8177 if (n_units == 0
8178 || (n_units == 1 && mode != BLKmode))
8179 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8181 k = 0;
8182 if (align_words + n_units > GP_ARG_NUM_REG)
8183 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8184 using a magic NULL_RTX component.
8185 This is not strictly correct. Only some of the arg belongs in
8186 memory, not all of it. However, the normal scheme using
8187 function_arg_partial_nregs can result in unusual subregs, eg.
8188 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8189 store the whole arg to memory is often more efficient than code
8190 to store pieces, and we know that space is available in the right
8191 place for the whole arg. */
8192 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8194 i = 0;
8197 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8198 rtx off = GEN_INT (i++ * 4);
8199 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8201 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8203 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8206 /* Determine where to put an argument to a function.
8207 Value is zero to push the argument on the stack,
8208 or a hard register in which to store the argument.
8210 MODE is the argument's machine mode.
8211 TYPE is the data type of the argument (as a tree).
8212 This is null for libcalls where that information may
8213 not be available.
8214 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8215 the preceding args and about the function being called. It is
8216 not modified in this routine.
8217 NAMED is nonzero if this argument is a named parameter
8218 (otherwise it is an extra parameter matching an ellipsis).
8220 On RS/6000 the first eight words of non-FP are normally in registers
8221 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8222 Under V.4, the first 8 FP args are in registers.
8224 If this is floating-point and no prototype is specified, we use
8225 both an FP and integer register (or possibly FP reg and stack). Library
8226 functions (when CALL_LIBCALL is set) always have the proper types for args,
8227 so we can pass the FP value just in one register. emit_library_function
8228 doesn't support PARALLEL anyway.
8230 Note that for args passed by reference, function_arg will be called
8231 with MODE and TYPE set to that of the pointer to the arg, not the arg
8232 itself. */
8235 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8236 tree type, int named)
8238 enum rs6000_abi abi = DEFAULT_ABI;
8240 /* Return a marker to indicate whether CR1 needs to set or clear the
8241 bit that V.4 uses to say fp args were passed in registers.
8242 Assume that we don't need the marker for software floating point,
8243 or compiler generated library calls. */
8244 if (mode == VOIDmode)
8246 if (abi == ABI_V4
8247 && (cum->call_cookie & CALL_LIBCALL) == 0
8248 && (cum->stdarg
8249 || (cum->nargs_prototype < 0
8250 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8252 /* For the SPE, we need to crxor CR6 always. */
8253 if (TARGET_SPE_ABI)
8254 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8255 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8256 return GEN_INT (cum->call_cookie
8257 | ((cum->fregno == FP_ARG_MIN_REG)
8258 ? CALL_V4_SET_FP_ARGS
8259 : CALL_V4_CLEAR_FP_ARGS));
8262 return GEN_INT (cum->call_cookie);
8265 if (rs6000_darwin64_abi && mode == BLKmode
8266 && TREE_CODE (type) == RECORD_TYPE)
8268 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8269 if (rslt != NULL_RTX)
8270 return rslt;
8271 /* Else fall through to usual handling. */
8274 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8275 if (TARGET_64BIT && ! cum->prototype)
8277 /* Vector parameters get passed in vector register
8278 and also in GPRs or memory, in absence of prototype. */
8279 int align_words;
8280 rtx slot;
8281 align_words = (cum->words + 1) & ~1;
8283 if (align_words >= GP_ARG_NUM_REG)
8285 slot = NULL_RTX;
8287 else
8289 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8291 return gen_rtx_PARALLEL (mode,
8292 gen_rtvec (2,
8293 gen_rtx_EXPR_LIST (VOIDmode,
8294 slot, const0_rtx),
8295 gen_rtx_EXPR_LIST (VOIDmode,
8296 gen_rtx_REG (mode, cum->vregno),
8297 const0_rtx)));
8299 else
8300 return gen_rtx_REG (mode, cum->vregno);
8301 else if (TARGET_ALTIVEC_ABI
8302 && (ALTIVEC_VECTOR_MODE (mode)
8303 || VSX_VECTOR_MODE (mode)
8304 || (type && TREE_CODE (type) == VECTOR_TYPE
8305 && int_size_in_bytes (type) == 16)))
8307 if (named || abi == ABI_V4)
8308 return NULL_RTX;
8309 else
8311 /* Vector parameters to varargs functions under AIX or Darwin
8312 get passed in memory and possibly also in GPRs. */
8313 int align, align_words, n_words;
8314 enum machine_mode part_mode;
8316 /* Vector parameters must be 16-byte aligned. This places them at
8317 2 mod 4 in terms of words in 32-bit mode, since the parameter
8318 save area starts at offset 24 from the stack. In 64-bit mode,
8319 they just have to start on an even word, since the parameter
8320 save area is 16-byte aligned. */
8321 if (TARGET_32BIT)
8322 align = (2 - cum->words) & 3;
8323 else
8324 align = cum->words & 1;
8325 align_words = cum->words + align;
8327 /* Out of registers? Memory, then. */
8328 if (align_words >= GP_ARG_NUM_REG)
8329 return NULL_RTX;
8331 if (TARGET_32BIT && TARGET_POWERPC64)
8332 return rs6000_mixed_function_arg (mode, type, align_words);
8334 /* The vector value goes in GPRs. Only the part of the
8335 value in GPRs is reported here. */
8336 part_mode = mode;
8337 n_words = rs6000_arg_size (mode, type);
8338 if (align_words + n_words > GP_ARG_NUM_REG)
8339 /* Fortunately, there are only two possibilities, the value
8340 is either wholly in GPRs or half in GPRs and half not. */
8341 part_mode = DImode;
8343 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8346 else if (TARGET_SPE_ABI && TARGET_SPE
8347 && (SPE_VECTOR_MODE (mode)
8348 || (TARGET_E500_DOUBLE && (mode == DFmode
8349 || mode == DCmode
8350 || mode == TFmode
8351 || mode == TCmode))))
8352 return rs6000_spe_function_arg (cum, mode, type);
8354 else if (abi == ABI_V4)
8356 if (TARGET_HARD_FLOAT && TARGET_FPRS
8357 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8358 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8359 || (mode == TFmode && !TARGET_IEEEQUAD)
8360 || mode == SDmode || mode == DDmode || mode == TDmode))
8362 /* _Decimal128 must use an even/odd register pair. This assumes
8363 that the register number is odd when fregno is odd. */
8364 if (mode == TDmode && (cum->fregno % 2) == 1)
8365 cum->fregno++;
8367 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8368 <= FP_ARG_V4_MAX_REG)
8369 return gen_rtx_REG (mode, cum->fregno);
8370 else
8371 return NULL_RTX;
8373 else
8375 int n_words = rs6000_arg_size (mode, type);
8376 int gregno = cum->sysv_gregno;
8378 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8379 (r7,r8) or (r9,r10). As does any other 2 word item such
8380 as complex int due to a historical mistake. */
8381 if (n_words == 2)
8382 gregno += (1 - gregno) & 1;
8384 /* Multi-reg args are not split between registers and stack. */
8385 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8386 return NULL_RTX;
8388 if (TARGET_32BIT && TARGET_POWERPC64)
8389 return rs6000_mixed_function_arg (mode, type,
8390 gregno - GP_ARG_MIN_REG);
8391 return gen_rtx_REG (mode, gregno);
8394 else
8396 int align_words = rs6000_parm_start (mode, type, cum->words);
8398 /* _Decimal128 must be passed in an even/odd float register pair.
8399 This assumes that the register number is odd when fregno is odd. */
8400 if (mode == TDmode && (cum->fregno % 2) == 1)
8401 cum->fregno++;
8403 if (USE_FP_FOR_ARG_P (cum, mode, type))
8405 rtx rvec[GP_ARG_NUM_REG + 1];
8406 rtx r;
8407 int k;
8408 bool needs_psave;
8409 enum machine_mode fmode = mode;
8410 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8412 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8414 /* Currently, we only ever need one reg here because complex
8415 doubles are split. */
8416 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8417 && (fmode == TFmode || fmode == TDmode));
8419 /* Long double or _Decimal128 split over regs and memory. */
8420 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8423 /* Do we also need to pass this arg in the parameter save
8424 area? */
8425 needs_psave = (type
8426 && (cum->nargs_prototype <= 0
8427 || (DEFAULT_ABI == ABI_AIX
8428 && TARGET_XL_COMPAT
8429 && align_words >= GP_ARG_NUM_REG)));
8431 if (!needs_psave && mode == fmode)
8432 return gen_rtx_REG (fmode, cum->fregno);
8434 k = 0;
8435 if (needs_psave)
8437 /* Describe the part that goes in gprs or the stack.
8438 This piece must come first, before the fprs. */
8439 if (align_words < GP_ARG_NUM_REG)
8441 unsigned long n_words = rs6000_arg_size (mode, type);
8443 if (align_words + n_words > GP_ARG_NUM_REG
8444 || (TARGET_32BIT && TARGET_POWERPC64))
8446 /* If this is partially on the stack, then we only
8447 include the portion actually in registers here. */
8448 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8449 rtx off;
8450 int i = 0;
8451 if (align_words + n_words > GP_ARG_NUM_REG)
8452 /* Not all of the arg fits in gprs. Say that it
8453 goes in memory too, using a magic NULL_RTX
8454 component. Also see comment in
8455 rs6000_mixed_function_arg for why the normal
8456 function_arg_partial_nregs scheme doesn't work
8457 in this case. */
8458 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8459 const0_rtx);
8462 r = gen_rtx_REG (rmode,
8463 GP_ARG_MIN_REG + align_words);
8464 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8465 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8467 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8469 else
8471 /* The whole arg fits in gprs. */
8472 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8473 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8476 else
8477 /* It's entirely in memory. */
8478 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8481 /* Describe where this piece goes in the fprs. */
8482 r = gen_rtx_REG (fmode, cum->fregno);
8483 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8485 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8487 else if (align_words < GP_ARG_NUM_REG)
8489 if (TARGET_32BIT && TARGET_POWERPC64)
8490 return rs6000_mixed_function_arg (mode, type, align_words);
8492 if (mode == BLKmode)
8493 mode = Pmode;
8495 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8497 else
8498 return NULL_RTX;
8502 /* For an arg passed partly in registers and partly in memory, this is
8503 the number of bytes passed in registers. For args passed entirely in
8504 registers or entirely in memory, zero. When an arg is described by a
8505 PARALLEL, perhaps using more than one register type, this function
8506 returns the number of bytes used by the first element of the PARALLEL. */
8508 static int
8509 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8510 tree type, bool named)
8512 int ret = 0;
8513 int align_words;
8515 if (DEFAULT_ABI == ABI_V4)
8516 return 0;
8518 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8519 && cum->nargs_prototype >= 0)
8520 return 0;
8522 /* In this complicated case we just disable the partial_nregs code. */
8523 if (rs6000_darwin64_abi && mode == BLKmode
8524 && TREE_CODE (type) == RECORD_TYPE
8525 && int_size_in_bytes (type) > 0)
8526 return 0;
8528 align_words = rs6000_parm_start (mode, type, cum->words);
8530 if (USE_FP_FOR_ARG_P (cum, mode, type))
8532 /* If we are passing this arg in the fixed parameter save area
8533 (gprs or memory) as well as fprs, then this function should
8534 return the number of partial bytes passed in the parameter
8535 save area rather than partial bytes passed in fprs. */
8536 if (type
8537 && (cum->nargs_prototype <= 0
8538 || (DEFAULT_ABI == ABI_AIX
8539 && TARGET_XL_COMPAT
8540 && align_words >= GP_ARG_NUM_REG)))
8541 return 0;
8542 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8543 > FP_ARG_MAX_REG + 1)
8544 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8545 else if (cum->nargs_prototype >= 0)
8546 return 0;
8549 if (align_words < GP_ARG_NUM_REG
8550 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8551 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8553 if (ret != 0 && TARGET_DEBUG_ARG)
8554 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8556 return ret;
8559 /* A C expression that indicates when an argument must be passed by
8560 reference. If nonzero for an argument, a copy of that argument is
8561 made in memory and a pointer to the argument is passed instead of
8562 the argument itself. The pointer is passed in whatever way is
8563 appropriate for passing a pointer to that type.
8565 Under V.4, aggregates and long double are passed by reference.
8567 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8568 reference unless the AltiVec vector extension ABI is in force.
8570 As an extension to all ABIs, variable sized types are passed by
8571 reference. */
8573 static bool
8574 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8575 enum machine_mode mode, const_tree type,
8576 bool named ATTRIBUTE_UNUSED)
8578 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8580 if (TARGET_DEBUG_ARG)
8581 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8582 return 1;
8585 if (!type)
8586 return 0;
8588 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8590 if (TARGET_DEBUG_ARG)
8591 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8592 return 1;
8595 if (int_size_in_bytes (type) < 0)
8597 if (TARGET_DEBUG_ARG)
8598 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8599 return 1;
8602 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8603 modes only exist for GCC vector types if -maltivec. */
8604 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8606 if (TARGET_DEBUG_ARG)
8607 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8608 return 1;
8611 /* Pass synthetic vectors in memory. */
8612 if (TREE_CODE (type) == VECTOR_TYPE
8613 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8615 static bool warned_for_pass_big_vectors = false;
8616 if (TARGET_DEBUG_ARG)
8617 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8618 if (!warned_for_pass_big_vectors)
8620 warning (0, "GCC vector passed by reference: "
8621 "non-standard ABI extension with no compatibility guarantee");
8622 warned_for_pass_big_vectors = true;
8624 return 1;
8627 return 0;
8630 static void
8631 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8633 int i;
8634 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8636 if (nregs == 0)
8637 return;
8639 for (i = 0; i < nregs; i++)
8641 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8642 if (reload_completed)
8644 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8645 tem = NULL_RTX;
8646 else
8647 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8648 i * GET_MODE_SIZE (reg_mode));
8650 else
8651 tem = replace_equiv_address (tem, XEXP (tem, 0));
8653 gcc_assert (tem);
8655 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8659 /* Perform any needed actions needed for a function that is receiving a
8660 variable number of arguments.
8662 CUM is as above.
8664 MODE and TYPE are the mode and type of the current parameter.
8666 PRETEND_SIZE is a variable that should be set to the amount of stack
8667 that must be pushed by the prolog to pretend that our caller pushed
8670 Normally, this macro will push all remaining incoming registers on the
8671 stack and set PRETEND_SIZE to the length of the registers pushed. */
8673 static void
8674 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8675 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8676 int no_rtl)
8678 CUMULATIVE_ARGS next_cum;
8679 int reg_size = TARGET_32BIT ? 4 : 8;
8680 rtx save_area = NULL_RTX, mem;
8681 int first_reg_offset;
8682 alias_set_type set;
8684 /* Skip the last named argument. */
8685 next_cum = *cum;
8686 function_arg_advance (&next_cum, mode, type, 1, 0);
8688 if (DEFAULT_ABI == ABI_V4)
8690 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8692 if (! no_rtl)
8694 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8695 HOST_WIDE_INT offset = 0;
8697 /* Try to optimize the size of the varargs save area.
8698 The ABI requires that ap.reg_save_area is doubleword
8699 aligned, but we don't need to allocate space for all
8700 the bytes, only those to which we actually will save
8701 anything. */
8702 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8703 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8704 if (TARGET_HARD_FLOAT && TARGET_FPRS
8705 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8706 && cfun->va_list_fpr_size)
8708 if (gpr_reg_num)
8709 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8710 * UNITS_PER_FP_WORD;
8711 if (cfun->va_list_fpr_size
8712 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8713 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8714 else
8715 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8716 * UNITS_PER_FP_WORD;
8718 if (gpr_reg_num)
8720 offset = -((first_reg_offset * reg_size) & ~7);
8721 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8723 gpr_reg_num = cfun->va_list_gpr_size;
8724 if (reg_size == 4 && (first_reg_offset & 1))
8725 gpr_reg_num++;
8727 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8729 else if (fpr_size)
8730 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8731 * UNITS_PER_FP_WORD
8732 - (int) (GP_ARG_NUM_REG * reg_size);
8734 if (gpr_size + fpr_size)
8736 rtx reg_save_area
8737 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8738 gcc_assert (GET_CODE (reg_save_area) == MEM);
8739 reg_save_area = XEXP (reg_save_area, 0);
8740 if (GET_CODE (reg_save_area) == PLUS)
8742 gcc_assert (XEXP (reg_save_area, 0)
8743 == virtual_stack_vars_rtx);
8744 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8745 offset += INTVAL (XEXP (reg_save_area, 1));
8747 else
8748 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8751 cfun->machine->varargs_save_offset = offset;
8752 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8755 else
8757 first_reg_offset = next_cum.words;
8758 save_area = virtual_incoming_args_rtx;
8760 if (targetm.calls.must_pass_in_stack (mode, type))
8761 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8764 set = get_varargs_alias_set ();
8765 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8766 && cfun->va_list_gpr_size)
8768 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8770 if (va_list_gpr_counter_field)
8772 /* V4 va_list_gpr_size counts number of registers needed. */
8773 if (nregs > cfun->va_list_gpr_size)
8774 nregs = cfun->va_list_gpr_size;
8776 else
8778 /* char * va_list instead counts number of bytes needed. */
8779 if (nregs > cfun->va_list_gpr_size / reg_size)
8780 nregs = cfun->va_list_gpr_size / reg_size;
8783 mem = gen_rtx_MEM (BLKmode,
8784 plus_constant (save_area,
8785 first_reg_offset * reg_size));
8786 MEM_NOTRAP_P (mem) = 1;
8787 set_mem_alias_set (mem, set);
8788 set_mem_align (mem, BITS_PER_WORD);
8790 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8791 nregs);
8794 /* Save FP registers if needed. */
8795 if (DEFAULT_ABI == ABI_V4
8796 && TARGET_HARD_FLOAT && TARGET_FPRS
8797 && ! no_rtl
8798 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8799 && cfun->va_list_fpr_size)
8801 int fregno = next_cum.fregno, nregs;
8802 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8803 rtx lab = gen_label_rtx ();
8804 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8805 * UNITS_PER_FP_WORD);
8807 emit_jump_insn
8808 (gen_rtx_SET (VOIDmode,
8809 pc_rtx,
8810 gen_rtx_IF_THEN_ELSE (VOIDmode,
8811 gen_rtx_NE (VOIDmode, cr1,
8812 const0_rtx),
8813 gen_rtx_LABEL_REF (VOIDmode, lab),
8814 pc_rtx)));
8816 for (nregs = 0;
8817 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8818 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8820 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8821 ? DFmode : SFmode,
8822 plus_constant (save_area, off));
8823 MEM_NOTRAP_P (mem) = 1;
8824 set_mem_alias_set (mem, set);
8825 set_mem_align (mem, GET_MODE_ALIGNMENT (
8826 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8827 ? DFmode : SFmode));
8828 emit_move_insn (mem, gen_rtx_REG (
8829 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8830 ? DFmode : SFmode, fregno));
8833 emit_label (lab);
8837 /* Create the va_list data type. */
8839 static tree
8840 rs6000_build_builtin_va_list (void)
8842 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8844 /* For AIX, prefer 'char *' because that's what the system
8845 header files like. */
8846 if (DEFAULT_ABI != ABI_V4)
8847 return build_pointer_type (char_type_node);
8849 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8850 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8851 get_identifier ("__va_list_tag"), record);
8853 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8854 unsigned_char_type_node);
8855 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8856 unsigned_char_type_node);
8857 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8858 every user file. */
8859 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8860 get_identifier ("reserved"), short_unsigned_type_node);
8861 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8862 get_identifier ("overflow_arg_area"),
8863 ptr_type_node);
8864 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8865 get_identifier ("reg_save_area"),
8866 ptr_type_node);
8868 va_list_gpr_counter_field = f_gpr;
8869 va_list_fpr_counter_field = f_fpr;
8871 DECL_FIELD_CONTEXT (f_gpr) = record;
8872 DECL_FIELD_CONTEXT (f_fpr) = record;
8873 DECL_FIELD_CONTEXT (f_res) = record;
8874 DECL_FIELD_CONTEXT (f_ovf) = record;
8875 DECL_FIELD_CONTEXT (f_sav) = record;
8877 TREE_CHAIN (record) = type_decl;
8878 TYPE_NAME (record) = type_decl;
8879 TYPE_FIELDS (record) = f_gpr;
8880 DECL_CHAIN (f_gpr) = f_fpr;
8881 DECL_CHAIN (f_fpr) = f_res;
8882 DECL_CHAIN (f_res) = f_ovf;
8883 DECL_CHAIN (f_ovf) = f_sav;
8885 layout_type (record);
8887 /* The correct type is an array type of one element. */
8888 return build_array_type (record, build_index_type (size_zero_node));
8891 /* Implement va_start. */
8893 static void
8894 rs6000_va_start (tree valist, rtx nextarg)
8896 HOST_WIDE_INT words, n_gpr, n_fpr;
8897 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8898 tree gpr, fpr, ovf, sav, t;
8900 /* Only SVR4 needs something special. */
8901 if (DEFAULT_ABI != ABI_V4)
8903 std_expand_builtin_va_start (valist, nextarg);
8904 return;
8907 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8908 f_fpr = DECL_CHAIN (f_gpr);
8909 f_res = DECL_CHAIN (f_fpr);
8910 f_ovf = DECL_CHAIN (f_res);
8911 f_sav = DECL_CHAIN (f_ovf);
8913 valist = build_va_arg_indirect_ref (valist);
8914 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8915 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8916 f_fpr, NULL_TREE);
8917 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8918 f_ovf, NULL_TREE);
8919 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8920 f_sav, NULL_TREE);
8922 /* Count number of gp and fp argument registers used. */
8923 words = crtl->args.info.words;
8924 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8925 GP_ARG_NUM_REG);
8926 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8927 FP_ARG_NUM_REG);
8929 if (TARGET_DEBUG_ARG)
8930 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8931 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8932 words, n_gpr, n_fpr);
8934 if (cfun->va_list_gpr_size)
8936 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8937 build_int_cst (NULL_TREE, n_gpr));
8938 TREE_SIDE_EFFECTS (t) = 1;
8939 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8942 if (cfun->va_list_fpr_size)
8944 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8945 build_int_cst (NULL_TREE, n_fpr));
8946 TREE_SIDE_EFFECTS (t) = 1;
8947 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8950 /* Find the overflow area. */
8951 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8952 if (words != 0)
8953 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8954 size_int (words * UNITS_PER_WORD));
8955 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8956 TREE_SIDE_EFFECTS (t) = 1;
8957 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8959 /* If there were no va_arg invocations, don't set up the register
8960 save area. */
8961 if (!cfun->va_list_gpr_size
8962 && !cfun->va_list_fpr_size
8963 && n_gpr < GP_ARG_NUM_REG
8964 && n_fpr < FP_ARG_V4_MAX_REG)
8965 return;
8967 /* Find the register save area. */
8968 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8969 if (cfun->machine->varargs_save_offset)
8970 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8971 size_int (cfun->machine->varargs_save_offset));
8972 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8973 TREE_SIDE_EFFECTS (t) = 1;
8974 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8977 /* Implement va_arg. */
8979 tree
8980 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8981 gimple_seq *post_p)
8983 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8984 tree gpr, fpr, ovf, sav, reg, t, u;
8985 int size, rsize, n_reg, sav_ofs, sav_scale;
8986 tree lab_false, lab_over, addr;
8987 int align;
8988 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8989 int regalign = 0;
8990 gimple stmt;
8992 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8994 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8995 return build_va_arg_indirect_ref (t);
8998 if (DEFAULT_ABI != ABI_V4)
9000 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9002 tree elem_type = TREE_TYPE (type);
9003 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9004 int elem_size = GET_MODE_SIZE (elem_mode);
9006 if (elem_size < UNITS_PER_WORD)
9008 tree real_part, imag_part;
9009 gimple_seq post = NULL;
9011 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9012 &post);
9013 /* Copy the value into a temporary, lest the formal temporary
9014 be reused out from under us. */
9015 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9016 gimple_seq_add_seq (pre_p, post);
9018 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9019 post_p);
9021 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9025 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9028 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9029 f_fpr = DECL_CHAIN (f_gpr);
9030 f_res = DECL_CHAIN (f_fpr);
9031 f_ovf = DECL_CHAIN (f_res);
9032 f_sav = DECL_CHAIN (f_ovf);
9034 valist = build_va_arg_indirect_ref (valist);
9035 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9036 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9037 f_fpr, NULL_TREE);
9038 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9039 f_ovf, NULL_TREE);
9040 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9041 f_sav, NULL_TREE);
9043 size = int_size_in_bytes (type);
9044 rsize = (size + 3) / 4;
9045 align = 1;
9047 if (TARGET_HARD_FLOAT && TARGET_FPRS
9048 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9049 || (TARGET_DOUBLE_FLOAT
9050 && (TYPE_MODE (type) == DFmode
9051 || TYPE_MODE (type) == TFmode
9052 || TYPE_MODE (type) == SDmode
9053 || TYPE_MODE (type) == DDmode
9054 || TYPE_MODE (type) == TDmode))))
9056 /* FP args go in FP registers, if present. */
9057 reg = fpr;
9058 n_reg = (size + 7) / 8;
9059 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9060 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9061 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9062 align = 8;
9064 else
9066 /* Otherwise into GP registers. */
9067 reg = gpr;
9068 n_reg = rsize;
9069 sav_ofs = 0;
9070 sav_scale = 4;
9071 if (n_reg == 2)
9072 align = 8;
9075 /* Pull the value out of the saved registers.... */
9077 lab_over = NULL;
9078 addr = create_tmp_var (ptr_type_node, "addr");
9080 /* AltiVec vectors never go in registers when -mabi=altivec. */
9081 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9082 align = 16;
9083 else
9085 lab_false = create_artificial_label (input_location);
9086 lab_over = create_artificial_label (input_location);
9088 /* Long long and SPE vectors are aligned in the registers.
9089 As are any other 2 gpr item such as complex int due to a
9090 historical mistake. */
9091 u = reg;
9092 if (n_reg == 2 && reg == gpr)
9094 regalign = 1;
9095 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9096 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9097 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9098 unshare_expr (reg), u);
9100 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9101 reg number is 0 for f1, so we want to make it odd. */
9102 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9104 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9105 build_int_cst (TREE_TYPE (reg), 1));
9106 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9109 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9110 t = build2 (GE_EXPR, boolean_type_node, u, t);
9111 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9112 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9113 gimplify_and_add (t, pre_p);
9115 t = sav;
9116 if (sav_ofs)
9117 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9119 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9120 build_int_cst (TREE_TYPE (reg), n_reg));
9121 u = fold_convert (sizetype, u);
9122 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9123 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9125 /* _Decimal32 varargs are located in the second word of the 64-bit
9126 FP register for 32-bit binaries. */
9127 if (!TARGET_POWERPC64
9128 && TARGET_HARD_FLOAT && TARGET_FPRS
9129 && TYPE_MODE (type) == SDmode)
9130 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9132 gimplify_assign (addr, t, pre_p);
9134 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9136 stmt = gimple_build_label (lab_false);
9137 gimple_seq_add_stmt (pre_p, stmt);
9139 if ((n_reg == 2 && !regalign) || n_reg > 2)
9141 /* Ensure that we don't find any more args in regs.
9142 Alignment has taken care of for special cases. */
9143 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9147 /* ... otherwise out of the overflow area. */
9149 /* Care for on-stack alignment if needed. */
9150 t = ovf;
9151 if (align != 1)
9153 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9154 t = fold_convert (sizetype, t);
9155 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9156 size_int (-align));
9157 t = fold_convert (TREE_TYPE (ovf), t);
9159 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9161 gimplify_assign (unshare_expr (addr), t, pre_p);
9163 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9164 gimplify_assign (unshare_expr (ovf), t, pre_p);
9166 if (lab_over)
9168 stmt = gimple_build_label (lab_over);
9169 gimple_seq_add_stmt (pre_p, stmt);
9172 if (STRICT_ALIGNMENT
9173 && (TYPE_ALIGN (type)
9174 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9176 /* The value (of type complex double, for example) may not be
9177 aligned in memory in the saved registers, so copy via a
9178 temporary. (This is the same code as used for SPARC.) */
9179 tree tmp = create_tmp_var (type, "va_arg_tmp");
9180 tree dest_addr = build_fold_addr_expr (tmp);
9182 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9183 3, dest_addr, addr, size_int (rsize * 4));
9185 gimplify_and_add (copy, pre_p);
9186 addr = dest_addr;
9189 addr = fold_convert (ptrtype, addr);
9190 return build_va_arg_indirect_ref (addr);
9193 /* Builtins. */
9195 static void
9196 def_builtin (int mask, const char *name, tree type, int code)
9198 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9200 tree t;
9201 if (rs6000_builtin_decls[code])
9202 fatal_error ("internal error: builtin function to %s already processed.",
9203 name);
9205 rs6000_builtin_decls[code] = t =
9206 add_builtin_function (name, type, code, BUILT_IN_MD,
9207 NULL, NULL_TREE);
9209 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9210 switch (builtin_classify[code])
9212 default:
9213 gcc_unreachable ();
9215 /* assume builtin can do anything. */
9216 case RS6000_BTC_MISC:
9217 break;
9219 /* const function, function only depends on the inputs. */
9220 case RS6000_BTC_CONST:
9221 TREE_READONLY (t) = 1;
9222 TREE_NOTHROW (t) = 1;
9223 break;
9225 /* pure function, function can read global memory. */
9226 case RS6000_BTC_PURE:
9227 DECL_PURE_P (t) = 1;
9228 TREE_NOTHROW (t) = 1;
9229 break;
9231 /* Function is a math function. If rounding mode is on, then treat
9232 the function as not reading global memory, but it can have
9233 arbitrary side effects. If it is off, then assume the function is
9234 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9235 attribute in builtin-attribute.def that is used for the math
9236 functions. */
9237 case RS6000_BTC_FP_PURE:
9238 TREE_NOTHROW (t) = 1;
9239 if (flag_rounding_math)
9241 DECL_PURE_P (t) = 1;
9242 DECL_IS_NOVOPS (t) = 1;
9244 else
9245 TREE_READONLY (t) = 1;
9246 break;
9251 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9253 static const struct builtin_description bdesc_3arg[] =
9255 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9256 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9257 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9258 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9259 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9260 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9261 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9262 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9263 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9264 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9265 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9266 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9267 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9268 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9269 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9270 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9271 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9272 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9273 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9274 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9275 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9276 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9277 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9278 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9279 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9280 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9281 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9282 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9283 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9284 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9285 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9286 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9287 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9288 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9289 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9291 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9292 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9293 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9294 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9295 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9296 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9297 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9298 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9299 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9300 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9301 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9302 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9303 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9304 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9305 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9307 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9308 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9309 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9310 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9312 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9313 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9314 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9315 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9317 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9318 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9320 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9321 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9322 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9323 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9324 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9325 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9326 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9327 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9328 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9329 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9331 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9332 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9333 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9334 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9335 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9336 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9337 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9338 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9339 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9340 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9342 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9343 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9344 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9345 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9346 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9347 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9348 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9349 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9350 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9352 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9353 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9354 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9355 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9356 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9357 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9358 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9360 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9361 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9362 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9363 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9364 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9365 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9366 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9367 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9368 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9371 /* DST operations: void foo (void *, const int, const char). */
9373 static const struct builtin_description bdesc_dst[] =
9375 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9376 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9377 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9378 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9386 /* Simple binary operations: VECc = foo (VECa, VECb). */
9388 static struct builtin_description bdesc_2arg[] =
9390 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9391 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9392 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9393 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9394 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9395 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9396 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9397 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9398 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9399 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9400 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9401 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9402 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9403 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9404 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9405 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9406 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9407 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9408 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9409 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9410 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9411 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9412 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9413 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9414 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9415 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9416 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9417 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9418 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9419 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9420 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9421 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9422 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9423 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9424 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9425 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9426 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9427 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9428 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9429 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9430 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9431 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9432 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9433 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9434 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9435 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9436 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9437 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9438 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9439 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9440 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9441 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9442 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9443 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9444 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9445 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9446 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9447 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9448 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9449 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9450 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9451 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9452 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9453 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9454 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9455 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9456 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9457 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9458 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9459 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9460 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9461 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9462 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9463 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9464 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9465 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9466 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9467 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9468 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9469 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9470 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9471 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9472 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9473 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9474 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9475 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9476 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9477 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9478 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9479 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9480 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9481 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9482 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9483 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9484 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9485 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9486 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9487 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9488 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9489 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9490 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9491 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9492 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9493 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9494 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9495 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9496 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9497 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9498 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9499 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9500 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9501 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9502 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9503 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9504 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9505 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9506 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9508 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9509 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9510 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9511 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9512 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9513 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9514 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9515 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9516 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9517 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9518 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9519 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9521 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9522 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9523 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9524 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9525 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9526 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9527 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9528 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9529 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9530 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9531 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9532 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9534 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9535 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9536 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9537 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9538 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9539 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9541 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9542 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9543 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9544 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9545 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9546 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9547 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9548 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9549 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9550 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9551 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9552 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9554 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9555 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9556 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9557 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9558 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9559 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9560 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9561 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9562 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9563 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9564 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9565 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9566 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9567 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9568 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9569 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9570 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9571 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9572 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9573 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9574 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9575 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9576 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9577 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9578 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9579 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9580 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9581 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9582 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9583 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9584 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9585 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9586 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9587 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9588 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9589 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9590 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9591 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9592 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9593 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9594 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9595 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9596 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9597 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9598 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9599 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9600 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9601 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9602 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9603 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9604 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9605 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9606 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9607 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9608 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9609 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9610 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9611 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9612 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9613 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9614 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9615 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9616 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9617 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9618 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9619 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9620 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9621 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9622 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9623 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9624 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9625 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9626 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9627 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9628 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9629 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9630 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9631 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9632 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9633 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9634 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9635 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9636 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9637 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9638 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9639 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9640 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9641 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9642 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9643 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9644 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9645 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9646 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9647 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9648 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9649 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9650 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9651 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9652 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9653 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9654 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9655 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9656 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9657 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9658 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9659 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9660 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9661 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9662 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9663 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9664 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9665 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9666 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9667 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9668 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9669 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9670 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9671 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9672 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9673 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9674 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9675 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9676 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9677 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9678 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9679 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9680 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9681 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9682 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9684 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9685 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9687 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9688 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9689 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9690 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9691 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9692 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9693 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9694 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9695 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9696 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9698 /* Place holder, leave as first spe builtin. */
9699 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9700 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9701 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9702 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9703 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9704 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9705 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9706 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9707 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9708 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9709 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9710 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9711 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9712 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9713 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9714 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9715 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9716 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9717 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9718 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9719 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9720 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9721 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9722 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9723 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9724 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9725 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9726 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9727 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9728 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9729 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9730 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9731 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9732 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9733 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9734 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9735 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9736 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9737 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9738 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9739 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9740 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9741 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9742 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9743 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9744 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9745 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9746 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9747 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9748 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9749 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9750 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9751 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9752 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9753 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9754 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9755 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9756 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9757 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9758 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9759 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9760 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9761 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9762 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9763 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9764 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9765 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9766 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9767 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9768 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9769 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9770 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9771 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9772 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9773 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9774 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9775 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9776 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9777 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9778 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9779 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9780 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9781 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9782 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9783 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9784 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9785 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9786 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9787 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9788 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9789 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9790 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9791 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9792 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9793 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9794 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9795 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9796 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9797 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9798 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9799 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9800 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9801 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9802 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9803 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9804 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9805 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9806 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9807 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9809 /* SPE binary operations expecting a 5-bit unsigned literal. */
9810 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9812 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9813 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9814 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9815 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9816 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9817 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9818 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9819 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9820 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9821 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9822 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9823 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9824 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9825 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9826 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9827 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9828 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9829 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9830 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9831 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9832 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9833 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9834 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9835 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9836 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9837 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9839 /* Place-holder. Leave as last binary SPE builtin. */
9840 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9843 /* AltiVec predicates. */
9845 struct builtin_description_predicates
9847 const unsigned int mask;
9848 const enum insn_code icode;
9849 const char *const name;
9850 const enum rs6000_builtins code;
9853 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9855 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9856 ALTIVEC_BUILTIN_VCMPBFP_P },
9857 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9858 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9859 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9860 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9861 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9862 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9863 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9864 ALTIVEC_BUILTIN_VCMPEQUW_P },
9865 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9866 ALTIVEC_BUILTIN_VCMPGTSW_P },
9867 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9868 ALTIVEC_BUILTIN_VCMPGTUW_P },
9869 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9870 ALTIVEC_BUILTIN_VCMPEQUH_P },
9871 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9872 ALTIVEC_BUILTIN_VCMPGTSH_P },
9873 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9874 ALTIVEC_BUILTIN_VCMPGTUH_P },
9875 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9876 ALTIVEC_BUILTIN_VCMPEQUB_P },
9877 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9878 ALTIVEC_BUILTIN_VCMPGTSB_P },
9879 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9880 ALTIVEC_BUILTIN_VCMPGTUB_P },
9882 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9883 VSX_BUILTIN_XVCMPEQSP_P },
9884 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9885 VSX_BUILTIN_XVCMPGESP_P },
9886 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9887 VSX_BUILTIN_XVCMPGTSP_P },
9888 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9889 VSX_BUILTIN_XVCMPEQDP_P },
9890 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9891 VSX_BUILTIN_XVCMPGEDP_P },
9892 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9893 VSX_BUILTIN_XVCMPGTDP_P },
9895 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9896 ALTIVEC_BUILTIN_VCMPEQ_P },
9897 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9898 ALTIVEC_BUILTIN_VCMPGT_P },
9899 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9900 ALTIVEC_BUILTIN_VCMPGE_P }
9903 /* SPE predicates. */
9904 static struct builtin_description bdesc_spe_predicates[] =
9906 /* Place-holder. Leave as first. */
9907 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9908 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9909 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9910 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9911 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9912 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9913 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9914 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9915 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9916 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9917 /* Place-holder. Leave as last. */
9918 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9921 /* SPE evsel predicates. */
9922 static struct builtin_description bdesc_spe_evsel[] =
9924 /* Place-holder. Leave as first. */
9925 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9926 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9927 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9928 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9929 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9930 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9931 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9932 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9933 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9934 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9935 /* Place-holder. Leave as last. */
9936 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9939 /* PAIRED predicates. */
9940 static const struct builtin_description bdesc_paired_preds[] =
9942 /* Place-holder. Leave as first. */
9943 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9944 /* Place-holder. Leave as last. */
9945 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9948 /* ABS* operations. */
9950 static const struct builtin_description bdesc_abs[] =
9952 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9953 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9954 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9955 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9956 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9957 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9958 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9959 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9960 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9961 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9962 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9965 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9966 foo (VECa). */
9968 static struct builtin_description bdesc_1arg[] =
9970 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9971 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9972 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9973 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9974 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9975 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9976 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9977 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
9978 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9979 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9980 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9981 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9982 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9983 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9984 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9985 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9986 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9987 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9989 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9990 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9991 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
9992 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9993 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9994 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9995 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9997 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9998 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9999 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10000 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10001 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10002 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10003 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10005 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10006 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10007 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10008 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10009 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10010 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10012 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10013 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10014 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10015 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10016 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10017 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10019 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10020 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10021 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10022 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10024 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10025 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10026 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10027 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10028 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10029 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10030 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10031 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10032 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10034 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10035 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10036 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10037 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10038 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10039 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10040 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10041 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10042 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10044 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10045 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10046 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10047 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10048 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10071 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10072 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10073 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10075 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10076 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10077 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10078 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10080 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10081 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10082 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10083 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10084 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10085 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10086 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10087 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10088 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10089 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10090 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10091 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10092 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10093 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10094 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10095 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10096 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10097 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10098 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10099 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10100 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10101 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10102 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10103 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10104 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10105 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10106 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10107 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10108 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10109 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10111 /* Place-holder. Leave as last unary SPE builtin. */
10112 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10114 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10115 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10116 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10117 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10118 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10121 static rtx
10122 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10124 rtx pat;
10125 tree arg0 = CALL_EXPR_ARG (exp, 0);
10126 rtx op0 = expand_normal (arg0);
10127 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10128 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10130 if (icode == CODE_FOR_nothing)
10131 /* Builtin not supported on this processor. */
10132 return 0;
10134 /* If we got invalid arguments bail out before generating bad rtl. */
10135 if (arg0 == error_mark_node)
10136 return const0_rtx;
10138 if (icode == CODE_FOR_altivec_vspltisb
10139 || icode == CODE_FOR_altivec_vspltish
10140 || icode == CODE_FOR_altivec_vspltisw
10141 || icode == CODE_FOR_spe_evsplatfi
10142 || icode == CODE_FOR_spe_evsplati)
10144 /* Only allow 5-bit *signed* literals. */
10145 if (GET_CODE (op0) != CONST_INT
10146 || INTVAL (op0) > 15
10147 || INTVAL (op0) < -16)
10149 error ("argument 1 must be a 5-bit signed literal");
10150 return const0_rtx;
10154 if (target == 0
10155 || GET_MODE (target) != tmode
10156 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10157 target = gen_reg_rtx (tmode);
10159 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10160 op0 = copy_to_mode_reg (mode0, op0);
10162 pat = GEN_FCN (icode) (target, op0);
10163 if (! pat)
10164 return 0;
10165 emit_insn (pat);
10167 return target;
10170 static rtx
10171 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10173 rtx pat, scratch1, scratch2;
10174 tree arg0 = CALL_EXPR_ARG (exp, 0);
10175 rtx op0 = expand_normal (arg0);
10176 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10177 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10179 /* If we have invalid arguments, bail out before generating bad rtl. */
10180 if (arg0 == error_mark_node)
10181 return const0_rtx;
10183 if (target == 0
10184 || GET_MODE (target) != tmode
10185 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10186 target = gen_reg_rtx (tmode);
10188 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10189 op0 = copy_to_mode_reg (mode0, op0);
10191 scratch1 = gen_reg_rtx (mode0);
10192 scratch2 = gen_reg_rtx (mode0);
10194 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10195 if (! pat)
10196 return 0;
10197 emit_insn (pat);
10199 return target;
10202 static rtx
10203 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10205 rtx pat;
10206 tree arg0 = CALL_EXPR_ARG (exp, 0);
10207 tree arg1 = CALL_EXPR_ARG (exp, 1);
10208 rtx op0 = expand_normal (arg0);
10209 rtx op1 = expand_normal (arg1);
10210 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10211 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10212 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10214 if (icode == CODE_FOR_nothing)
10215 /* Builtin not supported on this processor. */
10216 return 0;
10218 /* If we got invalid arguments bail out before generating bad rtl. */
10219 if (arg0 == error_mark_node || arg1 == error_mark_node)
10220 return const0_rtx;
10222 if (icode == CODE_FOR_altivec_vcfux
10223 || icode == CODE_FOR_altivec_vcfsx
10224 || icode == CODE_FOR_altivec_vctsxs
10225 || icode == CODE_FOR_altivec_vctuxs
10226 || icode == CODE_FOR_altivec_vspltb
10227 || icode == CODE_FOR_altivec_vsplth
10228 || icode == CODE_FOR_altivec_vspltw
10229 || icode == CODE_FOR_spe_evaddiw
10230 || icode == CODE_FOR_spe_evldd
10231 || icode == CODE_FOR_spe_evldh
10232 || icode == CODE_FOR_spe_evldw
10233 || icode == CODE_FOR_spe_evlhhesplat
10234 || icode == CODE_FOR_spe_evlhhossplat
10235 || icode == CODE_FOR_spe_evlhhousplat
10236 || icode == CODE_FOR_spe_evlwhe
10237 || icode == CODE_FOR_spe_evlwhos
10238 || icode == CODE_FOR_spe_evlwhou
10239 || icode == CODE_FOR_spe_evlwhsplat
10240 || icode == CODE_FOR_spe_evlwwsplat
10241 || icode == CODE_FOR_spe_evrlwi
10242 || icode == CODE_FOR_spe_evslwi
10243 || icode == CODE_FOR_spe_evsrwis
10244 || icode == CODE_FOR_spe_evsubifw
10245 || icode == CODE_FOR_spe_evsrwiu)
10247 /* Only allow 5-bit unsigned literals. */
10248 STRIP_NOPS (arg1);
10249 if (TREE_CODE (arg1) != INTEGER_CST
10250 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10252 error ("argument 2 must be a 5-bit unsigned literal");
10253 return const0_rtx;
10257 if (target == 0
10258 || GET_MODE (target) != tmode
10259 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10260 target = gen_reg_rtx (tmode);
10262 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10263 op0 = copy_to_mode_reg (mode0, op0);
10264 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10265 op1 = copy_to_mode_reg (mode1, op1);
10267 pat = GEN_FCN (icode) (target, op0, op1);
10268 if (! pat)
10269 return 0;
10270 emit_insn (pat);
10272 return target;
10275 static rtx
10276 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10278 rtx pat, scratch;
10279 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10280 tree arg0 = CALL_EXPR_ARG (exp, 1);
10281 tree arg1 = CALL_EXPR_ARG (exp, 2);
10282 rtx op0 = expand_normal (arg0);
10283 rtx op1 = expand_normal (arg1);
10284 enum machine_mode tmode = SImode;
10285 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10286 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10287 int cr6_form_int;
10289 if (TREE_CODE (cr6_form) != INTEGER_CST)
10291 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10292 return const0_rtx;
10294 else
10295 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10297 gcc_assert (mode0 == mode1);
10299 /* If we have invalid arguments, bail out before generating bad rtl. */
10300 if (arg0 == error_mark_node || arg1 == error_mark_node)
10301 return const0_rtx;
10303 if (target == 0
10304 || GET_MODE (target) != tmode
10305 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10306 target = gen_reg_rtx (tmode);
10308 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10309 op0 = copy_to_mode_reg (mode0, op0);
10310 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10311 op1 = copy_to_mode_reg (mode1, op1);
10313 scratch = gen_reg_rtx (mode0);
10315 pat = GEN_FCN (icode) (scratch, op0, op1);
10316 if (! pat)
10317 return 0;
10318 emit_insn (pat);
10320 /* The vec_any* and vec_all* predicates use the same opcodes for two
10321 different operations, but the bits in CR6 will be different
10322 depending on what information we want. So we have to play tricks
10323 with CR6 to get the right bits out.
10325 If you think this is disgusting, look at the specs for the
10326 AltiVec predicates. */
10328 switch (cr6_form_int)
10330 case 0:
10331 emit_insn (gen_cr6_test_for_zero (target));
10332 break;
10333 case 1:
10334 emit_insn (gen_cr6_test_for_zero_reverse (target));
10335 break;
10336 case 2:
10337 emit_insn (gen_cr6_test_for_lt (target));
10338 break;
10339 case 3:
10340 emit_insn (gen_cr6_test_for_lt_reverse (target));
10341 break;
10342 default:
10343 error ("argument 1 of __builtin_altivec_predicate is out of range");
10344 break;
10347 return target;
10350 static rtx
10351 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10353 rtx pat, addr;
10354 tree arg0 = CALL_EXPR_ARG (exp, 0);
10355 tree arg1 = CALL_EXPR_ARG (exp, 1);
10356 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10357 enum machine_mode mode0 = Pmode;
10358 enum machine_mode mode1 = Pmode;
10359 rtx op0 = expand_normal (arg0);
10360 rtx op1 = expand_normal (arg1);
10362 if (icode == CODE_FOR_nothing)
10363 /* Builtin not supported on this processor. */
10364 return 0;
10366 /* If we got invalid arguments bail out before generating bad rtl. */
10367 if (arg0 == error_mark_node || arg1 == error_mark_node)
10368 return const0_rtx;
10370 if (target == 0
10371 || GET_MODE (target) != tmode
10372 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10373 target = gen_reg_rtx (tmode);
10375 op1 = copy_to_mode_reg (mode1, op1);
10377 if (op0 == const0_rtx)
10379 addr = gen_rtx_MEM (tmode, op1);
10381 else
10383 op0 = copy_to_mode_reg (mode0, op0);
10384 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10387 pat = GEN_FCN (icode) (target, addr);
10389 if (! pat)
10390 return 0;
10391 emit_insn (pat);
10393 return target;
10396 static rtx
10397 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10399 rtx pat, addr;
10400 tree arg0 = CALL_EXPR_ARG (exp, 0);
10401 tree arg1 = CALL_EXPR_ARG (exp, 1);
10402 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10403 enum machine_mode mode0 = Pmode;
10404 enum machine_mode mode1 = Pmode;
10405 rtx op0 = expand_normal (arg0);
10406 rtx op1 = expand_normal (arg1);
10408 if (icode == CODE_FOR_nothing)
10409 /* Builtin not supported on this processor. */
10410 return 0;
10412 /* If we got invalid arguments bail out before generating bad rtl. */
10413 if (arg0 == error_mark_node || arg1 == error_mark_node)
10414 return const0_rtx;
10416 if (target == 0
10417 || GET_MODE (target) != tmode
10418 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10419 target = gen_reg_rtx (tmode);
10421 op1 = copy_to_mode_reg (mode1, op1);
10423 if (op0 == const0_rtx)
10425 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10427 else
10429 op0 = copy_to_mode_reg (mode0, op0);
10430 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10433 pat = GEN_FCN (icode) (target, addr);
10435 if (! pat)
10436 return 0;
10437 emit_insn (pat);
10439 return target;
10442 static rtx
10443 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10445 tree arg0 = CALL_EXPR_ARG (exp, 0);
10446 tree arg1 = CALL_EXPR_ARG (exp, 1);
10447 tree arg2 = CALL_EXPR_ARG (exp, 2);
10448 rtx op0 = expand_normal (arg0);
10449 rtx op1 = expand_normal (arg1);
10450 rtx op2 = expand_normal (arg2);
10451 rtx pat;
10452 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10453 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10454 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10456 /* Invalid arguments. Bail before doing anything stoopid! */
10457 if (arg0 == error_mark_node
10458 || arg1 == error_mark_node
10459 || arg2 == error_mark_node)
10460 return const0_rtx;
10462 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10463 op0 = copy_to_mode_reg (mode2, op0);
10464 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10465 op1 = copy_to_mode_reg (mode0, op1);
10466 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10467 op2 = copy_to_mode_reg (mode1, op2);
10469 pat = GEN_FCN (icode) (op1, op2, op0);
10470 if (pat)
10471 emit_insn (pat);
10472 return NULL_RTX;
10475 static rtx
10476 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10478 tree arg0 = CALL_EXPR_ARG (exp, 0);
10479 tree arg1 = CALL_EXPR_ARG (exp, 1);
10480 tree arg2 = CALL_EXPR_ARG (exp, 2);
10481 rtx op0 = expand_normal (arg0);
10482 rtx op1 = expand_normal (arg1);
10483 rtx op2 = expand_normal (arg2);
10484 rtx pat, addr;
10485 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10486 enum machine_mode mode1 = Pmode;
10487 enum machine_mode mode2 = Pmode;
10489 /* Invalid arguments. Bail before doing anything stoopid! */
10490 if (arg0 == error_mark_node
10491 || arg1 == error_mark_node
10492 || arg2 == error_mark_node)
10493 return const0_rtx;
10495 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10496 op0 = copy_to_mode_reg (tmode, op0);
10498 op2 = copy_to_mode_reg (mode2, op2);
10500 if (op1 == const0_rtx)
10502 addr = gen_rtx_MEM (tmode, op2);
10504 else
10506 op1 = copy_to_mode_reg (mode1, op1);
10507 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10510 pat = GEN_FCN (icode) (addr, op0);
10511 if (pat)
10512 emit_insn (pat);
10513 return NULL_RTX;
10516 static rtx
10517 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10519 tree arg0 = CALL_EXPR_ARG (exp, 0);
10520 tree arg1 = CALL_EXPR_ARG (exp, 1);
10521 tree arg2 = CALL_EXPR_ARG (exp, 2);
10522 rtx op0 = expand_normal (arg0);
10523 rtx op1 = expand_normal (arg1);
10524 rtx op2 = expand_normal (arg2);
10525 rtx pat, addr;
10526 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10527 enum machine_mode mode1 = Pmode;
10528 enum machine_mode mode2 = Pmode;
10530 /* Invalid arguments. Bail before doing anything stoopid! */
10531 if (arg0 == error_mark_node
10532 || arg1 == error_mark_node
10533 || arg2 == error_mark_node)
10534 return const0_rtx;
10536 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10537 op0 = copy_to_mode_reg (tmode, op0);
10539 op2 = copy_to_mode_reg (mode2, op2);
10541 if (op1 == const0_rtx)
10543 addr = gen_rtx_MEM (tmode, op2);
10545 else
10547 op1 = copy_to_mode_reg (mode1, op1);
10548 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10551 pat = GEN_FCN (icode) (addr, op0);
10552 if (pat)
10553 emit_insn (pat);
10554 return NULL_RTX;
10557 static rtx
10558 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10560 rtx pat;
10561 tree arg0 = CALL_EXPR_ARG (exp, 0);
10562 tree arg1 = CALL_EXPR_ARG (exp, 1);
10563 tree arg2 = CALL_EXPR_ARG (exp, 2);
10564 rtx op0 = expand_normal (arg0);
10565 rtx op1 = expand_normal (arg1);
10566 rtx op2 = expand_normal (arg2);
10567 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10568 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10569 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10570 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10572 if (icode == CODE_FOR_nothing)
10573 /* Builtin not supported on this processor. */
10574 return 0;
10576 /* If we got invalid arguments bail out before generating bad rtl. */
10577 if (arg0 == error_mark_node
10578 || arg1 == error_mark_node
10579 || arg2 == error_mark_node)
10580 return const0_rtx;
10582 switch (icode)
10584 case CODE_FOR_altivec_vsldoi_v4sf:
10585 case CODE_FOR_altivec_vsldoi_v4si:
10586 case CODE_FOR_altivec_vsldoi_v8hi:
10587 case CODE_FOR_altivec_vsldoi_v16qi:
10588 /* Only allow 4-bit unsigned literals. */
10589 STRIP_NOPS (arg2);
10590 if (TREE_CODE (arg2) != INTEGER_CST
10591 || TREE_INT_CST_LOW (arg2) & ~0xf)
10593 error ("argument 3 must be a 4-bit unsigned literal");
10594 return const0_rtx;
10596 break;
10598 case CODE_FOR_vsx_xxpermdi_v2df:
10599 case CODE_FOR_vsx_xxpermdi_v2di:
10600 case CODE_FOR_vsx_xxsldwi_v16qi:
10601 case CODE_FOR_vsx_xxsldwi_v8hi:
10602 case CODE_FOR_vsx_xxsldwi_v4si:
10603 case CODE_FOR_vsx_xxsldwi_v4sf:
10604 case CODE_FOR_vsx_xxsldwi_v2di:
10605 case CODE_FOR_vsx_xxsldwi_v2df:
10606 /* Only allow 2-bit unsigned literals. */
10607 STRIP_NOPS (arg2);
10608 if (TREE_CODE (arg2) != INTEGER_CST
10609 || TREE_INT_CST_LOW (arg2) & ~0x3)
10611 error ("argument 3 must be a 2-bit unsigned literal");
10612 return const0_rtx;
10614 break;
10616 case CODE_FOR_vsx_set_v2df:
10617 case CODE_FOR_vsx_set_v2di:
10618 /* Only allow 1-bit unsigned literals. */
10619 STRIP_NOPS (arg2);
10620 if (TREE_CODE (arg2) != INTEGER_CST
10621 || TREE_INT_CST_LOW (arg2) & ~0x1)
10623 error ("argument 3 must be a 1-bit unsigned literal");
10624 return const0_rtx;
10626 break;
10628 default:
10629 break;
10632 if (target == 0
10633 || GET_MODE (target) != tmode
10634 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10635 target = gen_reg_rtx (tmode);
10637 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10638 op0 = copy_to_mode_reg (mode0, op0);
10639 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10640 op1 = copy_to_mode_reg (mode1, op1);
10641 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10642 op2 = copy_to_mode_reg (mode2, op2);
10644 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10645 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10646 else
10647 pat = GEN_FCN (icode) (target, op0, op1, op2);
10648 if (! pat)
10649 return 0;
10650 emit_insn (pat);
10652 return target;
10655 /* Expand the lvx builtins. */
10656 static rtx
10657 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10659 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10660 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10661 tree arg0;
10662 enum machine_mode tmode, mode0;
10663 rtx pat, op0;
10664 enum insn_code icode;
10666 switch (fcode)
10668 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10669 icode = CODE_FOR_vector_load_v16qi;
10670 break;
10671 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10672 icode = CODE_FOR_vector_load_v8hi;
10673 break;
10674 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10675 icode = CODE_FOR_vector_load_v4si;
10676 break;
10677 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10678 icode = CODE_FOR_vector_load_v4sf;
10679 break;
10680 default:
10681 *expandedp = false;
10682 return NULL_RTX;
10685 *expandedp = true;
10687 arg0 = CALL_EXPR_ARG (exp, 0);
10688 op0 = expand_normal (arg0);
10689 tmode = insn_data[icode].operand[0].mode;
10690 mode0 = insn_data[icode].operand[1].mode;
10692 if (target == 0
10693 || GET_MODE (target) != tmode
10694 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10695 target = gen_reg_rtx (tmode);
10697 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10698 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10700 pat = GEN_FCN (icode) (target, op0);
10701 if (! pat)
10702 return 0;
10703 emit_insn (pat);
10704 return target;
10707 /* Expand the stvx builtins. */
10708 static rtx
10709 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10710 bool *expandedp)
10712 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10713 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10714 tree arg0, arg1;
10715 enum machine_mode mode0, mode1;
10716 rtx pat, op0, op1;
10717 enum insn_code icode;
10719 switch (fcode)
10721 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10722 icode = CODE_FOR_vector_store_v16qi;
10723 break;
10724 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10725 icode = CODE_FOR_vector_store_v8hi;
10726 break;
10727 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10728 icode = CODE_FOR_vector_store_v4si;
10729 break;
10730 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10731 icode = CODE_FOR_vector_store_v4sf;
10732 break;
10733 default:
10734 *expandedp = false;
10735 return NULL_RTX;
10738 arg0 = CALL_EXPR_ARG (exp, 0);
10739 arg1 = CALL_EXPR_ARG (exp, 1);
10740 op0 = expand_normal (arg0);
10741 op1 = expand_normal (arg1);
10742 mode0 = insn_data[icode].operand[0].mode;
10743 mode1 = insn_data[icode].operand[1].mode;
10745 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10746 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10747 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10748 op1 = copy_to_mode_reg (mode1, op1);
10750 pat = GEN_FCN (icode) (op0, op1);
10751 if (pat)
10752 emit_insn (pat);
10754 *expandedp = true;
10755 return NULL_RTX;
10758 /* Expand the dst builtins. */
10759 static rtx
10760 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10761 bool *expandedp)
10763 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10764 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10765 tree arg0, arg1, arg2;
10766 enum machine_mode mode0, mode1;
10767 rtx pat, op0, op1, op2;
10768 const struct builtin_description *d;
10769 size_t i;
10771 *expandedp = false;
10773 /* Handle DST variants. */
10774 d = bdesc_dst;
10775 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10776 if (d->code == fcode)
10778 arg0 = CALL_EXPR_ARG (exp, 0);
10779 arg1 = CALL_EXPR_ARG (exp, 1);
10780 arg2 = CALL_EXPR_ARG (exp, 2);
10781 op0 = expand_normal (arg0);
10782 op1 = expand_normal (arg1);
10783 op2 = expand_normal (arg2);
10784 mode0 = insn_data[d->icode].operand[0].mode;
10785 mode1 = insn_data[d->icode].operand[1].mode;
10787 /* Invalid arguments, bail out before generating bad rtl. */
10788 if (arg0 == error_mark_node
10789 || arg1 == error_mark_node
10790 || arg2 == error_mark_node)
10791 return const0_rtx;
10793 *expandedp = true;
10794 STRIP_NOPS (arg2);
10795 if (TREE_CODE (arg2) != INTEGER_CST
10796 || TREE_INT_CST_LOW (arg2) & ~0x3)
10798 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10799 return const0_rtx;
10802 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10803 op0 = copy_to_mode_reg (Pmode, op0);
10804 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10805 op1 = copy_to_mode_reg (mode1, op1);
10807 pat = GEN_FCN (d->icode) (op0, op1, op2);
10808 if (pat != 0)
10809 emit_insn (pat);
10811 return NULL_RTX;
10814 return NULL_RTX;
10817 /* Expand vec_init builtin. */
10818 static rtx
10819 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10821 enum machine_mode tmode = TYPE_MODE (type);
10822 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10823 int i, n_elt = GET_MODE_NUNITS (tmode);
10824 rtvec v = rtvec_alloc (n_elt);
10826 gcc_assert (VECTOR_MODE_P (tmode));
10827 gcc_assert (n_elt == call_expr_nargs (exp));
10829 for (i = 0; i < n_elt; ++i)
10831 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10832 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10835 if (!target || !register_operand (target, tmode))
10836 target = gen_reg_rtx (tmode);
10838 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10839 return target;
10842 /* Return the integer constant in ARG. Constrain it to be in the range
10843 of the subparts of VEC_TYPE; issue an error if not. */
10845 static int
10846 get_element_number (tree vec_type, tree arg)
10848 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10850 if (!host_integerp (arg, 1)
10851 || (elt = tree_low_cst (arg, 1), elt > max))
10853 error ("selector must be an integer constant in the range 0..%wi", max);
10854 return 0;
10857 return elt;
10860 /* Expand vec_set builtin. */
10861 static rtx
10862 altivec_expand_vec_set_builtin (tree exp)
10864 enum machine_mode tmode, mode1;
10865 tree arg0, arg1, arg2;
10866 int elt;
10867 rtx op0, op1;
10869 arg0 = CALL_EXPR_ARG (exp, 0);
10870 arg1 = CALL_EXPR_ARG (exp, 1);
10871 arg2 = CALL_EXPR_ARG (exp, 2);
10873 tmode = TYPE_MODE (TREE_TYPE (arg0));
10874 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10875 gcc_assert (VECTOR_MODE_P (tmode));
10877 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10878 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10879 elt = get_element_number (TREE_TYPE (arg0), arg2);
10881 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10882 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10884 op0 = force_reg (tmode, op0);
10885 op1 = force_reg (mode1, op1);
10887 rs6000_expand_vector_set (op0, op1, elt);
10889 return op0;
10892 /* Expand vec_ext builtin. */
10893 static rtx
10894 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10896 enum machine_mode tmode, mode0;
10897 tree arg0, arg1;
10898 int elt;
10899 rtx op0;
10901 arg0 = CALL_EXPR_ARG (exp, 0);
10902 arg1 = CALL_EXPR_ARG (exp, 1);
10904 op0 = expand_normal (arg0);
10905 elt = get_element_number (TREE_TYPE (arg0), arg1);
10907 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10908 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10909 gcc_assert (VECTOR_MODE_P (mode0));
10911 op0 = force_reg (mode0, op0);
10913 if (optimize || !target || !register_operand (target, tmode))
10914 target = gen_reg_rtx (tmode);
10916 rs6000_expand_vector_extract (target, op0, elt);
10918 return target;
10921 /* Expand the builtin in EXP and store the result in TARGET. Store
10922 true in *EXPANDEDP if we found a builtin to expand. */
10923 static rtx
10924 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10926 const struct builtin_description *d;
10927 const struct builtin_description_predicates *dp;
10928 size_t i;
10929 enum insn_code icode;
10930 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10931 tree arg0;
10932 rtx op0, pat;
10933 enum machine_mode tmode, mode0;
10934 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10936 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10937 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10938 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10939 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10941 *expandedp = true;
10942 error ("unresolved overload for Altivec builtin %qF", fndecl);
10943 return const0_rtx;
10946 target = altivec_expand_ld_builtin (exp, target, expandedp);
10947 if (*expandedp)
10948 return target;
10950 target = altivec_expand_st_builtin (exp, target, expandedp);
10951 if (*expandedp)
10952 return target;
10954 target = altivec_expand_dst_builtin (exp, target, expandedp);
10955 if (*expandedp)
10956 return target;
10958 *expandedp = true;
10960 switch (fcode)
10962 case ALTIVEC_BUILTIN_STVX:
10963 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10964 case ALTIVEC_BUILTIN_STVEBX:
10965 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10966 case ALTIVEC_BUILTIN_STVEHX:
10967 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10968 case ALTIVEC_BUILTIN_STVEWX:
10969 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10970 case ALTIVEC_BUILTIN_STVXL:
10971 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10973 case ALTIVEC_BUILTIN_STVLX:
10974 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10975 case ALTIVEC_BUILTIN_STVLXL:
10976 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10977 case ALTIVEC_BUILTIN_STVRX:
10978 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10979 case ALTIVEC_BUILTIN_STVRXL:
10980 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10982 case ALTIVEC_BUILTIN_MFVSCR:
10983 icode = CODE_FOR_altivec_mfvscr;
10984 tmode = insn_data[icode].operand[0].mode;
10986 if (target == 0
10987 || GET_MODE (target) != tmode
10988 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10989 target = gen_reg_rtx (tmode);
10991 pat = GEN_FCN (icode) (target);
10992 if (! pat)
10993 return 0;
10994 emit_insn (pat);
10995 return target;
10997 case ALTIVEC_BUILTIN_MTVSCR:
10998 icode = CODE_FOR_altivec_mtvscr;
10999 arg0 = CALL_EXPR_ARG (exp, 0);
11000 op0 = expand_normal (arg0);
11001 mode0 = insn_data[icode].operand[0].mode;
11003 /* If we got invalid arguments bail out before generating bad rtl. */
11004 if (arg0 == error_mark_node)
11005 return const0_rtx;
11007 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11008 op0 = copy_to_mode_reg (mode0, op0);
11010 pat = GEN_FCN (icode) (op0);
11011 if (pat)
11012 emit_insn (pat);
11013 return NULL_RTX;
11015 case ALTIVEC_BUILTIN_DSSALL:
11016 emit_insn (gen_altivec_dssall ());
11017 return NULL_RTX;
11019 case ALTIVEC_BUILTIN_DSS:
11020 icode = CODE_FOR_altivec_dss;
11021 arg0 = CALL_EXPR_ARG (exp, 0);
11022 STRIP_NOPS (arg0);
11023 op0 = expand_normal (arg0);
11024 mode0 = insn_data[icode].operand[0].mode;
11026 /* If we got invalid arguments bail out before generating bad rtl. */
11027 if (arg0 == error_mark_node)
11028 return const0_rtx;
11030 if (TREE_CODE (arg0) != INTEGER_CST
11031 || TREE_INT_CST_LOW (arg0) & ~0x3)
11033 error ("argument to dss must be a 2-bit unsigned literal");
11034 return const0_rtx;
11037 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11038 op0 = copy_to_mode_reg (mode0, op0);
11040 emit_insn (gen_altivec_dss (op0));
11041 return NULL_RTX;
11043 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11044 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11045 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11046 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11047 case VSX_BUILTIN_VEC_INIT_V2DF:
11048 case VSX_BUILTIN_VEC_INIT_V2DI:
11049 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11051 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11052 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11053 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11054 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11055 case VSX_BUILTIN_VEC_SET_V2DF:
11056 case VSX_BUILTIN_VEC_SET_V2DI:
11057 return altivec_expand_vec_set_builtin (exp);
11059 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11060 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11061 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11062 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11063 case VSX_BUILTIN_VEC_EXT_V2DF:
11064 case VSX_BUILTIN_VEC_EXT_V2DI:
11065 return altivec_expand_vec_ext_builtin (exp, target);
11067 default:
11068 break;
11069 /* Fall through. */
11072 /* Expand abs* operations. */
11073 d = bdesc_abs;
11074 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11075 if (d->code == fcode)
11076 return altivec_expand_abs_builtin (d->icode, exp, target);
11078 /* Expand the AltiVec predicates. */
11079 dp = bdesc_altivec_preds;
11080 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11081 if (dp->code == fcode)
11082 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11084 /* LV* are funky. We initialized them differently. */
11085 switch (fcode)
11087 case ALTIVEC_BUILTIN_LVSL:
11088 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11089 exp, target, false);
11090 case ALTIVEC_BUILTIN_LVSR:
11091 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11092 exp, target, false);
11093 case ALTIVEC_BUILTIN_LVEBX:
11094 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11095 exp, target, false);
11096 case ALTIVEC_BUILTIN_LVEHX:
11097 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11098 exp, target, false);
11099 case ALTIVEC_BUILTIN_LVEWX:
11100 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11101 exp, target, false);
11102 case ALTIVEC_BUILTIN_LVXL:
11103 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11104 exp, target, false);
11105 case ALTIVEC_BUILTIN_LVX:
11106 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11107 exp, target, false);
11108 case ALTIVEC_BUILTIN_LVLX:
11109 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11110 exp, target, true);
11111 case ALTIVEC_BUILTIN_LVLXL:
11112 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11113 exp, target, true);
11114 case ALTIVEC_BUILTIN_LVRX:
11115 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11116 exp, target, true);
11117 case ALTIVEC_BUILTIN_LVRXL:
11118 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11119 exp, target, true);
11120 default:
11121 break;
11122 /* Fall through. */
11125 *expandedp = false;
11126 return NULL_RTX;
11129 /* Expand the builtin in EXP and store the result in TARGET. Store
11130 true in *EXPANDEDP if we found a builtin to expand. */
11131 static rtx
11132 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11134 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11135 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11136 const struct builtin_description *d;
11137 size_t i;
11139 *expandedp = true;
11141 switch (fcode)
11143 case PAIRED_BUILTIN_STX:
11144 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11145 case PAIRED_BUILTIN_LX:
11146 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11147 default:
11148 break;
11149 /* Fall through. */
11152 /* Expand the paired predicates. */
11153 d = bdesc_paired_preds;
11154 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11155 if (d->code == fcode)
11156 return paired_expand_predicate_builtin (d->icode, exp, target);
11158 *expandedp = false;
11159 return NULL_RTX;
11162 /* Binops that need to be initialized manually, but can be expanded
11163 automagically by rs6000_expand_binop_builtin. */
11164 static struct builtin_description bdesc_2arg_spe[] =
11166 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11167 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11168 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11169 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11170 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11171 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11172 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11173 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11174 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11175 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11176 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11177 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11178 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11179 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11180 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11181 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11182 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11183 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11184 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11185 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11186 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11187 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11190 /* Expand the builtin in EXP and store the result in TARGET. Store
11191 true in *EXPANDEDP if we found a builtin to expand.
11193 This expands the SPE builtins that are not simple unary and binary
11194 operations. */
11195 static rtx
11196 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11198 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11199 tree arg1, arg0;
11200 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11201 enum insn_code icode;
11202 enum machine_mode tmode, mode0;
11203 rtx pat, op0;
11204 struct builtin_description *d;
11205 size_t i;
11207 *expandedp = true;
11209 /* Syntax check for a 5-bit unsigned immediate. */
11210 switch (fcode)
11212 case SPE_BUILTIN_EVSTDD:
11213 case SPE_BUILTIN_EVSTDH:
11214 case SPE_BUILTIN_EVSTDW:
11215 case SPE_BUILTIN_EVSTWHE:
11216 case SPE_BUILTIN_EVSTWHO:
11217 case SPE_BUILTIN_EVSTWWE:
11218 case SPE_BUILTIN_EVSTWWO:
11219 arg1 = CALL_EXPR_ARG (exp, 2);
11220 if (TREE_CODE (arg1) != INTEGER_CST
11221 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11223 error ("argument 2 must be a 5-bit unsigned literal");
11224 return const0_rtx;
11226 break;
11227 default:
11228 break;
11231 /* The evsplat*i instructions are not quite generic. */
11232 switch (fcode)
11234 case SPE_BUILTIN_EVSPLATFI:
11235 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11236 exp, target);
11237 case SPE_BUILTIN_EVSPLATI:
11238 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11239 exp, target);
11240 default:
11241 break;
11244 d = (struct builtin_description *) bdesc_2arg_spe;
11245 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11246 if (d->code == fcode)
11247 return rs6000_expand_binop_builtin (d->icode, exp, target);
11249 d = (struct builtin_description *) bdesc_spe_predicates;
11250 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11251 if (d->code == fcode)
11252 return spe_expand_predicate_builtin (d->icode, exp, target);
11254 d = (struct builtin_description *) bdesc_spe_evsel;
11255 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11256 if (d->code == fcode)
11257 return spe_expand_evsel_builtin (d->icode, exp, target);
11259 switch (fcode)
11261 case SPE_BUILTIN_EVSTDDX:
11262 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11263 case SPE_BUILTIN_EVSTDHX:
11264 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11265 case SPE_BUILTIN_EVSTDWX:
11266 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11267 case SPE_BUILTIN_EVSTWHEX:
11268 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11269 case SPE_BUILTIN_EVSTWHOX:
11270 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11271 case SPE_BUILTIN_EVSTWWEX:
11272 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11273 case SPE_BUILTIN_EVSTWWOX:
11274 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11275 case SPE_BUILTIN_EVSTDD:
11276 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11277 case SPE_BUILTIN_EVSTDH:
11278 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11279 case SPE_BUILTIN_EVSTDW:
11280 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11281 case SPE_BUILTIN_EVSTWHE:
11282 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11283 case SPE_BUILTIN_EVSTWHO:
11284 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11285 case SPE_BUILTIN_EVSTWWE:
11286 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11287 case SPE_BUILTIN_EVSTWWO:
11288 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11289 case SPE_BUILTIN_MFSPEFSCR:
11290 icode = CODE_FOR_spe_mfspefscr;
11291 tmode = insn_data[icode].operand[0].mode;
11293 if (target == 0
11294 || GET_MODE (target) != tmode
11295 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11296 target = gen_reg_rtx (tmode);
11298 pat = GEN_FCN (icode) (target);
11299 if (! pat)
11300 return 0;
11301 emit_insn (pat);
11302 return target;
11303 case SPE_BUILTIN_MTSPEFSCR:
11304 icode = CODE_FOR_spe_mtspefscr;
11305 arg0 = CALL_EXPR_ARG (exp, 0);
11306 op0 = expand_normal (arg0);
11307 mode0 = insn_data[icode].operand[0].mode;
11309 if (arg0 == error_mark_node)
11310 return const0_rtx;
11312 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11313 op0 = copy_to_mode_reg (mode0, op0);
11315 pat = GEN_FCN (icode) (op0);
11316 if (pat)
11317 emit_insn (pat);
11318 return NULL_RTX;
11319 default:
11320 break;
11323 *expandedp = false;
11324 return NULL_RTX;
11327 static rtx
11328 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11330 rtx pat, scratch, tmp;
11331 tree form = CALL_EXPR_ARG (exp, 0);
11332 tree arg0 = CALL_EXPR_ARG (exp, 1);
11333 tree arg1 = CALL_EXPR_ARG (exp, 2);
11334 rtx op0 = expand_normal (arg0);
11335 rtx op1 = expand_normal (arg1);
11336 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11337 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11338 int form_int;
11339 enum rtx_code code;
11341 if (TREE_CODE (form) != INTEGER_CST)
11343 error ("argument 1 of __builtin_paired_predicate must be a constant");
11344 return const0_rtx;
11346 else
11347 form_int = TREE_INT_CST_LOW (form);
11349 gcc_assert (mode0 == mode1);
11351 if (arg0 == error_mark_node || arg1 == error_mark_node)
11352 return const0_rtx;
11354 if (target == 0
11355 || GET_MODE (target) != SImode
11356 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11357 target = gen_reg_rtx (SImode);
11358 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11359 op0 = copy_to_mode_reg (mode0, op0);
11360 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11361 op1 = copy_to_mode_reg (mode1, op1);
11363 scratch = gen_reg_rtx (CCFPmode);
11365 pat = GEN_FCN (icode) (scratch, op0, op1);
11366 if (!pat)
11367 return const0_rtx;
11369 emit_insn (pat);
11371 switch (form_int)
11373 /* LT bit. */
11374 case 0:
11375 code = LT;
11376 break;
11377 /* GT bit. */
11378 case 1:
11379 code = GT;
11380 break;
11381 /* EQ bit. */
11382 case 2:
11383 code = EQ;
11384 break;
11385 /* UN bit. */
11386 case 3:
11387 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11388 return target;
11389 default:
11390 error ("argument 1 of __builtin_paired_predicate is out of range");
11391 return const0_rtx;
11394 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11395 emit_move_insn (target, tmp);
11396 return target;
11399 static rtx
11400 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11402 rtx pat, scratch, tmp;
11403 tree form = CALL_EXPR_ARG (exp, 0);
11404 tree arg0 = CALL_EXPR_ARG (exp, 1);
11405 tree arg1 = CALL_EXPR_ARG (exp, 2);
11406 rtx op0 = expand_normal (arg0);
11407 rtx op1 = expand_normal (arg1);
11408 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11409 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11410 int form_int;
11411 enum rtx_code code;
11413 if (TREE_CODE (form) != INTEGER_CST)
11415 error ("argument 1 of __builtin_spe_predicate must be a constant");
11416 return const0_rtx;
11418 else
11419 form_int = TREE_INT_CST_LOW (form);
11421 gcc_assert (mode0 == mode1);
11423 if (arg0 == error_mark_node || arg1 == error_mark_node)
11424 return const0_rtx;
11426 if (target == 0
11427 || GET_MODE (target) != SImode
11428 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11429 target = gen_reg_rtx (SImode);
11431 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11432 op0 = copy_to_mode_reg (mode0, op0);
11433 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11434 op1 = copy_to_mode_reg (mode1, op1);
11436 scratch = gen_reg_rtx (CCmode);
11438 pat = GEN_FCN (icode) (scratch, op0, op1);
11439 if (! pat)
11440 return const0_rtx;
11441 emit_insn (pat);
11443 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11444 _lower_. We use one compare, but look in different bits of the
11445 CR for each variant.
11447 There are 2 elements in each SPE simd type (upper/lower). The CR
11448 bits are set as follows:
11450 BIT0 | BIT 1 | BIT 2 | BIT 3
11451 U | L | (U | L) | (U & L)
11453 So, for an "all" relationship, BIT 3 would be set.
11454 For an "any" relationship, BIT 2 would be set. Etc.
11456 Following traditional nomenclature, these bits map to:
11458 BIT0 | BIT 1 | BIT 2 | BIT 3
11459 LT | GT | EQ | OV
11461 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11464 switch (form_int)
11466 /* All variant. OV bit. */
11467 case 0:
11468 /* We need to get to the OV bit, which is the ORDERED bit. We
11469 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11470 that's ugly and will make validate_condition_mode die.
11471 So let's just use another pattern. */
11472 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11473 return target;
11474 /* Any variant. EQ bit. */
11475 case 1:
11476 code = EQ;
11477 break;
11478 /* Upper variant. LT bit. */
11479 case 2:
11480 code = LT;
11481 break;
11482 /* Lower variant. GT bit. */
11483 case 3:
11484 code = GT;
11485 break;
11486 default:
11487 error ("argument 1 of __builtin_spe_predicate is out of range");
11488 return const0_rtx;
11491 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11492 emit_move_insn (target, tmp);
11494 return target;
11497 /* The evsel builtins look like this:
11499 e = __builtin_spe_evsel_OP (a, b, c, d);
11501 and work like this:
11503 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11504 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11507 static rtx
11508 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11510 rtx pat, scratch;
11511 tree arg0 = CALL_EXPR_ARG (exp, 0);
11512 tree arg1 = CALL_EXPR_ARG (exp, 1);
11513 tree arg2 = CALL_EXPR_ARG (exp, 2);
11514 tree arg3 = CALL_EXPR_ARG (exp, 3);
11515 rtx op0 = expand_normal (arg0);
11516 rtx op1 = expand_normal (arg1);
11517 rtx op2 = expand_normal (arg2);
11518 rtx op3 = expand_normal (arg3);
11519 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11520 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11522 gcc_assert (mode0 == mode1);
11524 if (arg0 == error_mark_node || arg1 == error_mark_node
11525 || arg2 == error_mark_node || arg3 == error_mark_node)
11526 return const0_rtx;
11528 if (target == 0
11529 || GET_MODE (target) != mode0
11530 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11531 target = gen_reg_rtx (mode0);
11533 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11534 op0 = copy_to_mode_reg (mode0, op0);
11535 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11536 op1 = copy_to_mode_reg (mode0, op1);
11537 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11538 op2 = copy_to_mode_reg (mode0, op2);
11539 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11540 op3 = copy_to_mode_reg (mode0, op3);
11542 /* Generate the compare. */
11543 scratch = gen_reg_rtx (CCmode);
11544 pat = GEN_FCN (icode) (scratch, op0, op1);
11545 if (! pat)
11546 return const0_rtx;
11547 emit_insn (pat);
11549 if (mode0 == V2SImode)
11550 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11551 else
11552 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11554 return target;
11557 /* Expand an expression EXP that calls a built-in function,
11558 with result going to TARGET if that's convenient
11559 (and in mode MODE if that's convenient).
11560 SUBTARGET may be used as the target for computing one of EXP's operands.
11561 IGNORE is nonzero if the value is to be ignored. */
11563 static rtx
11564 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11565 enum machine_mode mode ATTRIBUTE_UNUSED,
11566 int ignore ATTRIBUTE_UNUSED)
11568 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11569 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11570 const struct builtin_description *d;
11571 size_t i;
11572 rtx ret;
11573 bool success;
11575 switch (fcode)
11577 case RS6000_BUILTIN_RECIP:
11578 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11580 case RS6000_BUILTIN_RECIPF:
11581 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11583 case RS6000_BUILTIN_RSQRTF:
11584 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11586 case RS6000_BUILTIN_RSQRT:
11587 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11589 case RS6000_BUILTIN_BSWAP_HI:
11590 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11592 case POWER7_BUILTIN_BPERMD:
11593 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11594 ? CODE_FOR_bpermd_di
11595 : CODE_FOR_bpermd_si), exp, target);
11597 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11598 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11600 int icode = (int) CODE_FOR_altivec_lvsr;
11601 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11602 enum machine_mode mode = insn_data[icode].operand[1].mode;
11603 tree arg;
11604 rtx op, addr, pat;
11606 gcc_assert (TARGET_ALTIVEC);
11608 arg = CALL_EXPR_ARG (exp, 0);
11609 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11610 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11611 addr = memory_address (mode, op);
11612 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11613 op = addr;
11614 else
11616 /* For the load case need to negate the address. */
11617 op = gen_reg_rtx (GET_MODE (addr));
11618 emit_insn (gen_rtx_SET (VOIDmode, op,
11619 gen_rtx_NEG (GET_MODE (addr), addr)));
11621 op = gen_rtx_MEM (mode, op);
11623 if (target == 0
11624 || GET_MODE (target) != tmode
11625 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11626 target = gen_reg_rtx (tmode);
11628 /*pat = gen_altivec_lvsr (target, op);*/
11629 pat = GEN_FCN (icode) (target, op);
11630 if (!pat)
11631 return 0;
11632 emit_insn (pat);
11634 return target;
11637 case ALTIVEC_BUILTIN_VCFUX:
11638 case ALTIVEC_BUILTIN_VCFSX:
11639 case ALTIVEC_BUILTIN_VCTUXS:
11640 case ALTIVEC_BUILTIN_VCTSXS:
11641 /* FIXME: There's got to be a nicer way to handle this case than
11642 constructing a new CALL_EXPR. */
11643 if (call_expr_nargs (exp) == 1)
11645 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11646 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11648 break;
11650 default:
11651 break;
11654 if (TARGET_ALTIVEC)
11656 ret = altivec_expand_builtin (exp, target, &success);
11658 if (success)
11659 return ret;
11661 if (TARGET_SPE)
11663 ret = spe_expand_builtin (exp, target, &success);
11665 if (success)
11666 return ret;
11668 if (TARGET_PAIRED_FLOAT)
11670 ret = paired_expand_builtin (exp, target, &success);
11672 if (success)
11673 return ret;
11676 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11678 /* Handle simple unary operations. */
11679 d = (struct builtin_description *) bdesc_1arg;
11680 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11681 if (d->code == fcode)
11682 return rs6000_expand_unop_builtin (d->icode, exp, target);
11684 /* Handle simple binary operations. */
11685 d = (struct builtin_description *) bdesc_2arg;
11686 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11687 if (d->code == fcode)
11688 return rs6000_expand_binop_builtin (d->icode, exp, target);
11690 /* Handle simple ternary operations. */
11691 d = bdesc_3arg;
11692 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11693 if (d->code == fcode)
11694 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11696 gcc_unreachable ();
11699 static void
11700 rs6000_init_builtins (void)
11702 tree tdecl;
11703 tree ftype;
11705 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11706 V2SF_type_node = build_vector_type (float_type_node, 2);
11707 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11708 V2DF_type_node = build_vector_type (double_type_node, 2);
11709 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11710 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11711 V4SF_type_node = build_vector_type (float_type_node, 4);
11712 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11713 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11715 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11716 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11717 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11718 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11720 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11721 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11722 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11723 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11725 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11726 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11727 'vector unsigned short'. */
11729 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11730 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11731 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11732 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11733 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11735 long_integer_type_internal_node = long_integer_type_node;
11736 long_unsigned_type_internal_node = long_unsigned_type_node;
11737 intQI_type_internal_node = intQI_type_node;
11738 uintQI_type_internal_node = unsigned_intQI_type_node;
11739 intHI_type_internal_node = intHI_type_node;
11740 uintHI_type_internal_node = unsigned_intHI_type_node;
11741 intSI_type_internal_node = intSI_type_node;
11742 uintSI_type_internal_node = unsigned_intSI_type_node;
11743 intDI_type_internal_node = intDI_type_node;
11744 uintDI_type_internal_node = unsigned_intDI_type_node;
11745 float_type_internal_node = float_type_node;
11746 double_type_internal_node = float_type_node;
11747 void_type_internal_node = void_type_node;
11749 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11750 tree type node. */
11751 builtin_mode_to_type[QImode][0] = integer_type_node;
11752 builtin_mode_to_type[HImode][0] = integer_type_node;
11753 builtin_mode_to_type[SImode][0] = intSI_type_node;
11754 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11755 builtin_mode_to_type[DImode][0] = intDI_type_node;
11756 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11757 builtin_mode_to_type[SFmode][0] = float_type_node;
11758 builtin_mode_to_type[DFmode][0] = double_type_node;
11759 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11760 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11761 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11762 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11763 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11764 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11765 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11766 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11767 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11768 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11769 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11770 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11771 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11773 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11774 get_identifier ("__bool char"),
11775 bool_char_type_node);
11776 TYPE_NAME (bool_char_type_node) = tdecl;
11777 (*lang_hooks.decls.pushdecl) (tdecl);
11778 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11779 get_identifier ("__bool short"),
11780 bool_short_type_node);
11781 TYPE_NAME (bool_short_type_node) = tdecl;
11782 (*lang_hooks.decls.pushdecl) (tdecl);
11783 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11784 get_identifier ("__bool int"),
11785 bool_int_type_node);
11786 TYPE_NAME (bool_int_type_node) = tdecl;
11787 (*lang_hooks.decls.pushdecl) (tdecl);
11788 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11789 pixel_type_node);
11790 TYPE_NAME (pixel_type_node) = tdecl;
11791 (*lang_hooks.decls.pushdecl) (tdecl);
11793 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11794 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11795 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11796 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11797 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11799 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11800 get_identifier ("__vector unsigned char"),
11801 unsigned_V16QI_type_node);
11802 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11803 (*lang_hooks.decls.pushdecl) (tdecl);
11804 tdecl = build_decl (BUILTINS_LOCATION,
11805 TYPE_DECL, get_identifier ("__vector signed char"),
11806 V16QI_type_node);
11807 TYPE_NAME (V16QI_type_node) = tdecl;
11808 (*lang_hooks.decls.pushdecl) (tdecl);
11809 tdecl = build_decl (BUILTINS_LOCATION,
11810 TYPE_DECL, get_identifier ("__vector __bool char"),
11811 bool_V16QI_type_node);
11812 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11813 (*lang_hooks.decls.pushdecl) (tdecl);
11815 tdecl = build_decl (BUILTINS_LOCATION,
11816 TYPE_DECL, get_identifier ("__vector unsigned short"),
11817 unsigned_V8HI_type_node);
11818 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11819 (*lang_hooks.decls.pushdecl) (tdecl);
11820 tdecl = build_decl (BUILTINS_LOCATION,
11821 TYPE_DECL, get_identifier ("__vector signed short"),
11822 V8HI_type_node);
11823 TYPE_NAME (V8HI_type_node) = tdecl;
11824 (*lang_hooks.decls.pushdecl) (tdecl);
11825 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11826 get_identifier ("__vector __bool short"),
11827 bool_V8HI_type_node);
11828 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11829 (*lang_hooks.decls.pushdecl) (tdecl);
11831 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11832 get_identifier ("__vector unsigned int"),
11833 unsigned_V4SI_type_node);
11834 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11835 (*lang_hooks.decls.pushdecl) (tdecl);
11836 tdecl = build_decl (BUILTINS_LOCATION,
11837 TYPE_DECL, get_identifier ("__vector signed int"),
11838 V4SI_type_node);
11839 TYPE_NAME (V4SI_type_node) = tdecl;
11840 (*lang_hooks.decls.pushdecl) (tdecl);
11841 tdecl = build_decl (BUILTINS_LOCATION,
11842 TYPE_DECL, get_identifier ("__vector __bool int"),
11843 bool_V4SI_type_node);
11844 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11845 (*lang_hooks.decls.pushdecl) (tdecl);
11847 tdecl = build_decl (BUILTINS_LOCATION,
11848 TYPE_DECL, get_identifier ("__vector float"),
11849 V4SF_type_node);
11850 TYPE_NAME (V4SF_type_node) = tdecl;
11851 (*lang_hooks.decls.pushdecl) (tdecl);
11852 tdecl = build_decl (BUILTINS_LOCATION,
11853 TYPE_DECL, get_identifier ("__vector __pixel"),
11854 pixel_V8HI_type_node);
11855 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11856 (*lang_hooks.decls.pushdecl) (tdecl);
11858 if (TARGET_VSX)
11860 tdecl = build_decl (BUILTINS_LOCATION,
11861 TYPE_DECL, get_identifier ("__vector double"),
11862 V2DF_type_node);
11863 TYPE_NAME (V2DF_type_node) = tdecl;
11864 (*lang_hooks.decls.pushdecl) (tdecl);
11866 tdecl = build_decl (BUILTINS_LOCATION,
11867 TYPE_DECL, get_identifier ("__vector long"),
11868 V2DI_type_node);
11869 TYPE_NAME (V2DI_type_node) = tdecl;
11870 (*lang_hooks.decls.pushdecl) (tdecl);
11872 tdecl = build_decl (BUILTINS_LOCATION,
11873 TYPE_DECL, get_identifier ("__vector unsigned long"),
11874 unsigned_V2DI_type_node);
11875 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11876 (*lang_hooks.decls.pushdecl) (tdecl);
11878 tdecl = build_decl (BUILTINS_LOCATION,
11879 TYPE_DECL, get_identifier ("__vector __bool long"),
11880 bool_V2DI_type_node);
11881 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11882 (*lang_hooks.decls.pushdecl) (tdecl);
11885 if (TARGET_PAIRED_FLOAT)
11886 paired_init_builtins ();
11887 if (TARGET_SPE)
11888 spe_init_builtins ();
11889 if (TARGET_ALTIVEC)
11890 altivec_init_builtins ();
11891 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11892 rs6000_common_init_builtins ();
11893 if (TARGET_FRE)
11895 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11896 RS6000_BUILTIN_RECIP,
11897 "__builtin_recipdiv");
11898 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11899 RS6000_BUILTIN_RECIP);
11901 if (TARGET_FRES)
11903 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11904 RS6000_BUILTIN_RECIPF,
11905 "__builtin_recipdivf");
11906 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11907 RS6000_BUILTIN_RECIPF);
11909 if (TARGET_FRSQRTE)
11911 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
11912 RS6000_BUILTIN_RSQRT,
11913 "__builtin_rsqrt");
11914 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
11915 RS6000_BUILTIN_RSQRT);
11917 if (TARGET_FRSQRTES)
11919 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11920 RS6000_BUILTIN_RSQRTF,
11921 "__builtin_rsqrtf");
11922 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11923 RS6000_BUILTIN_RSQRTF);
11925 if (TARGET_POPCNTD)
11927 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11928 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11929 POWER7_BUILTIN_BPERMD,
11930 "__builtin_bpermd");
11931 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11932 POWER7_BUILTIN_BPERMD);
11934 if (TARGET_POWERPC)
11936 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11937 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11938 unsigned_intHI_type_node,
11939 NULL_TREE);
11940 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11941 RS6000_BUILTIN_BSWAP_HI);
11944 #if TARGET_XCOFF
11945 /* AIX libm provides clog as __clog. */
11946 if (built_in_decls [BUILT_IN_CLOG])
11947 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11948 #endif
11950 #ifdef SUBTARGET_INIT_BUILTINS
11951 SUBTARGET_INIT_BUILTINS;
11952 #endif
11955 /* Returns the rs6000 builtin decl for CODE. */
11957 static tree
11958 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11960 if (code >= RS6000_BUILTIN_COUNT)
11961 return error_mark_node;
11963 return rs6000_builtin_decls[code];
11966 /* Search through a set of builtins and enable the mask bits.
11967 DESC is an array of builtins.
11968 SIZE is the total number of builtins.
11969 START is the builtin enum at which to start.
11970 END is the builtin enum at which to end. */
11971 static void
11972 enable_mask_for_builtins (struct builtin_description *desc, int size,
11973 enum rs6000_builtins start,
11974 enum rs6000_builtins end)
11976 int i;
11978 for (i = 0; i < size; ++i)
11979 if (desc[i].code == start)
11980 break;
11982 if (i == size)
11983 return;
11985 for (; i < size; ++i)
11987 /* Flip all the bits on. */
11988 desc[i].mask = target_flags;
11989 if (desc[i].code == end)
11990 break;
11994 static void
11995 spe_init_builtins (void)
11997 tree endlink = void_list_node;
11998 tree puint_type_node = build_pointer_type (unsigned_type_node);
11999 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12000 struct builtin_description *d;
12001 size_t i;
12003 tree v2si_ftype_4_v2si
12004 = build_function_type
12005 (opaque_V2SI_type_node,
12006 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12007 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12008 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12009 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12010 endlink)))));
12012 tree v2sf_ftype_4_v2sf
12013 = build_function_type
12014 (opaque_V2SF_type_node,
12015 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12016 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12017 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12018 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12019 endlink)))));
12021 tree int_ftype_int_v2si_v2si
12022 = build_function_type
12023 (integer_type_node,
12024 tree_cons (NULL_TREE, integer_type_node,
12025 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12026 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12027 endlink))));
12029 tree int_ftype_int_v2sf_v2sf
12030 = build_function_type
12031 (integer_type_node,
12032 tree_cons (NULL_TREE, integer_type_node,
12033 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12034 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12035 endlink))));
12037 tree void_ftype_v2si_puint_int
12038 = build_function_type (void_type_node,
12039 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12040 tree_cons (NULL_TREE, puint_type_node,
12041 tree_cons (NULL_TREE,
12042 integer_type_node,
12043 endlink))));
12045 tree void_ftype_v2si_puint_char
12046 = build_function_type (void_type_node,
12047 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12048 tree_cons (NULL_TREE, puint_type_node,
12049 tree_cons (NULL_TREE,
12050 char_type_node,
12051 endlink))));
12053 tree void_ftype_v2si_pv2si_int
12054 = build_function_type (void_type_node,
12055 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12056 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12057 tree_cons (NULL_TREE,
12058 integer_type_node,
12059 endlink))));
12061 tree void_ftype_v2si_pv2si_char
12062 = build_function_type (void_type_node,
12063 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12064 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12065 tree_cons (NULL_TREE,
12066 char_type_node,
12067 endlink))));
12069 tree void_ftype_int
12070 = build_function_type (void_type_node,
12071 tree_cons (NULL_TREE, integer_type_node, endlink));
12073 tree int_ftype_void
12074 = build_function_type (integer_type_node, endlink);
12076 tree v2si_ftype_pv2si_int
12077 = build_function_type (opaque_V2SI_type_node,
12078 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12079 tree_cons (NULL_TREE, integer_type_node,
12080 endlink)));
12082 tree v2si_ftype_puint_int
12083 = build_function_type (opaque_V2SI_type_node,
12084 tree_cons (NULL_TREE, puint_type_node,
12085 tree_cons (NULL_TREE, integer_type_node,
12086 endlink)));
12088 tree v2si_ftype_pushort_int
12089 = build_function_type (opaque_V2SI_type_node,
12090 tree_cons (NULL_TREE, pushort_type_node,
12091 tree_cons (NULL_TREE, integer_type_node,
12092 endlink)));
12094 tree v2si_ftype_signed_char
12095 = build_function_type (opaque_V2SI_type_node,
12096 tree_cons (NULL_TREE, signed_char_type_node,
12097 endlink));
12099 /* The initialization of the simple binary and unary builtins is
12100 done in rs6000_common_init_builtins, but we have to enable the
12101 mask bits here manually because we have run out of `target_flags'
12102 bits. We really need to redesign this mask business. */
12104 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12105 ARRAY_SIZE (bdesc_2arg),
12106 SPE_BUILTIN_EVADDW,
12107 SPE_BUILTIN_EVXOR);
12108 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12109 ARRAY_SIZE (bdesc_1arg),
12110 SPE_BUILTIN_EVABS,
12111 SPE_BUILTIN_EVSUBFUSIAAW);
12112 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12113 ARRAY_SIZE (bdesc_spe_predicates),
12114 SPE_BUILTIN_EVCMPEQ,
12115 SPE_BUILTIN_EVFSTSTLT);
12116 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12117 ARRAY_SIZE (bdesc_spe_evsel),
12118 SPE_BUILTIN_EVSEL_CMPGTS,
12119 SPE_BUILTIN_EVSEL_FSTSTEQ);
12121 (*lang_hooks.decls.pushdecl)
12122 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12123 get_identifier ("__ev64_opaque__"),
12124 opaque_V2SI_type_node));
12126 /* Initialize irregular SPE builtins. */
12128 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12129 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12130 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12131 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12132 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12133 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12134 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12135 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12136 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12137 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12138 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12139 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12140 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12141 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12142 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12143 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12144 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12145 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12147 /* Loads. */
12148 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12149 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12150 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12151 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12152 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12153 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12154 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12155 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12156 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12157 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12158 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12159 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12160 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12161 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12162 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12163 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12164 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12165 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12166 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12167 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12168 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12169 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12171 /* Predicates. */
12172 d = (struct builtin_description *) bdesc_spe_predicates;
12173 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12175 tree type;
12177 switch (insn_data[d->icode].operand[1].mode)
12179 case V2SImode:
12180 type = int_ftype_int_v2si_v2si;
12181 break;
12182 case V2SFmode:
12183 type = int_ftype_int_v2sf_v2sf;
12184 break;
12185 default:
12186 gcc_unreachable ();
12189 def_builtin (d->mask, d->name, type, d->code);
12192 /* Evsel predicates. */
12193 d = (struct builtin_description *) bdesc_spe_evsel;
12194 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12196 tree type;
12198 switch (insn_data[d->icode].operand[1].mode)
12200 case V2SImode:
12201 type = v2si_ftype_4_v2si;
12202 break;
12203 case V2SFmode:
12204 type = v2sf_ftype_4_v2sf;
12205 break;
12206 default:
12207 gcc_unreachable ();
12210 def_builtin (d->mask, d->name, type, d->code);
12214 static void
12215 paired_init_builtins (void)
12217 const struct builtin_description *d;
12218 size_t i;
12219 tree endlink = void_list_node;
12221 tree int_ftype_int_v2sf_v2sf
12222 = build_function_type
12223 (integer_type_node,
12224 tree_cons (NULL_TREE, integer_type_node,
12225 tree_cons (NULL_TREE, V2SF_type_node,
12226 tree_cons (NULL_TREE, V2SF_type_node,
12227 endlink))));
12228 tree pcfloat_type_node =
12229 build_pointer_type (build_qualified_type
12230 (float_type_node, TYPE_QUAL_CONST));
12232 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12233 long_integer_type_node,
12234 pcfloat_type_node,
12235 NULL_TREE);
12236 tree void_ftype_v2sf_long_pcfloat =
12237 build_function_type_list (void_type_node,
12238 V2SF_type_node,
12239 long_integer_type_node,
12240 pcfloat_type_node,
12241 NULL_TREE);
12244 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12245 PAIRED_BUILTIN_LX);
12248 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12249 PAIRED_BUILTIN_STX);
12251 /* Predicates. */
12252 d = bdesc_paired_preds;
12253 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12255 tree type;
12257 switch (insn_data[d->icode].operand[1].mode)
12259 case V2SFmode:
12260 type = int_ftype_int_v2sf_v2sf;
12261 break;
12262 default:
12263 gcc_unreachable ();
12266 def_builtin (d->mask, d->name, type, d->code);
12270 static void
12271 altivec_init_builtins (void)
12273 const struct builtin_description *d;
12274 const struct builtin_description_predicates *dp;
12275 size_t i;
12276 tree ftype;
12278 tree pfloat_type_node = build_pointer_type (float_type_node);
12279 tree pint_type_node = build_pointer_type (integer_type_node);
12280 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12281 tree pchar_type_node = build_pointer_type (char_type_node);
12283 tree pvoid_type_node = build_pointer_type (void_type_node);
12285 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12286 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12287 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12288 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12290 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12292 tree int_ftype_opaque
12293 = build_function_type_list (integer_type_node,
12294 opaque_V4SI_type_node, NULL_TREE);
12295 tree opaque_ftype_opaque
12296 = build_function_type (integer_type_node,
12297 NULL_TREE);
12298 tree opaque_ftype_opaque_int
12299 = build_function_type_list (opaque_V4SI_type_node,
12300 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12301 tree opaque_ftype_opaque_opaque_int
12302 = build_function_type_list (opaque_V4SI_type_node,
12303 opaque_V4SI_type_node, opaque_V4SI_type_node,
12304 integer_type_node, NULL_TREE);
12305 tree int_ftype_int_opaque_opaque
12306 = build_function_type_list (integer_type_node,
12307 integer_type_node, opaque_V4SI_type_node,
12308 opaque_V4SI_type_node, NULL_TREE);
12309 tree int_ftype_int_v4si_v4si
12310 = build_function_type_list (integer_type_node,
12311 integer_type_node, V4SI_type_node,
12312 V4SI_type_node, NULL_TREE);
12313 tree v4sf_ftype_pcfloat
12314 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12315 tree void_ftype_pfloat_v4sf
12316 = build_function_type_list (void_type_node,
12317 pfloat_type_node, V4SF_type_node, NULL_TREE);
12318 tree v4si_ftype_pcint
12319 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12320 tree void_ftype_pint_v4si
12321 = build_function_type_list (void_type_node,
12322 pint_type_node, V4SI_type_node, NULL_TREE);
12323 tree v8hi_ftype_pcshort
12324 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12325 tree void_ftype_pshort_v8hi
12326 = build_function_type_list (void_type_node,
12327 pshort_type_node, V8HI_type_node, NULL_TREE);
12328 tree v16qi_ftype_pcchar
12329 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12330 tree void_ftype_pchar_v16qi
12331 = build_function_type_list (void_type_node,
12332 pchar_type_node, V16QI_type_node, NULL_TREE);
12333 tree void_ftype_v4si
12334 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12335 tree v8hi_ftype_void
12336 = build_function_type (V8HI_type_node, void_list_node);
12337 tree void_ftype_void
12338 = build_function_type (void_type_node, void_list_node);
12339 tree void_ftype_int
12340 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12342 tree opaque_ftype_long_pcvoid
12343 = build_function_type_list (opaque_V4SI_type_node,
12344 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12345 tree v16qi_ftype_long_pcvoid
12346 = build_function_type_list (V16QI_type_node,
12347 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12348 tree v8hi_ftype_long_pcvoid
12349 = build_function_type_list (V8HI_type_node,
12350 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12351 tree v4si_ftype_long_pcvoid
12352 = build_function_type_list (V4SI_type_node,
12353 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12355 tree void_ftype_opaque_long_pvoid
12356 = build_function_type_list (void_type_node,
12357 opaque_V4SI_type_node, long_integer_type_node,
12358 pvoid_type_node, NULL_TREE);
12359 tree void_ftype_v4si_long_pvoid
12360 = build_function_type_list (void_type_node,
12361 V4SI_type_node, long_integer_type_node,
12362 pvoid_type_node, NULL_TREE);
12363 tree void_ftype_v16qi_long_pvoid
12364 = build_function_type_list (void_type_node,
12365 V16QI_type_node, long_integer_type_node,
12366 pvoid_type_node, NULL_TREE);
12367 tree void_ftype_v8hi_long_pvoid
12368 = build_function_type_list (void_type_node,
12369 V8HI_type_node, long_integer_type_node,
12370 pvoid_type_node, NULL_TREE);
12371 tree int_ftype_int_v8hi_v8hi
12372 = build_function_type_list (integer_type_node,
12373 integer_type_node, V8HI_type_node,
12374 V8HI_type_node, NULL_TREE);
12375 tree int_ftype_int_v16qi_v16qi
12376 = build_function_type_list (integer_type_node,
12377 integer_type_node, V16QI_type_node,
12378 V16QI_type_node, NULL_TREE);
12379 tree int_ftype_int_v4sf_v4sf
12380 = build_function_type_list (integer_type_node,
12381 integer_type_node, V4SF_type_node,
12382 V4SF_type_node, NULL_TREE);
12383 tree int_ftype_int_v2df_v2df
12384 = build_function_type_list (integer_type_node,
12385 integer_type_node, V2DF_type_node,
12386 V2DF_type_node, NULL_TREE);
12387 tree v4si_ftype_v4si
12388 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12389 tree v8hi_ftype_v8hi
12390 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12391 tree v16qi_ftype_v16qi
12392 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12393 tree v4sf_ftype_v4sf
12394 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12395 tree v2df_ftype_v2df
12396 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12397 tree void_ftype_pcvoid_int_int
12398 = build_function_type_list (void_type_node,
12399 pcvoid_type_node, integer_type_node,
12400 integer_type_node, NULL_TREE);
12402 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12403 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12404 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12405 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12406 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12407 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12408 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12409 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12410 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12411 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12412 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12413 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12414 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12415 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12416 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12417 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12418 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12419 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12420 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12421 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12422 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12423 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12424 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12425 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12426 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12427 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12428 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12429 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12430 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12431 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12432 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12433 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12434 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12435 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12436 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12437 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12438 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12439 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12440 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12441 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12442 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12443 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12444 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12445 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12446 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12447 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12449 if (rs6000_cpu == PROCESSOR_CELL)
12451 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12452 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12453 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12454 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12456 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12457 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12458 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12459 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12461 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12462 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12463 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12464 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12466 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12467 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12468 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12469 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12471 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12472 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12473 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12475 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12476 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12477 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12478 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12479 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12480 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12481 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12482 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12483 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12484 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12485 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12486 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12488 /* Add the DST variants. */
12489 d = bdesc_dst;
12490 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12491 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12493 /* Initialize the predicates. */
12494 dp = bdesc_altivec_preds;
12495 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12497 enum machine_mode mode1;
12498 tree type;
12499 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12500 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12501 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12502 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12504 if (is_overloaded)
12505 mode1 = VOIDmode;
12506 else
12507 mode1 = insn_data[dp->icode].operand[1].mode;
12509 switch (mode1)
12511 case VOIDmode:
12512 type = int_ftype_int_opaque_opaque;
12513 break;
12514 case V4SImode:
12515 type = int_ftype_int_v4si_v4si;
12516 break;
12517 case V8HImode:
12518 type = int_ftype_int_v8hi_v8hi;
12519 break;
12520 case V16QImode:
12521 type = int_ftype_int_v16qi_v16qi;
12522 break;
12523 case V4SFmode:
12524 type = int_ftype_int_v4sf_v4sf;
12525 break;
12526 case V2DFmode:
12527 type = int_ftype_int_v2df_v2df;
12528 break;
12529 default:
12530 gcc_unreachable ();
12533 def_builtin (dp->mask, dp->name, type, dp->code);
12536 /* Initialize the abs* operators. */
12537 d = bdesc_abs;
12538 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12540 enum machine_mode mode0;
12541 tree type;
12543 mode0 = insn_data[d->icode].operand[0].mode;
12545 switch (mode0)
12547 case V4SImode:
12548 type = v4si_ftype_v4si;
12549 break;
12550 case V8HImode:
12551 type = v8hi_ftype_v8hi;
12552 break;
12553 case V16QImode:
12554 type = v16qi_ftype_v16qi;
12555 break;
12556 case V4SFmode:
12557 type = v4sf_ftype_v4sf;
12558 break;
12559 case V2DFmode:
12560 type = v2df_ftype_v2df;
12561 break;
12562 default:
12563 gcc_unreachable ();
12566 def_builtin (d->mask, d->name, type, d->code);
12569 if (TARGET_ALTIVEC)
12571 tree decl;
12573 /* Initialize target builtin that implements
12574 targetm.vectorize.builtin_mask_for_load. */
12576 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12577 v16qi_ftype_long_pcvoid,
12578 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12579 BUILT_IN_MD, NULL, NULL_TREE);
12580 TREE_READONLY (decl) = 1;
12581 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12582 altivec_builtin_mask_for_load = decl;
12585 /* Access to the vec_init patterns. */
12586 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12587 integer_type_node, integer_type_node,
12588 integer_type_node, NULL_TREE);
12589 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12590 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12592 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12593 short_integer_type_node,
12594 short_integer_type_node,
12595 short_integer_type_node,
12596 short_integer_type_node,
12597 short_integer_type_node,
12598 short_integer_type_node,
12599 short_integer_type_node, NULL_TREE);
12600 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12601 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12603 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12604 char_type_node, char_type_node,
12605 char_type_node, char_type_node,
12606 char_type_node, char_type_node,
12607 char_type_node, char_type_node,
12608 char_type_node, char_type_node,
12609 char_type_node, char_type_node,
12610 char_type_node, char_type_node,
12611 char_type_node, NULL_TREE);
12612 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12613 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12615 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12616 float_type_node, float_type_node,
12617 float_type_node, NULL_TREE);
12618 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12619 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12621 if (TARGET_VSX)
12623 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12624 double_type_node, NULL_TREE);
12625 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12626 VSX_BUILTIN_VEC_INIT_V2DF);
12628 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12629 intDI_type_node, NULL_TREE);
12630 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12631 VSX_BUILTIN_VEC_INIT_V2DI);
12634 /* Access to the vec_set patterns. */
12635 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12636 intSI_type_node,
12637 integer_type_node, NULL_TREE);
12638 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12639 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12641 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12642 intHI_type_node,
12643 integer_type_node, NULL_TREE);
12644 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12645 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12647 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12648 intQI_type_node,
12649 integer_type_node, NULL_TREE);
12650 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12651 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12653 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12654 float_type_node,
12655 integer_type_node, NULL_TREE);
12656 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12657 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12659 if (TARGET_VSX)
12661 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12662 double_type_node,
12663 integer_type_node, NULL_TREE);
12664 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12665 VSX_BUILTIN_VEC_SET_V2DF);
12667 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12668 intDI_type_node,
12669 integer_type_node, NULL_TREE);
12670 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12671 VSX_BUILTIN_VEC_SET_V2DI);
12674 /* Access to the vec_extract patterns. */
12675 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12676 integer_type_node, NULL_TREE);
12677 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12678 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12680 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12681 integer_type_node, NULL_TREE);
12682 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12683 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12685 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12686 integer_type_node, NULL_TREE);
12687 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12688 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12690 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12691 integer_type_node, NULL_TREE);
12692 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12693 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12695 if (TARGET_VSX)
12697 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12698 integer_type_node, NULL_TREE);
12699 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12700 VSX_BUILTIN_VEC_EXT_V2DF);
12702 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12703 integer_type_node, NULL_TREE);
12704 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12705 VSX_BUILTIN_VEC_EXT_V2DI);
12709 /* Hash function for builtin functions with up to 3 arguments and a return
12710 type. */
12711 static unsigned
12712 builtin_hash_function (const void *hash_entry)
12714 unsigned ret = 0;
12715 int i;
12716 const struct builtin_hash_struct *bh =
12717 (const struct builtin_hash_struct *) hash_entry;
12719 for (i = 0; i < 4; i++)
12721 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12722 ret = (ret * 2) + bh->uns_p[i];
12725 return ret;
12728 /* Compare builtin hash entries H1 and H2 for equivalence. */
12729 static int
12730 builtin_hash_eq (const void *h1, const void *h2)
12732 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12733 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12735 return ((p1->mode[0] == p2->mode[0])
12736 && (p1->mode[1] == p2->mode[1])
12737 && (p1->mode[2] == p2->mode[2])
12738 && (p1->mode[3] == p2->mode[3])
12739 && (p1->uns_p[0] == p2->uns_p[0])
12740 && (p1->uns_p[1] == p2->uns_p[1])
12741 && (p1->uns_p[2] == p2->uns_p[2])
12742 && (p1->uns_p[3] == p2->uns_p[3]));
12745 /* Map types for builtin functions with an explicit return type and up to 3
12746 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12747 of the argument. */
12748 static tree
12749 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12750 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12751 enum rs6000_builtins builtin, const char *name)
12753 struct builtin_hash_struct h;
12754 struct builtin_hash_struct *h2;
12755 void **found;
12756 int num_args = 3;
12757 int i;
12758 tree ret_type = NULL_TREE;
12759 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12760 tree args;
12762 /* Create builtin_hash_table. */
12763 if (builtin_hash_table == NULL)
12764 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12765 builtin_hash_eq, NULL);
12767 h.type = NULL_TREE;
12768 h.mode[0] = mode_ret;
12769 h.mode[1] = mode_arg0;
12770 h.mode[2] = mode_arg1;
12771 h.mode[3] = mode_arg2;
12772 h.uns_p[0] = 0;
12773 h.uns_p[1] = 0;
12774 h.uns_p[2] = 0;
12775 h.uns_p[3] = 0;
12777 /* If the builtin is a type that produces unsigned results or takes unsigned
12778 arguments, and it is returned as a decl for the vectorizer (such as
12779 widening multiplies, permute), make sure the arguments and return value
12780 are type correct. */
12781 switch (builtin)
12783 /* unsigned 2 argument functions. */
12784 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12785 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12786 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12787 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12788 h.uns_p[0] = 1;
12789 h.uns_p[1] = 1;
12790 h.uns_p[2] = 1;
12791 break;
12793 /* unsigned 3 argument functions. */
12794 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12795 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12796 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12797 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12798 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12799 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12800 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12801 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12802 case VSX_BUILTIN_VPERM_16QI_UNS:
12803 case VSX_BUILTIN_VPERM_8HI_UNS:
12804 case VSX_BUILTIN_VPERM_4SI_UNS:
12805 case VSX_BUILTIN_VPERM_2DI_UNS:
12806 case VSX_BUILTIN_XXSEL_16QI_UNS:
12807 case VSX_BUILTIN_XXSEL_8HI_UNS:
12808 case VSX_BUILTIN_XXSEL_4SI_UNS:
12809 case VSX_BUILTIN_XXSEL_2DI_UNS:
12810 h.uns_p[0] = 1;
12811 h.uns_p[1] = 1;
12812 h.uns_p[2] = 1;
12813 h.uns_p[3] = 1;
12814 break;
12816 /* signed permute functions with unsigned char mask. */
12817 case ALTIVEC_BUILTIN_VPERM_16QI:
12818 case ALTIVEC_BUILTIN_VPERM_8HI:
12819 case ALTIVEC_BUILTIN_VPERM_4SI:
12820 case ALTIVEC_BUILTIN_VPERM_4SF:
12821 case ALTIVEC_BUILTIN_VPERM_2DI:
12822 case ALTIVEC_BUILTIN_VPERM_2DF:
12823 case VSX_BUILTIN_VPERM_16QI:
12824 case VSX_BUILTIN_VPERM_8HI:
12825 case VSX_BUILTIN_VPERM_4SI:
12826 case VSX_BUILTIN_VPERM_4SF:
12827 case VSX_BUILTIN_VPERM_2DI:
12828 case VSX_BUILTIN_VPERM_2DF:
12829 h.uns_p[3] = 1;
12830 break;
12832 /* unsigned args, signed return. */
12833 case VSX_BUILTIN_XVCVUXDDP_UNS:
12834 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12835 h.uns_p[1] = 1;
12836 break;
12838 /* signed args, unsigned return. */
12839 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12840 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12841 h.uns_p[0] = 1;
12842 break;
12844 default:
12845 break;
12848 /* Figure out how many args are present. */
12849 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12850 num_args--;
12852 if (num_args == 0)
12853 fatal_error ("internal error: builtin function %s had no type", name);
12855 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12856 if (!ret_type && h.uns_p[0])
12857 ret_type = builtin_mode_to_type[h.mode[0]][0];
12859 if (!ret_type)
12860 fatal_error ("internal error: builtin function %s had an unexpected "
12861 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12863 for (i = 0; i < num_args; i++)
12865 int m = (int) h.mode[i+1];
12866 int uns_p = h.uns_p[i+1];
12868 arg_type[i] = builtin_mode_to_type[m][uns_p];
12869 if (!arg_type[i] && uns_p)
12870 arg_type[i] = builtin_mode_to_type[m][0];
12872 if (!arg_type[i])
12873 fatal_error ("internal error: builtin function %s, argument %d "
12874 "had unexpected argument type %s", name, i,
12875 GET_MODE_NAME (m));
12878 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12879 if (*found == NULL)
12881 h2 = ggc_alloc_builtin_hash_struct ();
12882 *h2 = h;
12883 *found = (void *)h2;
12884 args = void_list_node;
12886 for (i = num_args - 1; i >= 0; i--)
12887 args = tree_cons (NULL_TREE, arg_type[i], args);
12889 h2->type = build_function_type (ret_type, args);
12892 return ((struct builtin_hash_struct *)(*found))->type;
12895 static void
12896 rs6000_common_init_builtins (void)
12898 const struct builtin_description *d;
12899 size_t i;
12901 tree opaque_ftype_opaque = NULL_TREE;
12902 tree opaque_ftype_opaque_opaque = NULL_TREE;
12903 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12904 tree v2si_ftype_qi = NULL_TREE;
12905 tree v2si_ftype_v2si_qi = NULL_TREE;
12906 tree v2si_ftype_int_qi = NULL_TREE;
12908 if (!TARGET_PAIRED_FLOAT)
12910 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12911 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12914 /* Add the ternary operators. */
12915 d = bdesc_3arg;
12916 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12918 tree type;
12919 int mask = d->mask;
12921 if ((mask != 0 && (mask & target_flags) == 0)
12922 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12923 continue;
12925 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12926 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12927 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12928 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12930 if (! (type = opaque_ftype_opaque_opaque_opaque))
12931 type = opaque_ftype_opaque_opaque_opaque
12932 = build_function_type_list (opaque_V4SI_type_node,
12933 opaque_V4SI_type_node,
12934 opaque_V4SI_type_node,
12935 opaque_V4SI_type_node,
12936 NULL_TREE);
12938 else
12940 enum insn_code icode = d->icode;
12941 if (d->name == 0 || icode == CODE_FOR_nothing)
12942 continue;
12944 type = builtin_function_type (insn_data[icode].operand[0].mode,
12945 insn_data[icode].operand[1].mode,
12946 insn_data[icode].operand[2].mode,
12947 insn_data[icode].operand[3].mode,
12948 d->code, d->name);
12951 def_builtin (d->mask, d->name, type, d->code);
12954 /* Add the binary operators. */
12955 d = bdesc_2arg;
12956 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12958 enum machine_mode mode0, mode1, mode2;
12959 tree type;
12960 int mask = d->mask;
12962 if ((mask != 0 && (mask & target_flags) == 0)
12963 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12964 continue;
12966 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12967 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12968 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12969 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12971 if (! (type = opaque_ftype_opaque_opaque))
12972 type = opaque_ftype_opaque_opaque
12973 = build_function_type_list (opaque_V4SI_type_node,
12974 opaque_V4SI_type_node,
12975 opaque_V4SI_type_node,
12976 NULL_TREE);
12978 else
12980 enum insn_code icode = d->icode;
12981 if (d->name == 0 || icode == CODE_FOR_nothing)
12982 continue;
12984 mode0 = insn_data[icode].operand[0].mode;
12985 mode1 = insn_data[icode].operand[1].mode;
12986 mode2 = insn_data[icode].operand[2].mode;
12988 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12990 if (! (type = v2si_ftype_v2si_qi))
12991 type = v2si_ftype_v2si_qi
12992 = build_function_type_list (opaque_V2SI_type_node,
12993 opaque_V2SI_type_node,
12994 char_type_node,
12995 NULL_TREE);
12998 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12999 && mode2 == QImode)
13001 if (! (type = v2si_ftype_int_qi))
13002 type = v2si_ftype_int_qi
13003 = build_function_type_list (opaque_V2SI_type_node,
13004 integer_type_node,
13005 char_type_node,
13006 NULL_TREE);
13009 else
13010 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13011 d->code, d->name);
13014 def_builtin (d->mask, d->name, type, d->code);
13017 /* Add the simple unary operators. */
13018 d = (struct builtin_description *) bdesc_1arg;
13019 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13021 enum machine_mode mode0, mode1;
13022 tree type;
13023 int mask = d->mask;
13025 if ((mask != 0 && (mask & target_flags) == 0)
13026 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13027 continue;
13029 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13030 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13031 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13032 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13034 if (! (type = opaque_ftype_opaque))
13035 type = opaque_ftype_opaque
13036 = build_function_type_list (opaque_V4SI_type_node,
13037 opaque_V4SI_type_node,
13038 NULL_TREE);
13040 else
13042 enum insn_code icode = d->icode;
13043 if (d->name == 0 || icode == CODE_FOR_nothing)
13044 continue;
13046 mode0 = insn_data[icode].operand[0].mode;
13047 mode1 = insn_data[icode].operand[1].mode;
13049 if (mode0 == V2SImode && mode1 == QImode)
13051 if (! (type = v2si_ftype_qi))
13052 type = v2si_ftype_qi
13053 = build_function_type_list (opaque_V2SI_type_node,
13054 char_type_node,
13055 NULL_TREE);
13058 else
13059 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13060 d->code, d->name);
13063 def_builtin (d->mask, d->name, type, d->code);
13067 static void
13068 rs6000_init_libfuncs (void)
13070 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13071 && !TARGET_POWER2 && !TARGET_POWERPC)
13073 /* AIX library routines for float->int conversion. */
13074 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13075 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13076 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13077 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13080 if (!TARGET_IEEEQUAD)
13081 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13082 if (!TARGET_XL_COMPAT)
13084 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13085 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13086 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13087 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13089 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13091 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13092 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13093 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13094 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13095 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13096 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13097 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13099 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13100 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13101 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13102 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13103 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13104 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13105 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13106 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13109 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13110 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13112 else
13114 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13115 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13116 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13117 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13119 else
13121 /* 32-bit SVR4 quad floating point routines. */
13123 set_optab_libfunc (add_optab, TFmode, "_q_add");
13124 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13125 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13126 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13127 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13128 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13129 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13131 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13132 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13133 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13134 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13135 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13136 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13138 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13139 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13140 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13141 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13142 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13143 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13144 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13145 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13150 /* Expand a block clear operation, and return 1 if successful. Return 0
13151 if we should let the compiler generate normal code.
13153 operands[0] is the destination
13154 operands[1] is the length
13155 operands[3] is the alignment */
13158 expand_block_clear (rtx operands[])
13160 rtx orig_dest = operands[0];
13161 rtx bytes_rtx = operands[1];
13162 rtx align_rtx = operands[3];
13163 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13164 HOST_WIDE_INT align;
13165 HOST_WIDE_INT bytes;
13166 int offset;
13167 int clear_bytes;
13168 int clear_step;
13170 /* If this is not a fixed size move, just call memcpy */
13171 if (! constp)
13172 return 0;
13174 /* This must be a fixed size alignment */
13175 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13176 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13178 /* Anything to clear? */
13179 bytes = INTVAL (bytes_rtx);
13180 if (bytes <= 0)
13181 return 1;
13183 /* Use the builtin memset after a point, to avoid huge code bloat.
13184 When optimize_size, avoid any significant code bloat; calling
13185 memset is about 4 instructions, so allow for one instruction to
13186 load zero and three to do clearing. */
13187 if (TARGET_ALTIVEC && align >= 128)
13188 clear_step = 16;
13189 else if (TARGET_POWERPC64 && align >= 32)
13190 clear_step = 8;
13191 else if (TARGET_SPE && align >= 64)
13192 clear_step = 8;
13193 else
13194 clear_step = 4;
13196 if (optimize_size && bytes > 3 * clear_step)
13197 return 0;
13198 if (! optimize_size && bytes > 8 * clear_step)
13199 return 0;
13201 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13203 enum machine_mode mode = BLKmode;
13204 rtx dest;
13206 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13208 clear_bytes = 16;
13209 mode = V4SImode;
13211 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13213 clear_bytes = 8;
13214 mode = V2SImode;
13216 else if (bytes >= 8 && TARGET_POWERPC64
13217 /* 64-bit loads and stores require word-aligned
13218 displacements. */
13219 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13221 clear_bytes = 8;
13222 mode = DImode;
13224 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13225 { /* move 4 bytes */
13226 clear_bytes = 4;
13227 mode = SImode;
13229 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13230 { /* move 2 bytes */
13231 clear_bytes = 2;
13232 mode = HImode;
13234 else /* move 1 byte at a time */
13236 clear_bytes = 1;
13237 mode = QImode;
13240 dest = adjust_address (orig_dest, mode, offset);
13242 emit_move_insn (dest, CONST0_RTX (mode));
13245 return 1;
13249 /* Expand a block move operation, and return 1 if successful. Return 0
13250 if we should let the compiler generate normal code.
13252 operands[0] is the destination
13253 operands[1] is the source
13254 operands[2] is the length
13255 operands[3] is the alignment */
13257 #define MAX_MOVE_REG 4
13260 expand_block_move (rtx operands[])
13262 rtx orig_dest = operands[0];
13263 rtx orig_src = operands[1];
13264 rtx bytes_rtx = operands[2];
13265 rtx align_rtx = operands[3];
13266 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13267 int align;
13268 int bytes;
13269 int offset;
13270 int move_bytes;
13271 rtx stores[MAX_MOVE_REG];
13272 int num_reg = 0;
13274 /* If this is not a fixed size move, just call memcpy */
13275 if (! constp)
13276 return 0;
13278 /* This must be a fixed size alignment */
13279 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13280 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13282 /* Anything to move? */
13283 bytes = INTVAL (bytes_rtx);
13284 if (bytes <= 0)
13285 return 1;
13287 if (bytes > rs6000_block_move_inline_limit)
13288 return 0;
13290 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13292 union {
13293 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13294 rtx (*mov) (rtx, rtx);
13295 } gen_func;
13296 enum machine_mode mode = BLKmode;
13297 rtx src, dest;
13299 /* Altivec first, since it will be faster than a string move
13300 when it applies, and usually not significantly larger. */
13301 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13303 move_bytes = 16;
13304 mode = V4SImode;
13305 gen_func.mov = gen_movv4si;
13307 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13309 move_bytes = 8;
13310 mode = V2SImode;
13311 gen_func.mov = gen_movv2si;
13313 else if (TARGET_STRING
13314 && bytes > 24 /* move up to 32 bytes at a time */
13315 && ! fixed_regs[5]
13316 && ! fixed_regs[6]
13317 && ! fixed_regs[7]
13318 && ! fixed_regs[8]
13319 && ! fixed_regs[9]
13320 && ! fixed_regs[10]
13321 && ! fixed_regs[11]
13322 && ! fixed_regs[12])
13324 move_bytes = (bytes > 32) ? 32 : bytes;
13325 gen_func.movmemsi = gen_movmemsi_8reg;
13327 else if (TARGET_STRING
13328 && bytes > 16 /* move up to 24 bytes at a time */
13329 && ! fixed_regs[5]
13330 && ! fixed_regs[6]
13331 && ! fixed_regs[7]
13332 && ! fixed_regs[8]
13333 && ! fixed_regs[9]
13334 && ! fixed_regs[10])
13336 move_bytes = (bytes > 24) ? 24 : bytes;
13337 gen_func.movmemsi = gen_movmemsi_6reg;
13339 else if (TARGET_STRING
13340 && bytes > 8 /* move up to 16 bytes at a time */
13341 && ! fixed_regs[5]
13342 && ! fixed_regs[6]
13343 && ! fixed_regs[7]
13344 && ! fixed_regs[8])
13346 move_bytes = (bytes > 16) ? 16 : bytes;
13347 gen_func.movmemsi = gen_movmemsi_4reg;
13349 else if (bytes >= 8 && TARGET_POWERPC64
13350 /* 64-bit loads and stores require word-aligned
13351 displacements. */
13352 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13354 move_bytes = 8;
13355 mode = DImode;
13356 gen_func.mov = gen_movdi;
13358 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13359 { /* move up to 8 bytes at a time */
13360 move_bytes = (bytes > 8) ? 8 : bytes;
13361 gen_func.movmemsi = gen_movmemsi_2reg;
13363 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13364 { /* move 4 bytes */
13365 move_bytes = 4;
13366 mode = SImode;
13367 gen_func.mov = gen_movsi;
13369 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13370 { /* move 2 bytes */
13371 move_bytes = 2;
13372 mode = HImode;
13373 gen_func.mov = gen_movhi;
13375 else if (TARGET_STRING && bytes > 1)
13376 { /* move up to 4 bytes at a time */
13377 move_bytes = (bytes > 4) ? 4 : bytes;
13378 gen_func.movmemsi = gen_movmemsi_1reg;
13380 else /* move 1 byte at a time */
13382 move_bytes = 1;
13383 mode = QImode;
13384 gen_func.mov = gen_movqi;
13387 src = adjust_address (orig_src, mode, offset);
13388 dest = adjust_address (orig_dest, mode, offset);
13390 if (mode != BLKmode)
13392 rtx tmp_reg = gen_reg_rtx (mode);
13394 emit_insn ((*gen_func.mov) (tmp_reg, src));
13395 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13398 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13400 int i;
13401 for (i = 0; i < num_reg; i++)
13402 emit_insn (stores[i]);
13403 num_reg = 0;
13406 if (mode == BLKmode)
13408 /* Move the address into scratch registers. The movmemsi
13409 patterns require zero offset. */
13410 if (!REG_P (XEXP (src, 0)))
13412 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13413 src = replace_equiv_address (src, src_reg);
13415 set_mem_size (src, GEN_INT (move_bytes));
13417 if (!REG_P (XEXP (dest, 0)))
13419 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13420 dest = replace_equiv_address (dest, dest_reg);
13422 set_mem_size (dest, GEN_INT (move_bytes));
13424 emit_insn ((*gen_func.movmemsi) (dest, src,
13425 GEN_INT (move_bytes & 31),
13426 align_rtx));
13430 return 1;
13434 /* Return a string to perform a load_multiple operation.
13435 operands[0] is the vector.
13436 operands[1] is the source address.
13437 operands[2] is the first destination register. */
13439 const char *
13440 rs6000_output_load_multiple (rtx operands[3])
13442 /* We have to handle the case where the pseudo used to contain the address
13443 is assigned to one of the output registers. */
13444 int i, j;
13445 int words = XVECLEN (operands[0], 0);
13446 rtx xop[10];
13448 if (XVECLEN (operands[0], 0) == 1)
13449 return "{l|lwz} %2,0(%1)";
13451 for (i = 0; i < words; i++)
13452 if (refers_to_regno_p (REGNO (operands[2]) + i,
13453 REGNO (operands[2]) + i + 1, operands[1], 0))
13455 if (i == words-1)
13457 xop[0] = GEN_INT (4 * (words-1));
13458 xop[1] = operands[1];
13459 xop[2] = operands[2];
13460 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13461 return "";
13463 else if (i == 0)
13465 xop[0] = GEN_INT (4 * (words-1));
13466 xop[1] = operands[1];
13467 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13468 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);
13469 return "";
13471 else
13473 for (j = 0; j < words; j++)
13474 if (j != i)
13476 xop[0] = GEN_INT (j * 4);
13477 xop[1] = operands[1];
13478 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13479 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13481 xop[0] = GEN_INT (i * 4);
13482 xop[1] = operands[1];
13483 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13484 return "";
13488 return "{lsi|lswi} %2,%1,%N0";
13492 /* A validation routine: say whether CODE, a condition code, and MODE
13493 match. The other alternatives either don't make sense or should
13494 never be generated. */
13496 void
13497 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13499 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13500 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13501 && GET_MODE_CLASS (mode) == MODE_CC);
13503 /* These don't make sense. */
13504 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13505 || mode != CCUNSmode);
13507 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13508 || mode == CCUNSmode);
13510 gcc_assert (mode == CCFPmode
13511 || (code != ORDERED && code != UNORDERED
13512 && code != UNEQ && code != LTGT
13513 && code != UNGT && code != UNLT
13514 && code != UNGE && code != UNLE));
13516 /* These should never be generated except for
13517 flag_finite_math_only. */
13518 gcc_assert (mode != CCFPmode
13519 || flag_finite_math_only
13520 || (code != LE && code != GE
13521 && code != UNEQ && code != LTGT
13522 && code != UNGT && code != UNLT));
13524 /* These are invalid; the information is not there. */
13525 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13529 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13530 mask required to convert the result of a rotate insn into a shift
13531 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13534 includes_lshift_p (rtx shiftop, rtx andop)
13536 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13538 shift_mask <<= INTVAL (shiftop);
13540 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13543 /* Similar, but for right shift. */
13546 includes_rshift_p (rtx shiftop, rtx andop)
13548 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13550 shift_mask >>= INTVAL (shiftop);
13552 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13555 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13556 to perform a left shift. It must have exactly SHIFTOP least
13557 significant 0's, then one or more 1's, then zero or more 0's. */
13560 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13562 if (GET_CODE (andop) == CONST_INT)
13564 HOST_WIDE_INT c, lsb, shift_mask;
13566 c = INTVAL (andop);
13567 if (c == 0 || c == ~0)
13568 return 0;
13570 shift_mask = ~0;
13571 shift_mask <<= INTVAL (shiftop);
13573 /* Find the least significant one bit. */
13574 lsb = c & -c;
13576 /* It must coincide with the LSB of the shift mask. */
13577 if (-lsb != shift_mask)
13578 return 0;
13580 /* Invert to look for the next transition (if any). */
13581 c = ~c;
13583 /* Remove the low group of ones (originally low group of zeros). */
13584 c &= -lsb;
13586 /* Again find the lsb, and check we have all 1's above. */
13587 lsb = c & -c;
13588 return c == -lsb;
13590 else if (GET_CODE (andop) == CONST_DOUBLE
13591 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13593 HOST_WIDE_INT low, high, lsb;
13594 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13596 low = CONST_DOUBLE_LOW (andop);
13597 if (HOST_BITS_PER_WIDE_INT < 64)
13598 high = CONST_DOUBLE_HIGH (andop);
13600 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13601 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13602 return 0;
13604 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13606 shift_mask_high = ~0;
13607 if (INTVAL (shiftop) > 32)
13608 shift_mask_high <<= INTVAL (shiftop) - 32;
13610 lsb = high & -high;
13612 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13613 return 0;
13615 high = ~high;
13616 high &= -lsb;
13618 lsb = high & -high;
13619 return high == -lsb;
13622 shift_mask_low = ~0;
13623 shift_mask_low <<= INTVAL (shiftop);
13625 lsb = low & -low;
13627 if (-lsb != shift_mask_low)
13628 return 0;
13630 if (HOST_BITS_PER_WIDE_INT < 64)
13631 high = ~high;
13632 low = ~low;
13633 low &= -lsb;
13635 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13637 lsb = high & -high;
13638 return high == -lsb;
13641 lsb = low & -low;
13642 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13644 else
13645 return 0;
13648 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13649 to perform a left shift. It must have SHIFTOP or more least
13650 significant 0's, with the remainder of the word 1's. */
13653 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13655 if (GET_CODE (andop) == CONST_INT)
13657 HOST_WIDE_INT c, lsb, shift_mask;
13659 shift_mask = ~0;
13660 shift_mask <<= INTVAL (shiftop);
13661 c = INTVAL (andop);
13663 /* Find the least significant one bit. */
13664 lsb = c & -c;
13666 /* It must be covered by the shift mask.
13667 This test also rejects c == 0. */
13668 if ((lsb & shift_mask) == 0)
13669 return 0;
13671 /* Check we have all 1's above the transition, and reject all 1's. */
13672 return c == -lsb && lsb != 1;
13674 else if (GET_CODE (andop) == CONST_DOUBLE
13675 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13677 HOST_WIDE_INT low, lsb, shift_mask_low;
13679 low = CONST_DOUBLE_LOW (andop);
13681 if (HOST_BITS_PER_WIDE_INT < 64)
13683 HOST_WIDE_INT high, shift_mask_high;
13685 high = CONST_DOUBLE_HIGH (andop);
13687 if (low == 0)
13689 shift_mask_high = ~0;
13690 if (INTVAL (shiftop) > 32)
13691 shift_mask_high <<= INTVAL (shiftop) - 32;
13693 lsb = high & -high;
13695 if ((lsb & shift_mask_high) == 0)
13696 return 0;
13698 return high == -lsb;
13700 if (high != ~0)
13701 return 0;
13704 shift_mask_low = ~0;
13705 shift_mask_low <<= INTVAL (shiftop);
13707 lsb = low & -low;
13709 if ((lsb & shift_mask_low) == 0)
13710 return 0;
13712 return low == -lsb && lsb != 1;
13714 else
13715 return 0;
13718 /* Return 1 if operands will generate a valid arguments to rlwimi
13719 instruction for insert with right shift in 64-bit mode. The mask may
13720 not start on the first bit or stop on the last bit because wrap-around
13721 effects of instruction do not correspond to semantics of RTL insn. */
13724 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13726 if (INTVAL (startop) > 32
13727 && INTVAL (startop) < 64
13728 && INTVAL (sizeop) > 1
13729 && INTVAL (sizeop) + INTVAL (startop) < 64
13730 && INTVAL (shiftop) > 0
13731 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13732 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13733 return 1;
13735 return 0;
13738 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13739 for lfq and stfq insns iff the registers are hard registers. */
13742 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13744 /* We might have been passed a SUBREG. */
13745 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13746 return 0;
13748 /* We might have been passed non floating point registers. */
13749 if (!FP_REGNO_P (REGNO (reg1))
13750 || !FP_REGNO_P (REGNO (reg2)))
13751 return 0;
13753 return (REGNO (reg1) == REGNO (reg2) - 1);
13756 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13757 addr1 and addr2 must be in consecutive memory locations
13758 (addr2 == addr1 + 8). */
13761 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13763 rtx addr1, addr2;
13764 unsigned int reg1, reg2;
13765 int offset1, offset2;
13767 /* The mems cannot be volatile. */
13768 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13769 return 0;
13771 addr1 = XEXP (mem1, 0);
13772 addr2 = XEXP (mem2, 0);
13774 /* Extract an offset (if used) from the first addr. */
13775 if (GET_CODE (addr1) == PLUS)
13777 /* If not a REG, return zero. */
13778 if (GET_CODE (XEXP (addr1, 0)) != REG)
13779 return 0;
13780 else
13782 reg1 = REGNO (XEXP (addr1, 0));
13783 /* The offset must be constant! */
13784 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13785 return 0;
13786 offset1 = INTVAL (XEXP (addr1, 1));
13789 else if (GET_CODE (addr1) != REG)
13790 return 0;
13791 else
13793 reg1 = REGNO (addr1);
13794 /* This was a simple (mem (reg)) expression. Offset is 0. */
13795 offset1 = 0;
13798 /* And now for the second addr. */
13799 if (GET_CODE (addr2) == PLUS)
13801 /* If not a REG, return zero. */
13802 if (GET_CODE (XEXP (addr2, 0)) != REG)
13803 return 0;
13804 else
13806 reg2 = REGNO (XEXP (addr2, 0));
13807 /* The offset must be constant. */
13808 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13809 return 0;
13810 offset2 = INTVAL (XEXP (addr2, 1));
13813 else if (GET_CODE (addr2) != REG)
13814 return 0;
13815 else
13817 reg2 = REGNO (addr2);
13818 /* This was a simple (mem (reg)) expression. Offset is 0. */
13819 offset2 = 0;
13822 /* Both of these must have the same base register. */
13823 if (reg1 != reg2)
13824 return 0;
13826 /* The offset for the second addr must be 8 more than the first addr. */
13827 if (offset2 != offset1 + 8)
13828 return 0;
13830 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13831 instructions. */
13832 return 1;
13837 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13839 static bool eliminated = false;
13840 rtx ret;
13842 if (mode != SDmode)
13843 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13844 else
13846 rtx mem = cfun->machine->sdmode_stack_slot;
13847 gcc_assert (mem != NULL_RTX);
13849 if (!eliminated)
13851 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13852 cfun->machine->sdmode_stack_slot = mem;
13853 eliminated = true;
13855 ret = mem;
13858 if (TARGET_DEBUG_ADDR)
13860 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13861 GET_MODE_NAME (mode));
13862 if (!ret)
13863 fprintf (stderr, "\tNULL_RTX\n");
13864 else
13865 debug_rtx (ret);
13868 return ret;
13871 static tree
13872 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13874 /* Don't walk into types. */
13875 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13877 *walk_subtrees = 0;
13878 return NULL_TREE;
13881 switch (TREE_CODE (*tp))
13883 case VAR_DECL:
13884 case PARM_DECL:
13885 case FIELD_DECL:
13886 case RESULT_DECL:
13887 case SSA_NAME:
13888 case REAL_CST:
13889 case MEM_REF:
13890 case MISALIGNED_INDIRECT_REF:
13891 case VIEW_CONVERT_EXPR:
13892 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13893 return *tp;
13894 break;
13895 default:
13896 break;
13899 return NULL_TREE;
13902 enum reload_reg_type {
13903 GPR_REGISTER_TYPE,
13904 VECTOR_REGISTER_TYPE,
13905 OTHER_REGISTER_TYPE
13908 static enum reload_reg_type
13909 rs6000_reload_register_type (enum reg_class rclass)
13911 switch (rclass)
13913 case GENERAL_REGS:
13914 case BASE_REGS:
13915 return GPR_REGISTER_TYPE;
13917 case FLOAT_REGS:
13918 case ALTIVEC_REGS:
13919 case VSX_REGS:
13920 return VECTOR_REGISTER_TYPE;
13922 default:
13923 return OTHER_REGISTER_TYPE;
13927 /* Inform reload about cases where moving X with a mode MODE to a register in
13928 RCLASS requires an extra scratch or immediate register. Return the class
13929 needed for the immediate register.
13931 For VSX and Altivec, we may need a register to convert sp+offset into
13932 reg+sp. */
13934 static reg_class_t
13935 rs6000_secondary_reload (bool in_p,
13936 rtx x,
13937 reg_class_t rclass_i,
13938 enum machine_mode mode,
13939 secondary_reload_info *sri)
13941 enum reg_class rclass = (enum reg_class) rclass_i;
13942 reg_class_t ret = ALL_REGS;
13943 enum insn_code icode;
13944 bool default_p = false;
13946 sri->icode = CODE_FOR_nothing;
13948 /* Convert vector loads and stores into gprs to use an additional base
13949 register. */
13950 icode = rs6000_vector_reload[mode][in_p != false];
13951 if (icode != CODE_FOR_nothing)
13953 ret = NO_REGS;
13954 sri->icode = CODE_FOR_nothing;
13955 sri->extra_cost = 0;
13957 if (GET_CODE (x) == MEM)
13959 rtx addr = XEXP (x, 0);
13961 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13962 an extra register in that case, but it would need an extra
13963 register if the addressing is reg+reg or (reg+reg)&(-16). */
13964 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13966 if (!legitimate_indirect_address_p (addr, false)
13967 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13969 sri->icode = icode;
13970 /* account for splitting the loads, and converting the
13971 address from reg+reg to reg. */
13972 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13973 + ((GET_CODE (addr) == AND) ? 1 : 0));
13976 /* Loads to and stores from vector registers can only do reg+reg
13977 addressing. Altivec registers can also do (reg+reg)&(-16). */
13978 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13979 || rclass == FLOAT_REGS || rclass == NO_REGS)
13981 if (!VECTOR_MEM_ALTIVEC_P (mode)
13982 && GET_CODE (addr) == AND
13983 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13984 && INTVAL (XEXP (addr, 1)) == -16
13985 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13986 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13988 sri->icode = icode;
13989 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13990 ? 2 : 1);
13992 else if (!legitimate_indirect_address_p (addr, false)
13993 && (rclass == NO_REGS
13994 || !legitimate_indexed_address_p (addr, false)))
13996 sri->icode = icode;
13997 sri->extra_cost = 1;
13999 else
14000 icode = CODE_FOR_nothing;
14002 /* Any other loads, including to pseudo registers which haven't been
14003 assigned to a register yet, default to require a scratch
14004 register. */
14005 else
14007 sri->icode = icode;
14008 sri->extra_cost = 2;
14011 else if (REG_P (x))
14013 int regno = true_regnum (x);
14015 icode = CODE_FOR_nothing;
14016 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14017 default_p = true;
14018 else
14020 enum reg_class xclass = REGNO_REG_CLASS (regno);
14021 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14022 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14024 /* If memory is needed, use default_secondary_reload to create the
14025 stack slot. */
14026 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14027 default_p = true;
14028 else
14029 ret = NO_REGS;
14032 else
14033 default_p = true;
14035 else
14036 default_p = true;
14038 if (default_p)
14039 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14041 gcc_assert (ret != ALL_REGS);
14043 if (TARGET_DEBUG_ADDR)
14045 fprintf (stderr,
14046 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14047 "mode = %s",
14048 reg_class_names[ret],
14049 in_p ? "true" : "false",
14050 reg_class_names[rclass],
14051 GET_MODE_NAME (mode));
14053 if (default_p)
14054 fprintf (stderr, ", default secondary reload");
14056 if (sri->icode != CODE_FOR_nothing)
14057 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14058 insn_data[sri->icode].name, sri->extra_cost);
14059 else
14060 fprintf (stderr, "\n");
14062 debug_rtx (x);
14065 return ret;
14068 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14069 to SP+reg addressing. */
14071 void
14072 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14074 int regno = true_regnum (reg);
14075 enum machine_mode mode = GET_MODE (reg);
14076 enum reg_class rclass;
14077 rtx addr;
14078 rtx and_op2 = NULL_RTX;
14079 rtx addr_op1;
14080 rtx addr_op2;
14081 rtx scratch_or_premodify = scratch;
14082 rtx and_rtx;
14083 rtx cc_clobber;
14085 if (TARGET_DEBUG_ADDR)
14087 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14088 store_p ? "store" : "load");
14089 fprintf (stderr, "reg:\n");
14090 debug_rtx (reg);
14091 fprintf (stderr, "mem:\n");
14092 debug_rtx (mem);
14093 fprintf (stderr, "scratch:\n");
14094 debug_rtx (scratch);
14097 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14098 gcc_assert (GET_CODE (mem) == MEM);
14099 rclass = REGNO_REG_CLASS (regno);
14100 addr = XEXP (mem, 0);
14102 switch (rclass)
14104 /* GPRs can handle reg + small constant, all other addresses need to use
14105 the scratch register. */
14106 case GENERAL_REGS:
14107 case BASE_REGS:
14108 if (GET_CODE (addr) == AND)
14110 and_op2 = XEXP (addr, 1);
14111 addr = XEXP (addr, 0);
14114 if (GET_CODE (addr) == PRE_MODIFY)
14116 scratch_or_premodify = XEXP (addr, 0);
14117 gcc_assert (REG_P (scratch_or_premodify));
14118 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14119 addr = XEXP (addr, 1);
14122 if (GET_CODE (addr) == PLUS
14123 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14124 || and_op2 != NULL_RTX))
14126 addr_op1 = XEXP (addr, 0);
14127 addr_op2 = XEXP (addr, 1);
14128 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14130 if (!REG_P (addr_op2)
14131 && (GET_CODE (addr_op2) != CONST_INT
14132 || !satisfies_constraint_I (addr_op2)))
14134 if (TARGET_DEBUG_ADDR)
14136 fprintf (stderr,
14137 "\nMove plus addr to register %s, mode = %s: ",
14138 rs6000_reg_names[REGNO (scratch)],
14139 GET_MODE_NAME (mode));
14140 debug_rtx (addr_op2);
14142 rs6000_emit_move (scratch, addr_op2, Pmode);
14143 addr_op2 = scratch;
14146 emit_insn (gen_rtx_SET (VOIDmode,
14147 scratch_or_premodify,
14148 gen_rtx_PLUS (Pmode,
14149 addr_op1,
14150 addr_op2)));
14152 addr = scratch_or_premodify;
14153 scratch_or_premodify = scratch;
14155 else if (!legitimate_indirect_address_p (addr, false)
14156 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14158 if (TARGET_DEBUG_ADDR)
14160 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14161 rs6000_reg_names[REGNO (scratch_or_premodify)],
14162 GET_MODE_NAME (mode));
14163 debug_rtx (addr);
14165 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14166 addr = scratch_or_premodify;
14167 scratch_or_premodify = scratch;
14169 break;
14171 /* Float/Altivec registers can only handle reg+reg addressing. Move
14172 other addresses into a scratch register. */
14173 case FLOAT_REGS:
14174 case VSX_REGS:
14175 case ALTIVEC_REGS:
14177 /* With float regs, we need to handle the AND ourselves, since we can't
14178 use the Altivec instruction with an implicit AND -16. Allow scalar
14179 loads to float registers to use reg+offset even if VSX. */
14180 if (GET_CODE (addr) == AND
14181 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14182 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14183 || INTVAL (XEXP (addr, 1)) != -16
14184 || !VECTOR_MEM_ALTIVEC_P (mode)))
14186 and_op2 = XEXP (addr, 1);
14187 addr = XEXP (addr, 0);
14190 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14191 as the address later. */
14192 if (GET_CODE (addr) == PRE_MODIFY
14193 && (!VECTOR_MEM_VSX_P (mode)
14194 || and_op2 != NULL_RTX
14195 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14197 scratch_or_premodify = XEXP (addr, 0);
14198 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14199 false));
14200 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14201 addr = XEXP (addr, 1);
14204 if (legitimate_indirect_address_p (addr, false) /* reg */
14205 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14206 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14207 || (GET_CODE (addr) == AND /* Altivec memory */
14208 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14209 && INTVAL (XEXP (addr, 1)) == -16
14210 && VECTOR_MEM_ALTIVEC_P (mode))
14211 || (rclass == FLOAT_REGS /* legacy float mem */
14212 && GET_MODE_SIZE (mode) == 8
14213 && and_op2 == NULL_RTX
14214 && scratch_or_premodify == scratch
14215 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14218 else if (GET_CODE (addr) == PLUS)
14220 addr_op1 = XEXP (addr, 0);
14221 addr_op2 = XEXP (addr, 1);
14222 gcc_assert (REG_P (addr_op1));
14224 if (TARGET_DEBUG_ADDR)
14226 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14227 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14228 debug_rtx (addr_op2);
14230 rs6000_emit_move (scratch, addr_op2, Pmode);
14231 emit_insn (gen_rtx_SET (VOIDmode,
14232 scratch_or_premodify,
14233 gen_rtx_PLUS (Pmode,
14234 addr_op1,
14235 scratch)));
14236 addr = scratch_or_premodify;
14237 scratch_or_premodify = scratch;
14240 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14241 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14243 if (TARGET_DEBUG_ADDR)
14245 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14246 rs6000_reg_names[REGNO (scratch_or_premodify)],
14247 GET_MODE_NAME (mode));
14248 debug_rtx (addr);
14251 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14252 addr = scratch_or_premodify;
14253 scratch_or_premodify = scratch;
14256 else
14257 gcc_unreachable ();
14259 break;
14261 default:
14262 gcc_unreachable ();
14265 /* If the original address involved a pre-modify that we couldn't use the VSX
14266 memory instruction with update, and we haven't taken care of already,
14267 store the address in the pre-modify register and use that as the
14268 address. */
14269 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14271 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14272 addr = scratch_or_premodify;
14275 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14276 memory instruction, recreate the AND now, including the clobber which is
14277 generated by the general ANDSI3/ANDDI3 patterns for the
14278 andi. instruction. */
14279 if (and_op2 != NULL_RTX)
14281 if (! legitimate_indirect_address_p (addr, false))
14283 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14284 addr = scratch;
14287 if (TARGET_DEBUG_ADDR)
14289 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14290 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14291 debug_rtx (and_op2);
14294 and_rtx = gen_rtx_SET (VOIDmode,
14295 scratch,
14296 gen_rtx_AND (Pmode,
14297 addr,
14298 and_op2));
14300 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14301 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14302 gen_rtvec (2, and_rtx, cc_clobber)));
14303 addr = scratch;
14306 /* Adjust the address if it changed. */
14307 if (addr != XEXP (mem, 0))
14309 mem = change_address (mem, mode, addr);
14310 if (TARGET_DEBUG_ADDR)
14311 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14314 /* Now create the move. */
14315 if (store_p)
14316 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14317 else
14318 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14320 return;
14323 /* Target hook to return the cover classes for Integrated Register Allocator.
14324 Cover classes is a set of non-intersected register classes covering all hard
14325 registers used for register allocation purpose. Any move between two
14326 registers of a cover class should be cheaper than load or store of the
14327 registers. The value is array of register classes with LIM_REG_CLASSES used
14328 as the end marker.
14330 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14331 account for the Altivec and Floating registers being subsets of the VSX
14332 register set under VSX, but distinct register sets on pre-VSX machines. */
14334 static const reg_class_t *
14335 rs6000_ira_cover_classes (void)
14337 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14338 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14340 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14343 /* Allocate a 64-bit stack slot to be used for copying SDmode
14344 values through if this function has any SDmode references. */
14346 static void
14347 rs6000_alloc_sdmode_stack_slot (void)
14349 tree t;
14350 basic_block bb;
14351 gimple_stmt_iterator gsi;
14353 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14355 FOR_EACH_BB (bb)
14356 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14358 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14359 if (ret)
14361 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14362 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14363 SDmode, 0);
14364 return;
14368 /* Check for any SDmode parameters of the function. */
14369 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14371 if (TREE_TYPE (t) == error_mark_node)
14372 continue;
14374 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14375 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14377 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14378 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14379 SDmode, 0);
14380 return;
14385 static void
14386 rs6000_instantiate_decls (void)
14388 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14389 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14392 /* Given an rtx X being reloaded into a reg required to be
14393 in class CLASS, return the class of reg to actually use.
14394 In general this is just CLASS; but on some machines
14395 in some cases it is preferable to use a more restrictive class.
14397 On the RS/6000, we have to return NO_REGS when we want to reload a
14398 floating-point CONST_DOUBLE to force it to be copied to memory.
14400 We also don't want to reload integer values into floating-point
14401 registers if we can at all help it. In fact, this can
14402 cause reload to die, if it tries to generate a reload of CTR
14403 into a FP register and discovers it doesn't have the memory location
14404 required.
14406 ??? Would it be a good idea to have reload do the converse, that is
14407 try to reload floating modes into FP registers if possible?
14410 static enum reg_class
14411 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14413 enum machine_mode mode = GET_MODE (x);
14415 if (VECTOR_UNIT_VSX_P (mode)
14416 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14417 return rclass;
14419 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14420 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14421 && easy_vector_constant (x, mode))
14422 return ALTIVEC_REGS;
14424 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14425 return NO_REGS;
14427 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14428 return GENERAL_REGS;
14430 /* For VSX, prefer the traditional registers for 64-bit values because we can
14431 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14432 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14433 prefer Altivec loads.. */
14434 if (rclass == VSX_REGS)
14436 if (GET_MODE_SIZE (mode) <= 8)
14437 return FLOAT_REGS;
14439 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14440 return ALTIVEC_REGS;
14442 return rclass;
14445 return rclass;
14448 /* Debug version of rs6000_preferred_reload_class. */
14449 static enum reg_class
14450 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14452 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14454 fprintf (stderr,
14455 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14456 "mode = %s, x:\n",
14457 reg_class_names[ret], reg_class_names[rclass],
14458 GET_MODE_NAME (GET_MODE (x)));
14459 debug_rtx (x);
14461 return ret;
14464 /* If we are copying between FP or AltiVec registers and anything else, we need
14465 a memory location. The exception is when we are targeting ppc64 and the
14466 move to/from fpr to gpr instructions are available. Also, under VSX, you
14467 can copy vector registers from the FP register set to the Altivec register
14468 set and vice versa. */
14470 static bool
14471 rs6000_secondary_memory_needed (enum reg_class class1,
14472 enum reg_class class2,
14473 enum machine_mode mode)
14475 if (class1 == class2)
14476 return false;
14478 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14479 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14480 between these classes. But we need memory for other things that can go in
14481 FLOAT_REGS like SFmode. */
14482 if (TARGET_VSX
14483 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14484 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14485 || class1 == FLOAT_REGS))
14486 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14487 && class2 != FLOAT_REGS);
14489 if (class1 == VSX_REGS || class2 == VSX_REGS)
14490 return true;
14492 if (class1 == FLOAT_REGS
14493 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14494 || ((mode != DFmode)
14495 && (mode != DDmode)
14496 && (mode != DImode))))
14497 return true;
14499 if (class2 == FLOAT_REGS
14500 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14501 || ((mode != DFmode)
14502 && (mode != DDmode)
14503 && (mode != DImode))))
14504 return true;
14506 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14507 return true;
14509 return false;
14512 /* Debug version of rs6000_secondary_memory_needed. */
14513 static bool
14514 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14515 enum reg_class class2,
14516 enum machine_mode mode)
14518 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14520 fprintf (stderr,
14521 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14522 "class2 = %s, mode = %s\n",
14523 ret ? "true" : "false", reg_class_names[class1],
14524 reg_class_names[class2], GET_MODE_NAME (mode));
14526 return ret;
14529 /* Return the register class of a scratch register needed to copy IN into
14530 or out of a register in RCLASS in MODE. If it can be done directly,
14531 NO_REGS is returned. */
14533 static enum reg_class
14534 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14535 rtx in)
14537 int regno;
14539 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14540 #if TARGET_MACHO
14541 && MACHOPIC_INDIRECT
14542 #endif
14545 /* We cannot copy a symbolic operand directly into anything
14546 other than BASE_REGS for TARGET_ELF. So indicate that a
14547 register from BASE_REGS is needed as an intermediate
14548 register.
14550 On Darwin, pic addresses require a load from memory, which
14551 needs a base register. */
14552 if (rclass != BASE_REGS
14553 && (GET_CODE (in) == SYMBOL_REF
14554 || GET_CODE (in) == HIGH
14555 || GET_CODE (in) == LABEL_REF
14556 || GET_CODE (in) == CONST))
14557 return BASE_REGS;
14560 if (GET_CODE (in) == REG)
14562 regno = REGNO (in);
14563 if (regno >= FIRST_PSEUDO_REGISTER)
14565 regno = true_regnum (in);
14566 if (regno >= FIRST_PSEUDO_REGISTER)
14567 regno = -1;
14570 else if (GET_CODE (in) == SUBREG)
14572 regno = true_regnum (in);
14573 if (regno >= FIRST_PSEUDO_REGISTER)
14574 regno = -1;
14576 else
14577 regno = -1;
14579 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14580 into anything. */
14581 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14582 || (regno >= 0 && INT_REGNO_P (regno)))
14583 return NO_REGS;
14585 /* Constants, memory, and FP registers can go into FP registers. */
14586 if ((regno == -1 || FP_REGNO_P (regno))
14587 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14588 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14590 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14591 VSX. */
14592 if (TARGET_VSX
14593 && (regno == -1 || VSX_REGNO_P (regno))
14594 && VSX_REG_CLASS_P (rclass))
14595 return NO_REGS;
14597 /* Memory, and AltiVec registers can go into AltiVec registers. */
14598 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14599 && rclass == ALTIVEC_REGS)
14600 return NO_REGS;
14602 /* We can copy among the CR registers. */
14603 if ((rclass == CR_REGS || rclass == CR0_REGS)
14604 && regno >= 0 && CR_REGNO_P (regno))
14605 return NO_REGS;
14607 /* Otherwise, we need GENERAL_REGS. */
14608 return GENERAL_REGS;
14611 /* Debug version of rs6000_secondary_reload_class. */
14612 static enum reg_class
14613 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14614 enum machine_mode mode, rtx in)
14616 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14617 fprintf (stderr,
14618 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14619 "mode = %s, input rtx:\n",
14620 reg_class_names[ret], reg_class_names[rclass],
14621 GET_MODE_NAME (mode));
14622 debug_rtx (in);
14624 return ret;
14627 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14629 static bool
14630 rs6000_cannot_change_mode_class (enum machine_mode from,
14631 enum machine_mode to,
14632 enum reg_class rclass)
14634 unsigned from_size = GET_MODE_SIZE (from);
14635 unsigned to_size = GET_MODE_SIZE (to);
14637 if (from_size != to_size)
14639 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14640 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14641 && reg_classes_intersect_p (xclass, rclass));
14644 if (TARGET_E500_DOUBLE
14645 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14646 || (((to) == TFmode) + ((from) == TFmode)) == 1
14647 || (((to) == DDmode) + ((from) == DDmode)) == 1
14648 || (((to) == TDmode) + ((from) == TDmode)) == 1
14649 || (((to) == DImode) + ((from) == DImode)) == 1))
14650 return true;
14652 /* Since the VSX register set includes traditional floating point registers
14653 and altivec registers, just check for the size being different instead of
14654 trying to check whether the modes are vector modes. Otherwise it won't
14655 allow say DF and DI to change classes. */
14656 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14657 return (from_size != 8 && from_size != 16);
14659 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14660 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14661 return true;
14663 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14664 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14665 return true;
14667 return false;
14670 /* Debug version of rs6000_cannot_change_mode_class. */
14671 static bool
14672 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14673 enum machine_mode to,
14674 enum reg_class rclass)
14676 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14678 fprintf (stderr,
14679 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14680 "to = %s, rclass = %s\n",
14681 ret ? "true" : "false",
14682 GET_MODE_NAME (from), GET_MODE_NAME (to),
14683 reg_class_names[rclass]);
14685 return ret;
14688 /* Given a comparison operation, return the bit number in CCR to test. We
14689 know this is a valid comparison.
14691 SCC_P is 1 if this is for an scc. That means that %D will have been
14692 used instead of %C, so the bits will be in different places.
14694 Return -1 if OP isn't a valid comparison for some reason. */
14697 ccr_bit (rtx op, int scc_p)
14699 enum rtx_code code = GET_CODE (op);
14700 enum machine_mode cc_mode;
14701 int cc_regnum;
14702 int base_bit;
14703 rtx reg;
14705 if (!COMPARISON_P (op))
14706 return -1;
14708 reg = XEXP (op, 0);
14710 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14712 cc_mode = GET_MODE (reg);
14713 cc_regnum = REGNO (reg);
14714 base_bit = 4 * (cc_regnum - CR0_REGNO);
14716 validate_condition_mode (code, cc_mode);
14718 /* When generating a sCOND operation, only positive conditions are
14719 allowed. */
14720 gcc_assert (!scc_p
14721 || code == EQ || code == GT || code == LT || code == UNORDERED
14722 || code == GTU || code == LTU);
14724 switch (code)
14726 case NE:
14727 return scc_p ? base_bit + 3 : base_bit + 2;
14728 case EQ:
14729 return base_bit + 2;
14730 case GT: case GTU: case UNLE:
14731 return base_bit + 1;
14732 case LT: case LTU: case UNGE:
14733 return base_bit;
14734 case ORDERED: case UNORDERED:
14735 return base_bit + 3;
14737 case GE: case GEU:
14738 /* If scc, we will have done a cror to put the bit in the
14739 unordered position. So test that bit. For integer, this is ! LT
14740 unless this is an scc insn. */
14741 return scc_p ? base_bit + 3 : base_bit;
14743 case LE: case LEU:
14744 return scc_p ? base_bit + 3 : base_bit + 1;
14746 default:
14747 gcc_unreachable ();
14751 /* Return the GOT register. */
14754 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14756 /* The second flow pass currently (June 1999) can't update
14757 regs_ever_live without disturbing other parts of the compiler, so
14758 update it here to make the prolog/epilogue code happy. */
14759 if (!can_create_pseudo_p ()
14760 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14761 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14763 crtl->uses_pic_offset_table = 1;
14765 return pic_offset_table_rtx;
14768 /* Function to init struct machine_function.
14769 This will be called, via a pointer variable,
14770 from push_function_context. */
14772 static struct machine_function *
14773 rs6000_init_machine_status (void)
14775 return ggc_alloc_cleared_machine_function ();
14778 /* These macros test for integers and extract the low-order bits. */
14779 #define INT_P(X) \
14780 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14781 && GET_MODE (X) == VOIDmode)
14783 #define INT_LOWPART(X) \
14784 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14787 extract_MB (rtx op)
14789 int i;
14790 unsigned long val = INT_LOWPART (op);
14792 /* If the high bit is zero, the value is the first 1 bit we find
14793 from the left. */
14794 if ((val & 0x80000000) == 0)
14796 gcc_assert (val & 0xffffffff);
14798 i = 1;
14799 while (((val <<= 1) & 0x80000000) == 0)
14800 ++i;
14801 return i;
14804 /* If the high bit is set and the low bit is not, or the mask is all
14805 1's, the value is zero. */
14806 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14807 return 0;
14809 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14810 from the right. */
14811 i = 31;
14812 while (((val >>= 1) & 1) != 0)
14813 --i;
14815 return i;
14819 extract_ME (rtx op)
14821 int i;
14822 unsigned long val = INT_LOWPART (op);
14824 /* If the low bit is zero, the value is the first 1 bit we find from
14825 the right. */
14826 if ((val & 1) == 0)
14828 gcc_assert (val & 0xffffffff);
14830 i = 30;
14831 while (((val >>= 1) & 1) == 0)
14832 --i;
14834 return i;
14837 /* If the low bit is set and the high bit is not, or the mask is all
14838 1's, the value is 31. */
14839 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14840 return 31;
14842 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14843 from the left. */
14844 i = 0;
14845 while (((val <<= 1) & 0x80000000) != 0)
14846 ++i;
14848 return i;
14851 /* Locate some local-dynamic symbol still in use by this function
14852 so that we can print its name in some tls_ld pattern. */
14854 static const char *
14855 rs6000_get_some_local_dynamic_name (void)
14857 rtx insn;
14859 if (cfun->machine->some_ld_name)
14860 return cfun->machine->some_ld_name;
14862 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14863 if (INSN_P (insn)
14864 && for_each_rtx (&PATTERN (insn),
14865 rs6000_get_some_local_dynamic_name_1, 0))
14866 return cfun->machine->some_ld_name;
14868 gcc_unreachable ();
14871 /* Helper function for rs6000_get_some_local_dynamic_name. */
14873 static int
14874 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14876 rtx x = *px;
14878 if (GET_CODE (x) == SYMBOL_REF)
14880 const char *str = XSTR (x, 0);
14881 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14883 cfun->machine->some_ld_name = str;
14884 return 1;
14888 return 0;
14891 /* Write out a function code label. */
14893 void
14894 rs6000_output_function_entry (FILE *file, const char *fname)
14896 if (fname[0] != '.')
14898 switch (DEFAULT_ABI)
14900 default:
14901 gcc_unreachable ();
14903 case ABI_AIX:
14904 if (DOT_SYMBOLS)
14905 putc ('.', file);
14906 else
14907 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14908 break;
14910 case ABI_V4:
14911 case ABI_DARWIN:
14912 break;
14916 RS6000_OUTPUT_BASENAME (file, fname);
14919 /* Print an operand. Recognize special options, documented below. */
14921 #if TARGET_ELF
14922 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14923 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14924 #else
14925 #define SMALL_DATA_RELOC "sda21"
14926 #define SMALL_DATA_REG 0
14927 #endif
14929 void
14930 print_operand (FILE *file, rtx x, int code)
14932 int i;
14933 HOST_WIDE_INT val;
14934 unsigned HOST_WIDE_INT uval;
14936 switch (code)
14938 case '.':
14939 /* Write out an instruction after the call which may be replaced
14940 with glue code by the loader. This depends on the AIX version. */
14941 asm_fprintf (file, RS6000_CALL_GLUE);
14942 return;
14944 /* %a is output_address. */
14946 case 'A':
14947 /* If X is a constant integer whose low-order 5 bits are zero,
14948 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14949 in the AIX assembler where "sri" with a zero shift count
14950 writes a trash instruction. */
14951 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14952 putc ('l', file);
14953 else
14954 putc ('r', file);
14955 return;
14957 case 'b':
14958 /* If constant, low-order 16 bits of constant, unsigned.
14959 Otherwise, write normally. */
14960 if (INT_P (x))
14961 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14962 else
14963 print_operand (file, x, 0);
14964 return;
14966 case 'B':
14967 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14968 for 64-bit mask direction. */
14969 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14970 return;
14972 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14973 output_operand. */
14975 case 'c':
14976 /* X is a CR register. Print the number of the GT bit of the CR. */
14977 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14978 output_operand_lossage ("invalid %%c value");
14979 else
14980 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14981 return;
14983 case 'D':
14984 /* Like 'J' but get to the GT bit only. */
14985 gcc_assert (GET_CODE (x) == REG);
14987 /* Bit 1 is GT bit. */
14988 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14990 /* Add one for shift count in rlinm for scc. */
14991 fprintf (file, "%d", i + 1);
14992 return;
14994 case 'E':
14995 /* X is a CR register. Print the number of the EQ bit of the CR */
14996 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14997 output_operand_lossage ("invalid %%E value");
14998 else
14999 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15000 return;
15002 case 'f':
15003 /* X is a CR register. Print the shift count needed to move it
15004 to the high-order four bits. */
15005 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15006 output_operand_lossage ("invalid %%f value");
15007 else
15008 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15009 return;
15011 case 'F':
15012 /* Similar, but print the count for the rotate in the opposite
15013 direction. */
15014 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15015 output_operand_lossage ("invalid %%F value");
15016 else
15017 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15018 return;
15020 case 'G':
15021 /* X is a constant integer. If it is negative, print "m",
15022 otherwise print "z". This is to make an aze or ame insn. */
15023 if (GET_CODE (x) != CONST_INT)
15024 output_operand_lossage ("invalid %%G value");
15025 else if (INTVAL (x) >= 0)
15026 putc ('z', file);
15027 else
15028 putc ('m', file);
15029 return;
15031 case 'h':
15032 /* If constant, output low-order five bits. Otherwise, write
15033 normally. */
15034 if (INT_P (x))
15035 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15036 else
15037 print_operand (file, x, 0);
15038 return;
15040 case 'H':
15041 /* If constant, output low-order six bits. Otherwise, write
15042 normally. */
15043 if (INT_P (x))
15044 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15045 else
15046 print_operand (file, x, 0);
15047 return;
15049 case 'I':
15050 /* Print `i' if this is a constant, else nothing. */
15051 if (INT_P (x))
15052 putc ('i', file);
15053 return;
15055 case 'j':
15056 /* Write the bit number in CCR for jump. */
15057 i = ccr_bit (x, 0);
15058 if (i == -1)
15059 output_operand_lossage ("invalid %%j code");
15060 else
15061 fprintf (file, "%d", i);
15062 return;
15064 case 'J':
15065 /* Similar, but add one for shift count in rlinm for scc and pass
15066 scc flag to `ccr_bit'. */
15067 i = ccr_bit (x, 1);
15068 if (i == -1)
15069 output_operand_lossage ("invalid %%J code");
15070 else
15071 /* If we want bit 31, write a shift count of zero, not 32. */
15072 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15073 return;
15075 case 'k':
15076 /* X must be a constant. Write the 1's complement of the
15077 constant. */
15078 if (! INT_P (x))
15079 output_operand_lossage ("invalid %%k value");
15080 else
15081 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15082 return;
15084 case 'K':
15085 /* X must be a symbolic constant on ELF. Write an
15086 expression suitable for an 'addi' that adds in the low 16
15087 bits of the MEM. */
15088 if (GET_CODE (x) == CONST)
15090 if (GET_CODE (XEXP (x, 0)) != PLUS
15091 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15092 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15093 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15094 output_operand_lossage ("invalid %%K value");
15096 print_operand_address (file, x);
15097 fputs ("@l", file);
15098 return;
15100 /* %l is output_asm_label. */
15102 case 'L':
15103 /* Write second word of DImode or DFmode reference. Works on register
15104 or non-indexed memory only. */
15105 if (GET_CODE (x) == REG)
15106 fputs (reg_names[REGNO (x) + 1], file);
15107 else if (GET_CODE (x) == MEM)
15109 /* Handle possible auto-increment. Since it is pre-increment and
15110 we have already done it, we can just use an offset of word. */
15111 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15112 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15113 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15114 UNITS_PER_WORD));
15115 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15116 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15117 UNITS_PER_WORD));
15118 else
15119 output_address (XEXP (adjust_address_nv (x, SImode,
15120 UNITS_PER_WORD),
15121 0));
15123 if (small_data_operand (x, GET_MODE (x)))
15124 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15125 reg_names[SMALL_DATA_REG]);
15127 return;
15129 case 'm':
15130 /* MB value for a mask operand. */
15131 if (! mask_operand (x, SImode))
15132 output_operand_lossage ("invalid %%m value");
15134 fprintf (file, "%d", extract_MB (x));
15135 return;
15137 case 'M':
15138 /* ME value for a mask operand. */
15139 if (! mask_operand (x, SImode))
15140 output_operand_lossage ("invalid %%M value");
15142 fprintf (file, "%d", extract_ME (x));
15143 return;
15145 /* %n outputs the negative of its operand. */
15147 case 'N':
15148 /* Write the number of elements in the vector times 4. */
15149 if (GET_CODE (x) != PARALLEL)
15150 output_operand_lossage ("invalid %%N value");
15151 else
15152 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15153 return;
15155 case 'O':
15156 /* Similar, but subtract 1 first. */
15157 if (GET_CODE (x) != PARALLEL)
15158 output_operand_lossage ("invalid %%O value");
15159 else
15160 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15161 return;
15163 case 'p':
15164 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15165 if (! INT_P (x)
15166 || INT_LOWPART (x) < 0
15167 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15168 output_operand_lossage ("invalid %%p value");
15169 else
15170 fprintf (file, "%d", i);
15171 return;
15173 case 'P':
15174 /* The operand must be an indirect memory reference. The result
15175 is the register name. */
15176 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15177 || REGNO (XEXP (x, 0)) >= 32)
15178 output_operand_lossage ("invalid %%P value");
15179 else
15180 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15181 return;
15183 case 'q':
15184 /* This outputs the logical code corresponding to a boolean
15185 expression. The expression may have one or both operands
15186 negated (if one, only the first one). For condition register
15187 logical operations, it will also treat the negated
15188 CR codes as NOTs, but not handle NOTs of them. */
15190 const char *const *t = 0;
15191 const char *s;
15192 enum rtx_code code = GET_CODE (x);
15193 static const char * const tbl[3][3] = {
15194 { "and", "andc", "nor" },
15195 { "or", "orc", "nand" },
15196 { "xor", "eqv", "xor" } };
15198 if (code == AND)
15199 t = tbl[0];
15200 else if (code == IOR)
15201 t = tbl[1];
15202 else if (code == XOR)
15203 t = tbl[2];
15204 else
15205 output_operand_lossage ("invalid %%q value");
15207 if (GET_CODE (XEXP (x, 0)) != NOT)
15208 s = t[0];
15209 else
15211 if (GET_CODE (XEXP (x, 1)) == NOT)
15212 s = t[2];
15213 else
15214 s = t[1];
15217 fputs (s, file);
15219 return;
15221 case 'Q':
15222 if (TARGET_MFCRF)
15223 fputc (',', file);
15224 /* FALLTHRU */
15225 else
15226 return;
15228 case 'R':
15229 /* X is a CR register. Print the mask for `mtcrf'. */
15230 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15231 output_operand_lossage ("invalid %%R value");
15232 else
15233 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15234 return;
15236 case 's':
15237 /* Low 5 bits of 32 - value */
15238 if (! INT_P (x))
15239 output_operand_lossage ("invalid %%s value");
15240 else
15241 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15242 return;
15244 case 'S':
15245 /* PowerPC64 mask position. All 0's is excluded.
15246 CONST_INT 32-bit mask is considered sign-extended so any
15247 transition must occur within the CONST_INT, not on the boundary. */
15248 if (! mask64_operand (x, DImode))
15249 output_operand_lossage ("invalid %%S value");
15251 uval = INT_LOWPART (x);
15253 if (uval & 1) /* Clear Left */
15255 #if HOST_BITS_PER_WIDE_INT > 64
15256 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15257 #endif
15258 i = 64;
15260 else /* Clear Right */
15262 uval = ~uval;
15263 #if HOST_BITS_PER_WIDE_INT > 64
15264 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15265 #endif
15266 i = 63;
15268 while (uval != 0)
15269 --i, uval >>= 1;
15270 gcc_assert (i >= 0);
15271 fprintf (file, "%d", i);
15272 return;
15274 case 't':
15275 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15276 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15278 /* Bit 3 is OV bit. */
15279 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15281 /* If we want bit 31, write a shift count of zero, not 32. */
15282 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15283 return;
15285 case 'T':
15286 /* Print the symbolic name of a branch target register. */
15287 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15288 && REGNO (x) != CTR_REGNO))
15289 output_operand_lossage ("invalid %%T value");
15290 else if (REGNO (x) == LR_REGNO)
15291 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15292 else
15293 fputs ("ctr", file);
15294 return;
15296 case 'u':
15297 /* High-order 16 bits of constant for use in unsigned operand. */
15298 if (! INT_P (x))
15299 output_operand_lossage ("invalid %%u value");
15300 else
15301 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15302 (INT_LOWPART (x) >> 16) & 0xffff);
15303 return;
15305 case 'v':
15306 /* High-order 16 bits of constant for use in signed operand. */
15307 if (! INT_P (x))
15308 output_operand_lossage ("invalid %%v value");
15309 else
15310 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15311 (INT_LOWPART (x) >> 16) & 0xffff);
15312 return;
15314 case 'U':
15315 /* Print `u' if this has an auto-increment or auto-decrement. */
15316 if (GET_CODE (x) == MEM
15317 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15318 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15319 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15320 putc ('u', file);
15321 return;
15323 case 'V':
15324 /* Print the trap code for this operand. */
15325 switch (GET_CODE (x))
15327 case EQ:
15328 fputs ("eq", file); /* 4 */
15329 break;
15330 case NE:
15331 fputs ("ne", file); /* 24 */
15332 break;
15333 case LT:
15334 fputs ("lt", file); /* 16 */
15335 break;
15336 case LE:
15337 fputs ("le", file); /* 20 */
15338 break;
15339 case GT:
15340 fputs ("gt", file); /* 8 */
15341 break;
15342 case GE:
15343 fputs ("ge", file); /* 12 */
15344 break;
15345 case LTU:
15346 fputs ("llt", file); /* 2 */
15347 break;
15348 case LEU:
15349 fputs ("lle", file); /* 6 */
15350 break;
15351 case GTU:
15352 fputs ("lgt", file); /* 1 */
15353 break;
15354 case GEU:
15355 fputs ("lge", file); /* 5 */
15356 break;
15357 default:
15358 gcc_unreachable ();
15360 break;
15362 case 'w':
15363 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15364 normally. */
15365 if (INT_P (x))
15366 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15367 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15368 else
15369 print_operand (file, x, 0);
15370 return;
15372 case 'W':
15373 /* MB value for a PowerPC64 rldic operand. */
15374 val = (GET_CODE (x) == CONST_INT
15375 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15377 if (val < 0)
15378 i = -1;
15379 else
15380 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15381 if ((val <<= 1) < 0)
15382 break;
15384 #if HOST_BITS_PER_WIDE_INT == 32
15385 if (GET_CODE (x) == CONST_INT && i >= 0)
15386 i += 32; /* zero-extend high-part was all 0's */
15387 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15389 val = CONST_DOUBLE_LOW (x);
15391 gcc_assert (val);
15392 if (val < 0)
15393 --i;
15394 else
15395 for ( ; i < 64; i++)
15396 if ((val <<= 1) < 0)
15397 break;
15399 #endif
15401 fprintf (file, "%d", i + 1);
15402 return;
15404 case 'x':
15405 /* X is a FPR or Altivec register used in a VSX context. */
15406 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15407 output_operand_lossage ("invalid %%x value");
15408 else
15410 int reg = REGNO (x);
15411 int vsx_reg = (FP_REGNO_P (reg)
15412 ? reg - 32
15413 : reg - FIRST_ALTIVEC_REGNO + 32);
15415 #ifdef TARGET_REGNAMES
15416 if (TARGET_REGNAMES)
15417 fprintf (file, "%%vs%d", vsx_reg);
15418 else
15419 #endif
15420 fprintf (file, "%d", vsx_reg);
15422 return;
15424 case 'X':
15425 if (GET_CODE (x) == MEM
15426 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15427 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15428 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15429 putc ('x', file);
15430 return;
15432 case 'Y':
15433 /* Like 'L', for third word of TImode */
15434 if (GET_CODE (x) == REG)
15435 fputs (reg_names[REGNO (x) + 2], file);
15436 else if (GET_CODE (x) == MEM)
15438 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15439 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15440 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15441 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15442 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15443 else
15444 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15445 if (small_data_operand (x, GET_MODE (x)))
15446 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15447 reg_names[SMALL_DATA_REG]);
15449 return;
15451 case 'z':
15452 /* X is a SYMBOL_REF. Write out the name preceded by a
15453 period and without any trailing data in brackets. Used for function
15454 names. If we are configured for System V (or the embedded ABI) on
15455 the PowerPC, do not emit the period, since those systems do not use
15456 TOCs and the like. */
15457 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15459 /* Mark the decl as referenced so that cgraph will output the
15460 function. */
15461 if (SYMBOL_REF_DECL (x))
15462 mark_decl_referenced (SYMBOL_REF_DECL (x));
15464 /* For macho, check to see if we need a stub. */
15465 if (TARGET_MACHO)
15467 const char *name = XSTR (x, 0);
15468 #if TARGET_MACHO
15469 if (darwin_emit_branch_islands
15470 && MACHOPIC_INDIRECT
15471 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15472 name = machopic_indirection_name (x, /*stub_p=*/true);
15473 #endif
15474 assemble_name (file, name);
15476 else if (!DOT_SYMBOLS)
15477 assemble_name (file, XSTR (x, 0));
15478 else
15479 rs6000_output_function_entry (file, XSTR (x, 0));
15480 return;
15482 case 'Z':
15483 /* Like 'L', for last word of TImode. */
15484 if (GET_CODE (x) == REG)
15485 fputs (reg_names[REGNO (x) + 3], file);
15486 else if (GET_CODE (x) == MEM)
15488 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15489 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15490 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15491 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15492 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15493 else
15494 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15495 if (small_data_operand (x, GET_MODE (x)))
15496 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15497 reg_names[SMALL_DATA_REG]);
15499 return;
15501 /* Print AltiVec or SPE memory operand. */
15502 case 'y':
15504 rtx tmp;
15506 gcc_assert (GET_CODE (x) == MEM);
15508 tmp = XEXP (x, 0);
15510 /* Ugly hack because %y is overloaded. */
15511 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15512 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15513 || GET_MODE (x) == TFmode
15514 || GET_MODE (x) == TImode))
15516 /* Handle [reg]. */
15517 if (GET_CODE (tmp) == REG)
15519 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15520 break;
15522 /* Handle [reg+UIMM]. */
15523 else if (GET_CODE (tmp) == PLUS &&
15524 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15526 int x;
15528 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15530 x = INTVAL (XEXP (tmp, 1));
15531 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15532 break;
15535 /* Fall through. Must be [reg+reg]. */
15537 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15538 && GET_CODE (tmp) == AND
15539 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15540 && INTVAL (XEXP (tmp, 1)) == -16)
15541 tmp = XEXP (tmp, 0);
15542 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15543 && GET_CODE (tmp) == PRE_MODIFY)
15544 tmp = XEXP (tmp, 1);
15545 if (GET_CODE (tmp) == REG)
15546 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15547 else
15549 if (!GET_CODE (tmp) == PLUS
15550 || !REG_P (XEXP (tmp, 0))
15551 || !REG_P (XEXP (tmp, 1)))
15553 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15554 break;
15557 if (REGNO (XEXP (tmp, 0)) == 0)
15558 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15559 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15560 else
15561 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15562 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15564 break;
15567 case 0:
15568 if (GET_CODE (x) == REG)
15569 fprintf (file, "%s", reg_names[REGNO (x)]);
15570 else if (GET_CODE (x) == MEM)
15572 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15573 know the width from the mode. */
15574 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15575 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15576 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15577 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15578 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15579 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15580 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15581 output_address (XEXP (XEXP (x, 0), 1));
15582 else
15583 output_address (XEXP (x, 0));
15585 else
15586 output_addr_const (file, x);
15587 return;
15589 case '&':
15590 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15591 return;
15593 default:
15594 output_operand_lossage ("invalid %%xn code");
15598 /* Print the address of an operand. */
15600 void
15601 print_operand_address (FILE *file, rtx x)
15603 if (GET_CODE (x) == REG)
15604 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15605 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15606 || GET_CODE (x) == LABEL_REF)
15608 output_addr_const (file, x);
15609 if (small_data_operand (x, GET_MODE (x)))
15610 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15611 reg_names[SMALL_DATA_REG]);
15612 else
15613 gcc_assert (!TARGET_TOC);
15615 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15617 gcc_assert (REG_P (XEXP (x, 0)));
15618 if (REGNO (XEXP (x, 0)) == 0)
15619 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15620 reg_names[ REGNO (XEXP (x, 0)) ]);
15621 else
15622 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15623 reg_names[ REGNO (XEXP (x, 1)) ]);
15625 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15626 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15627 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15628 #if TARGET_MACHO
15629 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15630 && CONSTANT_P (XEXP (x, 1)))
15632 fprintf (file, "lo16(");
15633 output_addr_const (file, XEXP (x, 1));
15634 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15636 #endif
15637 else if (legitimate_constant_pool_address_p (x, true))
15639 /* This hack along with a corresponding hack in
15640 rs6000_output_addr_const_extra arranges to output addends
15641 where the assembler expects to find them. eg.
15642 (lo_sum (reg 9)
15643 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15644 without this hack would be output as "x@toc+8@l(9)". We
15645 want "x+8@toc@l(9)". */
15646 output_addr_const (file, tocrel_base);
15647 if (GET_CODE (x) == LO_SUM)
15648 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15649 else
15650 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15652 #if TARGET_ELF
15653 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15654 && CONSTANT_P (XEXP (x, 1)))
15656 output_addr_const (file, XEXP (x, 1));
15657 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15659 #endif
15660 else
15661 gcc_unreachable ();
15664 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15666 bool
15667 rs6000_output_addr_const_extra (FILE *file, rtx x)
15669 if (GET_CODE (x) == UNSPEC)
15670 switch (XINT (x, 1))
15672 case UNSPEC_TOCREL:
15673 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
15674 output_addr_const (file, XVECEXP (x, 0, 0));
15675 if (x == tocrel_base && tocrel_offset != const0_rtx)
15677 if (INTVAL (tocrel_offset) >= 0)
15678 fprintf (file, "+");
15679 output_addr_const (file, tocrel_offset);
15681 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15683 putc ('-', file);
15684 assemble_name (file, toc_label_name);
15686 else if (TARGET_ELF)
15687 fputs ("@toc", file);
15688 return true;
15690 #if TARGET_MACHO
15691 case UNSPEC_MACHOPIC_OFFSET:
15692 output_addr_const (file, XVECEXP (x, 0, 0));
15693 putc ('-', file);
15694 machopic_output_function_base_name (file);
15695 return true;
15696 #endif
15698 return false;
15701 /* Target hook for assembling integer objects. The PowerPC version has
15702 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15703 is defined. It also needs to handle DI-mode objects on 64-bit
15704 targets. */
15706 static bool
15707 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15709 #ifdef RELOCATABLE_NEEDS_FIXUP
15710 /* Special handling for SI values. */
15711 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15713 static int recurse = 0;
15715 /* For -mrelocatable, we mark all addresses that need to be fixed up
15716 in the .fixup section. */
15717 if (TARGET_RELOCATABLE
15718 && in_section != toc_section
15719 && in_section != text_section
15720 && !unlikely_text_section_p (in_section)
15721 && !recurse
15722 && GET_CODE (x) != CONST_INT
15723 && GET_CODE (x) != CONST_DOUBLE
15724 && CONSTANT_P (x))
15726 char buf[256];
15728 recurse = 1;
15729 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15730 fixuplabelno++;
15731 ASM_OUTPUT_LABEL (asm_out_file, buf);
15732 fprintf (asm_out_file, "\t.long\t(");
15733 output_addr_const (asm_out_file, x);
15734 fprintf (asm_out_file, ")@fixup\n");
15735 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15736 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15737 fprintf (asm_out_file, "\t.long\t");
15738 assemble_name (asm_out_file, buf);
15739 fprintf (asm_out_file, "\n\t.previous\n");
15740 recurse = 0;
15741 return true;
15743 /* Remove initial .'s to turn a -mcall-aixdesc function
15744 address into the address of the descriptor, not the function
15745 itself. */
15746 else if (GET_CODE (x) == SYMBOL_REF
15747 && XSTR (x, 0)[0] == '.'
15748 && DEFAULT_ABI == ABI_AIX)
15750 const char *name = XSTR (x, 0);
15751 while (*name == '.')
15752 name++;
15754 fprintf (asm_out_file, "\t.long\t%s\n", name);
15755 return true;
15758 #endif /* RELOCATABLE_NEEDS_FIXUP */
15759 return default_assemble_integer (x, size, aligned_p);
15762 #ifdef HAVE_GAS_HIDDEN
15763 /* Emit an assembler directive to set symbol visibility for DECL to
15764 VISIBILITY_TYPE. */
15766 static void
15767 rs6000_assemble_visibility (tree decl, int vis)
15769 /* Functions need to have their entry point symbol visibility set as
15770 well as their descriptor symbol visibility. */
15771 if (DEFAULT_ABI == ABI_AIX
15772 && DOT_SYMBOLS
15773 && TREE_CODE (decl) == FUNCTION_DECL)
15775 static const char * const visibility_types[] = {
15776 NULL, "internal", "hidden", "protected"
15779 const char *name, *type;
15781 name = ((* targetm.strip_name_encoding)
15782 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15783 type = visibility_types[vis];
15785 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15786 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15788 else
15789 default_assemble_visibility (decl, vis);
15791 #endif
15793 enum rtx_code
15794 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15796 /* Reversal of FP compares takes care -- an ordered compare
15797 becomes an unordered compare and vice versa. */
15798 if (mode == CCFPmode
15799 && (!flag_finite_math_only
15800 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15801 || code == UNEQ || code == LTGT))
15802 return reverse_condition_maybe_unordered (code);
15803 else
15804 return reverse_condition (code);
15807 /* Generate a compare for CODE. Return a brand-new rtx that
15808 represents the result of the compare. */
15810 static rtx
15811 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15813 enum machine_mode comp_mode;
15814 rtx compare_result;
15815 enum rtx_code code = GET_CODE (cmp);
15816 rtx op0 = XEXP (cmp, 0);
15817 rtx op1 = XEXP (cmp, 1);
15819 if (FLOAT_MODE_P (mode))
15820 comp_mode = CCFPmode;
15821 else if (code == GTU || code == LTU
15822 || code == GEU || code == LEU)
15823 comp_mode = CCUNSmode;
15824 else if ((code == EQ || code == NE)
15825 && GET_CODE (op0) == SUBREG
15826 && GET_CODE (op1) == SUBREG
15827 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15828 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15829 /* These are unsigned values, perhaps there will be a later
15830 ordering compare that can be shared with this one.
15831 Unfortunately we cannot detect the signedness of the operands
15832 for non-subregs. */
15833 comp_mode = CCUNSmode;
15834 else
15835 comp_mode = CCmode;
15837 /* First, the compare. */
15838 compare_result = gen_reg_rtx (comp_mode);
15840 /* E500 FP compare instructions on the GPRs. Yuck! */
15841 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15842 && FLOAT_MODE_P (mode))
15844 rtx cmp, or_result, compare_result2;
15845 enum machine_mode op_mode = GET_MODE (op0);
15847 if (op_mode == VOIDmode)
15848 op_mode = GET_MODE (op1);
15850 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15851 This explains the following mess. */
15853 switch (code)
15855 case EQ: case UNEQ: case NE: case LTGT:
15856 switch (op_mode)
15858 case SFmode:
15859 cmp = (flag_finite_math_only && !flag_trapping_math)
15860 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15861 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15862 break;
15864 case DFmode:
15865 cmp = (flag_finite_math_only && !flag_trapping_math)
15866 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15867 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15868 break;
15870 case TFmode:
15871 cmp = (flag_finite_math_only && !flag_trapping_math)
15872 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15873 : gen_cmptfeq_gpr (compare_result, op0, op1);
15874 break;
15876 default:
15877 gcc_unreachable ();
15879 break;
15881 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15882 switch (op_mode)
15884 case SFmode:
15885 cmp = (flag_finite_math_only && !flag_trapping_math)
15886 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15887 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15888 break;
15890 case DFmode:
15891 cmp = (flag_finite_math_only && !flag_trapping_math)
15892 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15893 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15894 break;
15896 case TFmode:
15897 cmp = (flag_finite_math_only && !flag_trapping_math)
15898 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15899 : gen_cmptfgt_gpr (compare_result, op0, op1);
15900 break;
15902 default:
15903 gcc_unreachable ();
15905 break;
15907 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15908 switch (op_mode)
15910 case SFmode:
15911 cmp = (flag_finite_math_only && !flag_trapping_math)
15912 ? gen_tstsflt_gpr (compare_result, op0, op1)
15913 : gen_cmpsflt_gpr (compare_result, op0, op1);
15914 break;
15916 case DFmode:
15917 cmp = (flag_finite_math_only && !flag_trapping_math)
15918 ? gen_tstdflt_gpr (compare_result, op0, op1)
15919 : gen_cmpdflt_gpr (compare_result, op0, op1);
15920 break;
15922 case TFmode:
15923 cmp = (flag_finite_math_only && !flag_trapping_math)
15924 ? gen_tsttflt_gpr (compare_result, op0, op1)
15925 : gen_cmptflt_gpr (compare_result, op0, op1);
15926 break;
15928 default:
15929 gcc_unreachable ();
15931 break;
15932 default:
15933 gcc_unreachable ();
15936 /* Synthesize LE and GE from LT/GT || EQ. */
15937 if (code == LE || code == GE || code == LEU || code == GEU)
15939 emit_insn (cmp);
15941 switch (code)
15943 case LE: code = LT; break;
15944 case GE: code = GT; break;
15945 case LEU: code = LT; break;
15946 case GEU: code = GT; break;
15947 default: gcc_unreachable ();
15950 compare_result2 = gen_reg_rtx (CCFPmode);
15952 /* Do the EQ. */
15953 switch (op_mode)
15955 case SFmode:
15956 cmp = (flag_finite_math_only && !flag_trapping_math)
15957 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15958 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15959 break;
15961 case DFmode:
15962 cmp = (flag_finite_math_only && !flag_trapping_math)
15963 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15964 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15965 break;
15967 case TFmode:
15968 cmp = (flag_finite_math_only && !flag_trapping_math)
15969 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15970 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15971 break;
15973 default:
15974 gcc_unreachable ();
15976 emit_insn (cmp);
15978 /* OR them together. */
15979 or_result = gen_reg_rtx (CCFPmode);
15980 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15981 compare_result2);
15982 compare_result = or_result;
15983 code = EQ;
15985 else
15987 if (code == NE || code == LTGT)
15988 code = NE;
15989 else
15990 code = EQ;
15993 emit_insn (cmp);
15995 else
15997 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15998 CLOBBERs to match cmptf_internal2 pattern. */
15999 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16000 && GET_MODE (op0) == TFmode
16001 && !TARGET_IEEEQUAD
16002 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16003 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16004 gen_rtvec (10,
16005 gen_rtx_SET (VOIDmode,
16006 compare_result,
16007 gen_rtx_COMPARE (comp_mode, op0, op1)),
16008 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16009 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16010 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16011 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16012 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16013 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16014 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16015 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16016 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16017 else if (GET_CODE (op1) == UNSPEC
16018 && XINT (op1, 1) == UNSPEC_SP_TEST)
16020 rtx op1b = XVECEXP (op1, 0, 0);
16021 comp_mode = CCEQmode;
16022 compare_result = gen_reg_rtx (CCEQmode);
16023 if (TARGET_64BIT)
16024 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16025 else
16026 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16028 else
16029 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16030 gen_rtx_COMPARE (comp_mode, op0, op1)));
16033 /* Some kinds of FP comparisons need an OR operation;
16034 under flag_finite_math_only we don't bother. */
16035 if (FLOAT_MODE_P (mode)
16036 && !flag_finite_math_only
16037 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16038 && (code == LE || code == GE
16039 || code == UNEQ || code == LTGT
16040 || code == UNGT || code == UNLT))
16042 enum rtx_code or1, or2;
16043 rtx or1_rtx, or2_rtx, compare2_rtx;
16044 rtx or_result = gen_reg_rtx (CCEQmode);
16046 switch (code)
16048 case LE: or1 = LT; or2 = EQ; break;
16049 case GE: or1 = GT; or2 = EQ; break;
16050 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16051 case LTGT: or1 = LT; or2 = GT; break;
16052 case UNGT: or1 = UNORDERED; or2 = GT; break;
16053 case UNLT: or1 = UNORDERED; or2 = LT; break;
16054 default: gcc_unreachable ();
16056 validate_condition_mode (or1, comp_mode);
16057 validate_condition_mode (or2, comp_mode);
16058 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16059 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16060 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16061 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16062 const_true_rtx);
16063 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16065 compare_result = or_result;
16066 code = EQ;
16069 validate_condition_mode (code, GET_MODE (compare_result));
16071 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16075 /* Emit the RTL for an sISEL pattern. */
16077 void
16078 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16080 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16083 void
16084 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16086 rtx condition_rtx;
16087 enum machine_mode op_mode;
16088 enum rtx_code cond_code;
16089 rtx result = operands[0];
16091 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16093 rs6000_emit_sISEL (mode, operands);
16094 return;
16097 condition_rtx = rs6000_generate_compare (operands[1], mode);
16098 cond_code = GET_CODE (condition_rtx);
16100 if (FLOAT_MODE_P (mode)
16101 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16103 rtx t;
16105 PUT_MODE (condition_rtx, SImode);
16106 t = XEXP (condition_rtx, 0);
16108 gcc_assert (cond_code == NE || cond_code == EQ);
16110 if (cond_code == NE)
16111 emit_insn (gen_e500_flip_gt_bit (t, t));
16113 emit_insn (gen_move_from_CR_gt_bit (result, t));
16114 return;
16117 if (cond_code == NE
16118 || cond_code == GE || cond_code == LE
16119 || cond_code == GEU || cond_code == LEU
16120 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16122 rtx not_result = gen_reg_rtx (CCEQmode);
16123 rtx not_op, rev_cond_rtx;
16124 enum machine_mode cc_mode;
16126 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16128 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16129 SImode, XEXP (condition_rtx, 0), const0_rtx);
16130 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16131 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16132 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16135 op_mode = GET_MODE (XEXP (operands[1], 0));
16136 if (op_mode == VOIDmode)
16137 op_mode = GET_MODE (XEXP (operands[1], 1));
16139 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16141 PUT_MODE (condition_rtx, DImode);
16142 convert_move (result, condition_rtx, 0);
16144 else
16146 PUT_MODE (condition_rtx, SImode);
16147 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16151 /* Emit a branch of kind CODE to location LOC. */
16153 void
16154 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16156 rtx condition_rtx, loc_ref;
16158 condition_rtx = rs6000_generate_compare (operands[0], mode);
16159 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16160 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16161 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16162 loc_ref, pc_rtx)));
16165 /* Return the string to output a conditional branch to LABEL, which is
16166 the operand number of the label, or -1 if the branch is really a
16167 conditional return.
16169 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16170 condition code register and its mode specifies what kind of
16171 comparison we made.
16173 REVERSED is nonzero if we should reverse the sense of the comparison.
16175 INSN is the insn. */
16177 char *
16178 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16180 static char string[64];
16181 enum rtx_code code = GET_CODE (op);
16182 rtx cc_reg = XEXP (op, 0);
16183 enum machine_mode mode = GET_MODE (cc_reg);
16184 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16185 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16186 int really_reversed = reversed ^ need_longbranch;
16187 char *s = string;
16188 const char *ccode;
16189 const char *pred;
16190 rtx note;
16192 validate_condition_mode (code, mode);
16194 /* Work out which way this really branches. We could use
16195 reverse_condition_maybe_unordered here always but this
16196 makes the resulting assembler clearer. */
16197 if (really_reversed)
16199 /* Reversal of FP compares takes care -- an ordered compare
16200 becomes an unordered compare and vice versa. */
16201 if (mode == CCFPmode)
16202 code = reverse_condition_maybe_unordered (code);
16203 else
16204 code = reverse_condition (code);
16207 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16209 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16210 to the GT bit. */
16211 switch (code)
16213 case EQ:
16214 /* Opposite of GT. */
16215 code = GT;
16216 break;
16218 case NE:
16219 code = UNLE;
16220 break;
16222 default:
16223 gcc_unreachable ();
16227 switch (code)
16229 /* Not all of these are actually distinct opcodes, but
16230 we distinguish them for clarity of the resulting assembler. */
16231 case NE: case LTGT:
16232 ccode = "ne"; break;
16233 case EQ: case UNEQ:
16234 ccode = "eq"; break;
16235 case GE: case GEU:
16236 ccode = "ge"; break;
16237 case GT: case GTU: case UNGT:
16238 ccode = "gt"; break;
16239 case LE: case LEU:
16240 ccode = "le"; break;
16241 case LT: case LTU: case UNLT:
16242 ccode = "lt"; break;
16243 case UNORDERED: ccode = "un"; break;
16244 case ORDERED: ccode = "nu"; break;
16245 case UNGE: ccode = "nl"; break;
16246 case UNLE: ccode = "ng"; break;
16247 default:
16248 gcc_unreachable ();
16251 /* Maybe we have a guess as to how likely the branch is.
16252 The old mnemonics don't have a way to specify this information. */
16253 pred = "";
16254 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16255 if (note != NULL_RTX)
16257 /* PROB is the difference from 50%. */
16258 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16260 /* Only hint for highly probable/improbable branches on newer
16261 cpus as static prediction overrides processor dynamic
16262 prediction. For older cpus we may as well always hint, but
16263 assume not taken for branches that are very close to 50% as a
16264 mispredicted taken branch is more expensive than a
16265 mispredicted not-taken branch. */
16266 if (rs6000_always_hint
16267 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16268 && br_prob_note_reliable_p (note)))
16270 if (abs (prob) > REG_BR_PROB_BASE / 20
16271 && ((prob > 0) ^ need_longbranch))
16272 pred = "+";
16273 else
16274 pred = "-";
16278 if (label == NULL)
16279 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16280 else
16281 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16283 /* We need to escape any '%' characters in the reg_names string.
16284 Assume they'd only be the first character.... */
16285 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16286 *s++ = '%';
16287 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16289 if (label != NULL)
16291 /* If the branch distance was too far, we may have to use an
16292 unconditional branch to go the distance. */
16293 if (need_longbranch)
16294 s += sprintf (s, ",$+8\n\tb %s", label);
16295 else
16296 s += sprintf (s, ",%s", label);
16299 return string;
16302 /* Return the string to flip the GT bit on a CR. */
16303 char *
16304 output_e500_flip_gt_bit (rtx dst, rtx src)
16306 static char string[64];
16307 int a, b;
16309 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16310 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16312 /* GT bit. */
16313 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16314 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16316 sprintf (string, "crnot %d,%d", a, b);
16317 return string;
16320 /* Return insn for VSX or Altivec comparisons. */
16322 static rtx
16323 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16325 rtx mask;
16326 enum machine_mode mode = GET_MODE (op0);
16328 switch (code)
16330 default:
16331 break;
16333 case GE:
16334 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16335 return NULL_RTX;
16337 case EQ:
16338 case GT:
16339 case GTU:
16340 mask = gen_reg_rtx (mode);
16341 emit_insn (gen_rtx_SET (VOIDmode,
16342 mask,
16343 gen_rtx_fmt_ee (code, mode, op0, op1)));
16344 return mask;
16347 return NULL_RTX;
16350 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16351 DMODE is expected destination mode. This is a recursive function. */
16353 static rtx
16354 rs6000_emit_vector_compare (enum rtx_code rcode,
16355 rtx op0, rtx op1,
16356 enum machine_mode dmode)
16358 rtx mask;
16359 bool swap_operands = false;
16360 bool try_again = false;
16362 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16363 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16365 /* See if the comparison works as is. */
16366 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16367 if (mask)
16368 return mask;
16370 switch (rcode)
16372 case LT:
16373 rcode = GT;
16374 swap_operands = true;
16375 try_again = true;
16376 break;
16377 case LTU:
16378 rcode = GTU;
16379 swap_operands = true;
16380 try_again = true;
16381 break;
16382 case NE:
16383 case UNLE:
16384 case UNLT:
16385 case UNGE:
16386 case UNGT:
16387 /* Invert condition and try again.
16388 e.g., A != B becomes ~(A==B). */
16390 enum rtx_code rev_code;
16391 enum insn_code nor_code;
16392 rtx mask2;
16394 rev_code = reverse_condition_maybe_unordered (rcode);
16395 if (rev_code == UNKNOWN)
16396 return NULL_RTX;
16398 nor_code = optab_handler (one_cmpl_optab, dmode);
16399 if (nor_code == CODE_FOR_nothing)
16400 return NULL_RTX;
16402 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16403 if (!mask2)
16404 return NULL_RTX;
16406 mask = gen_reg_rtx (dmode);
16407 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16408 return mask;
16410 break;
16411 case GE:
16412 case GEU:
16413 case LE:
16414 case LEU:
16415 /* Try GT/GTU/LT/LTU OR EQ */
16417 rtx c_rtx, eq_rtx;
16418 enum insn_code ior_code;
16419 enum rtx_code new_code;
16421 switch (rcode)
16423 case GE:
16424 new_code = GT;
16425 break;
16427 case GEU:
16428 new_code = GTU;
16429 break;
16431 case LE:
16432 new_code = LT;
16433 break;
16435 case LEU:
16436 new_code = LTU;
16437 break;
16439 default:
16440 gcc_unreachable ();
16443 ior_code = optab_handler (ior_optab, dmode);
16444 if (ior_code == CODE_FOR_nothing)
16445 return NULL_RTX;
16447 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16448 if (!c_rtx)
16449 return NULL_RTX;
16451 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16452 if (!eq_rtx)
16453 return NULL_RTX;
16455 mask = gen_reg_rtx (dmode);
16456 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16457 return mask;
16459 break;
16460 default:
16461 return NULL_RTX;
16464 if (try_again)
16466 if (swap_operands)
16468 rtx tmp;
16469 tmp = op0;
16470 op0 = op1;
16471 op1 = tmp;
16474 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16475 if (mask)
16476 return mask;
16479 /* You only get two chances. */
16480 return NULL_RTX;
16483 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16484 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16485 operands for the relation operation COND. */
16488 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16489 rtx cond, rtx cc_op0, rtx cc_op1)
16491 enum machine_mode dest_mode = GET_MODE (dest);
16492 enum rtx_code rcode = GET_CODE (cond);
16493 enum machine_mode cc_mode = CCmode;
16494 rtx mask;
16495 rtx cond2;
16496 rtx tmp;
16497 bool invert_move = false;
16499 if (VECTOR_UNIT_NONE_P (dest_mode))
16500 return 0;
16502 switch (rcode)
16504 /* Swap operands if we can, and fall back to doing the operation as
16505 specified, and doing a NOR to invert the test. */
16506 case NE:
16507 case UNLE:
16508 case UNLT:
16509 case UNGE:
16510 case UNGT:
16511 /* Invert condition and try again.
16512 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16513 invert_move = true;
16514 rcode = reverse_condition_maybe_unordered (rcode);
16515 if (rcode == UNKNOWN)
16516 return 0;
16517 break;
16519 /* Mark unsigned tests with CCUNSmode. */
16520 case GTU:
16521 case GEU:
16522 case LTU:
16523 case LEU:
16524 cc_mode = CCUNSmode;
16525 break;
16527 default:
16528 break;
16531 /* Get the vector mask for the given relational operations. */
16532 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16534 if (!mask)
16535 return 0;
16537 if (invert_move)
16539 tmp = op_true;
16540 op_true = op_false;
16541 op_false = tmp;
16544 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16545 emit_insn (gen_rtx_SET (VOIDmode,
16546 dest,
16547 gen_rtx_IF_THEN_ELSE (dest_mode,
16548 cond2,
16549 op_true,
16550 op_false)));
16551 return 1;
16554 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16555 operands of the last comparison is nonzero/true, FALSE_COND if it
16556 is zero/false. Return 0 if the hardware has no such operation. */
16559 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16561 enum rtx_code code = GET_CODE (op);
16562 rtx op0 = XEXP (op, 0);
16563 rtx op1 = XEXP (op, 1);
16564 REAL_VALUE_TYPE c1;
16565 enum machine_mode compare_mode = GET_MODE (op0);
16566 enum machine_mode result_mode = GET_MODE (dest);
16567 rtx temp;
16568 bool is_against_zero;
16570 /* These modes should always match. */
16571 if (GET_MODE (op1) != compare_mode
16572 /* In the isel case however, we can use a compare immediate, so
16573 op1 may be a small constant. */
16574 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16575 return 0;
16576 if (GET_MODE (true_cond) != result_mode)
16577 return 0;
16578 if (GET_MODE (false_cond) != result_mode)
16579 return 0;
16581 /* First, work out if the hardware can do this at all, or
16582 if it's too slow.... */
16583 if (!FLOAT_MODE_P (compare_mode))
16585 if (TARGET_ISEL)
16586 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16587 return 0;
16589 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16590 && SCALAR_FLOAT_MODE_P (compare_mode))
16591 return 0;
16593 is_against_zero = op1 == CONST0_RTX (compare_mode);
16595 /* A floating-point subtract might overflow, underflow, or produce
16596 an inexact result, thus changing the floating-point flags, so it
16597 can't be generated if we care about that. It's safe if one side
16598 of the construct is zero, since then no subtract will be
16599 generated. */
16600 if (SCALAR_FLOAT_MODE_P (compare_mode)
16601 && flag_trapping_math && ! is_against_zero)
16602 return 0;
16604 /* Eliminate half of the comparisons by switching operands, this
16605 makes the remaining code simpler. */
16606 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16607 || code == LTGT || code == LT || code == UNLE)
16609 code = reverse_condition_maybe_unordered (code);
16610 temp = true_cond;
16611 true_cond = false_cond;
16612 false_cond = temp;
16615 /* UNEQ and LTGT take four instructions for a comparison with zero,
16616 it'll probably be faster to use a branch here too. */
16617 if (code == UNEQ && HONOR_NANS (compare_mode))
16618 return 0;
16620 if (GET_CODE (op1) == CONST_DOUBLE)
16621 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16623 /* We're going to try to implement comparisons by performing
16624 a subtract, then comparing against zero. Unfortunately,
16625 Inf - Inf is NaN which is not zero, and so if we don't
16626 know that the operand is finite and the comparison
16627 would treat EQ different to UNORDERED, we can't do it. */
16628 if (HONOR_INFINITIES (compare_mode)
16629 && code != GT && code != UNGE
16630 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16631 /* Constructs of the form (a OP b ? a : b) are safe. */
16632 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16633 || (! rtx_equal_p (op0, true_cond)
16634 && ! rtx_equal_p (op1, true_cond))))
16635 return 0;
16637 /* At this point we know we can use fsel. */
16639 /* Reduce the comparison to a comparison against zero. */
16640 if (! is_against_zero)
16642 temp = gen_reg_rtx (compare_mode);
16643 emit_insn (gen_rtx_SET (VOIDmode, temp,
16644 gen_rtx_MINUS (compare_mode, op0, op1)));
16645 op0 = temp;
16646 op1 = CONST0_RTX (compare_mode);
16649 /* If we don't care about NaNs we can reduce some of the comparisons
16650 down to faster ones. */
16651 if (! HONOR_NANS (compare_mode))
16652 switch (code)
16654 case GT:
16655 code = LE;
16656 temp = true_cond;
16657 true_cond = false_cond;
16658 false_cond = temp;
16659 break;
16660 case UNGE:
16661 code = GE;
16662 break;
16663 case UNEQ:
16664 code = EQ;
16665 break;
16666 default:
16667 break;
16670 /* Now, reduce everything down to a GE. */
16671 switch (code)
16673 case GE:
16674 break;
16676 case LE:
16677 temp = gen_reg_rtx (compare_mode);
16678 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16679 op0 = temp;
16680 break;
16682 case ORDERED:
16683 temp = gen_reg_rtx (compare_mode);
16684 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16685 op0 = temp;
16686 break;
16688 case EQ:
16689 temp = gen_reg_rtx (compare_mode);
16690 emit_insn (gen_rtx_SET (VOIDmode, temp,
16691 gen_rtx_NEG (compare_mode,
16692 gen_rtx_ABS (compare_mode, op0))));
16693 op0 = temp;
16694 break;
16696 case UNGE:
16697 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16698 temp = gen_reg_rtx (result_mode);
16699 emit_insn (gen_rtx_SET (VOIDmode, temp,
16700 gen_rtx_IF_THEN_ELSE (result_mode,
16701 gen_rtx_GE (VOIDmode,
16702 op0, op1),
16703 true_cond, false_cond)));
16704 false_cond = true_cond;
16705 true_cond = temp;
16707 temp = gen_reg_rtx (compare_mode);
16708 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16709 op0 = temp;
16710 break;
16712 case GT:
16713 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16714 temp = gen_reg_rtx (result_mode);
16715 emit_insn (gen_rtx_SET (VOIDmode, temp,
16716 gen_rtx_IF_THEN_ELSE (result_mode,
16717 gen_rtx_GE (VOIDmode,
16718 op0, op1),
16719 true_cond, false_cond)));
16720 true_cond = false_cond;
16721 false_cond = temp;
16723 temp = gen_reg_rtx (compare_mode);
16724 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16725 op0 = temp;
16726 break;
16728 default:
16729 gcc_unreachable ();
16732 emit_insn (gen_rtx_SET (VOIDmode, dest,
16733 gen_rtx_IF_THEN_ELSE (result_mode,
16734 gen_rtx_GE (VOIDmode,
16735 op0, op1),
16736 true_cond, false_cond)));
16737 return 1;
16740 /* Same as above, but for ints (isel). */
16742 static int
16743 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16745 rtx condition_rtx, cr;
16746 enum machine_mode mode = GET_MODE (dest);
16747 enum rtx_code cond_code;
16748 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
16749 bool signedp;
16751 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16752 return 0;
16754 /* We still have to do the compare, because isel doesn't do a
16755 compare, it just looks at the CRx bits set by a previous compare
16756 instruction. */
16757 condition_rtx = rs6000_generate_compare (op, mode);
16758 cond_code = GET_CODE (condition_rtx);
16759 cr = XEXP (condition_rtx, 0);
16760 signedp = GET_MODE (cr) == CCmode;
16762 isel_func = (mode == SImode
16763 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
16764 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
16766 switch (cond_code)
16768 case LT: case GT: case LTU: case GTU: case EQ:
16769 /* isel handles these directly. */
16770 break;
16772 default:
16773 /* We need to swap the sense of the comparison. */
16775 rtx t = true_cond;
16776 true_cond = false_cond;
16777 false_cond = t;
16778 PUT_CODE (condition_rtx, reverse_condition (cond_code));
16780 break;
16783 false_cond = force_reg (mode, false_cond);
16784 if (true_cond != const0_rtx)
16785 true_cond = force_reg (mode, true_cond);
16787 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
16789 return 1;
16792 const char *
16793 output_isel (rtx *operands)
16795 enum rtx_code code;
16797 code = GET_CODE (operands[1]);
16799 gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE));
16801 return "isel %0,%2,%3,%j1";
16804 void
16805 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16807 enum machine_mode mode = GET_MODE (op0);
16808 enum rtx_code c;
16809 rtx target;
16811 /* VSX/altivec have direct min/max insns. */
16812 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16814 emit_insn (gen_rtx_SET (VOIDmode,
16815 dest,
16816 gen_rtx_fmt_ee (code, mode, op0, op1)));
16817 return;
16820 if (code == SMAX || code == SMIN)
16821 c = GE;
16822 else
16823 c = GEU;
16825 if (code == SMAX || code == UMAX)
16826 target = emit_conditional_move (dest, c, op0, op1, mode,
16827 op0, op1, mode, 0);
16828 else
16829 target = emit_conditional_move (dest, c, op0, op1, mode,
16830 op1, op0, mode, 0);
16831 gcc_assert (target);
16832 if (target != dest)
16833 emit_move_insn (dest, target);
16836 /* Emit instructions to perform a load-reserved/store-conditional operation.
16837 The operation performed is an atomic
16838 (set M (CODE:MODE M OP))
16839 If not NULL, BEFORE is atomically set to M before the operation, and
16840 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16841 If SYNC_P then a memory barrier is emitted before the operation.
16842 Either OP or M may be wrapped in a NOT operation. */
16844 void
16845 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16846 rtx m, rtx op, rtx before_param, rtx after_param,
16847 bool sync_p)
16849 enum machine_mode used_mode;
16850 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16851 rtx used_m;
16852 rtvec vec;
16853 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16854 rtx shift = NULL_RTX;
16856 if (sync_p)
16857 emit_insn (gen_lwsync ());
16859 used_m = m;
16861 /* If this is smaller than SImode, we'll have to use SImode with
16862 adjustments. */
16863 if (mode == QImode || mode == HImode)
16865 rtx newop, oldop;
16867 if (MEM_ALIGN (used_m) >= 32)
16869 int ishift = 0;
16870 if (BYTES_BIG_ENDIAN)
16871 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16873 shift = GEN_INT (ishift);
16874 used_m = change_address (used_m, SImode, 0);
16876 else
16878 rtx addrSI, aligned_addr;
16879 int shift_mask = mode == QImode ? 0x18 : 0x10;
16881 addrSI = gen_lowpart_common (SImode,
16882 force_reg (Pmode, XEXP (used_m, 0)));
16883 addrSI = force_reg (SImode, addrSI);
16884 shift = gen_reg_rtx (SImode);
16886 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16887 GEN_INT (shift_mask)));
16888 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16890 aligned_addr = expand_binop (Pmode, and_optab,
16891 XEXP (used_m, 0),
16892 GEN_INT (-4), NULL_RTX,
16893 1, OPTAB_LIB_WIDEN);
16894 used_m = change_address (used_m, SImode, aligned_addr);
16895 set_mem_align (used_m, 32);
16897 /* It's safe to keep the old alias set of USED_M, because
16898 the operation is atomic and only affects the original
16899 USED_M. */
16900 m = used_m;
16902 if (GET_CODE (op) == NOT)
16904 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16905 oldop = gen_rtx_NOT (SImode, oldop);
16907 else
16908 oldop = lowpart_subreg (SImode, op, mode);
16910 switch (code)
16912 case IOR:
16913 case XOR:
16914 newop = expand_binop (SImode, and_optab,
16915 oldop, GEN_INT (imask), NULL_RTX,
16916 1, OPTAB_LIB_WIDEN);
16917 emit_insn (gen_ashlsi3 (newop, newop, shift));
16918 break;
16920 case NOT: /* NAND */
16921 newop = expand_binop (SImode, ior_optab,
16922 oldop, GEN_INT (~imask), NULL_RTX,
16923 1, OPTAB_LIB_WIDEN);
16924 emit_insn (gen_rotlsi3 (newop, newop, shift));
16925 break;
16927 case AND:
16928 newop = expand_binop (SImode, ior_optab,
16929 oldop, GEN_INT (~imask), NULL_RTX,
16930 1, OPTAB_LIB_WIDEN);
16931 emit_insn (gen_rotlsi3 (newop, newop, shift));
16932 break;
16934 case PLUS:
16935 case MINUS:
16937 rtx mask;
16939 newop = expand_binop (SImode, and_optab,
16940 oldop, GEN_INT (imask), NULL_RTX,
16941 1, OPTAB_LIB_WIDEN);
16942 emit_insn (gen_ashlsi3 (newop, newop, shift));
16944 mask = gen_reg_rtx (SImode);
16945 emit_move_insn (mask, GEN_INT (imask));
16946 emit_insn (gen_ashlsi3 (mask, mask, shift));
16948 if (code == PLUS)
16949 newop = gen_rtx_PLUS (SImode, m, newop);
16950 else
16951 newop = gen_rtx_MINUS (SImode, m, newop);
16952 newop = gen_rtx_AND (SImode, newop, mask);
16953 newop = gen_rtx_IOR (SImode, newop,
16954 gen_rtx_AND (SImode,
16955 gen_rtx_NOT (SImode, mask),
16956 m));
16957 break;
16960 default:
16961 gcc_unreachable ();
16964 op = newop;
16965 used_mode = SImode;
16966 before = gen_reg_rtx (used_mode);
16967 after = gen_reg_rtx (used_mode);
16969 else
16971 used_mode = mode;
16972 before = before_param;
16973 after = after_param;
16975 if (before == NULL_RTX)
16976 before = gen_reg_rtx (used_mode);
16977 if (after == NULL_RTX)
16978 after = gen_reg_rtx (used_mode);
16981 if ((code == PLUS || code == MINUS)
16982 && used_mode != mode)
16983 the_op = op; /* Computed above. */
16984 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16985 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16986 else if (code == NOT)
16987 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16988 gen_rtx_NOT (used_mode, m),
16989 gen_rtx_NOT (used_mode, op));
16990 else
16991 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16993 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16994 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16995 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16996 gen_rtx_UNSPEC (used_mode,
16997 gen_rtvec (1, the_op),
16998 UNSPEC_SYNC_OP));
16999 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17001 if ((code == PLUS || code == MINUS) && used_mode != mode)
17002 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17003 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17004 else
17005 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17006 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17008 /* Shift and mask the return values properly. */
17009 if (used_mode != mode && before_param)
17011 emit_insn (gen_lshrsi3 (before, before, shift));
17012 convert_move (before_param, before, 1);
17015 if (used_mode != mode && after_param)
17017 emit_insn (gen_lshrsi3 (after, after, shift));
17018 convert_move (after_param, after, 1);
17021 /* The previous sequence will end with a branch that's dependent on
17022 the conditional store, so placing an isync will ensure that no
17023 other instructions (especially, no load or store instructions)
17024 can start before the atomic operation completes. */
17025 if (sync_p)
17026 emit_insn (gen_isync ());
17029 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17030 COND is true. Mark the jump as unlikely to be taken. */
17032 static void
17033 emit_unlikely_jump (rtx cond, rtx label)
17035 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17036 rtx x;
17038 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17039 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17040 add_reg_note (x, REG_BR_PROB, very_unlikely);
17043 /* A subroutine of the atomic operation splitters. Emit a load-locked
17044 instruction in MODE. */
17046 static void
17047 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17049 rtx (*fn) (rtx, rtx) = NULL;
17050 if (mode == SImode)
17051 fn = gen_load_locked_si;
17052 else if (mode == DImode)
17053 fn = gen_load_locked_di;
17054 emit_insn (fn (reg, mem));
17057 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17058 instruction in MODE. */
17060 static void
17061 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17063 rtx (*fn) (rtx, rtx, rtx) = NULL;
17064 if (mode == SImode)
17065 fn = gen_store_conditional_si;
17066 else if (mode == DImode)
17067 fn = gen_store_conditional_di;
17069 /* Emit sync before stwcx. to address PPC405 Erratum. */
17070 if (PPC405_ERRATUM77)
17071 emit_insn (gen_memory_barrier ());
17073 emit_insn (fn (res, mem, val));
17076 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17077 to perform. MEM is the memory on which to operate. VAL is the second
17078 operand of the binary operator. BEFORE and AFTER are optional locations to
17079 return the value of MEM either before of after the operation. SCRATCH is
17080 a scratch register. */
17082 void
17083 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17084 rtx before, rtx after, rtx scratch)
17086 enum machine_mode mode = GET_MODE (mem);
17087 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17089 emit_insn (gen_lwsync ());
17091 label = gen_label_rtx ();
17092 emit_label (label);
17093 label = gen_rtx_LABEL_REF (VOIDmode, label);
17095 if (before == NULL_RTX)
17096 before = scratch;
17097 emit_load_locked (mode, before, mem);
17099 if (code == NOT)
17100 x = gen_rtx_IOR (mode,
17101 gen_rtx_NOT (mode, before),
17102 gen_rtx_NOT (mode, val));
17103 else if (code == AND)
17104 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17105 else
17106 x = gen_rtx_fmt_ee (code, mode, before, val);
17108 if (after != NULL_RTX)
17109 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17110 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17112 emit_store_conditional (mode, cond, mem, scratch);
17114 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17115 emit_unlikely_jump (x, label);
17117 emit_insn (gen_isync ());
17120 /* Expand an atomic compare and swap operation. MEM is the memory on which
17121 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17122 value to be stored. SCRATCH is a scratch GPR. */
17124 void
17125 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17126 rtx scratch)
17128 enum machine_mode mode = GET_MODE (mem);
17129 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17131 emit_insn (gen_lwsync ());
17133 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17134 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17135 emit_label (XEXP (label1, 0));
17137 emit_load_locked (mode, retval, mem);
17139 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17140 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17142 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17143 emit_unlikely_jump (x, label2);
17145 emit_move_insn (scratch, newval);
17146 emit_store_conditional (mode, cond, mem, scratch);
17148 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17149 emit_unlikely_jump (x, label1);
17151 emit_insn (gen_isync ());
17152 emit_label (XEXP (label2, 0));
17155 /* Expand an atomic test and set operation. MEM is the memory on which
17156 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17158 void
17159 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17161 enum machine_mode mode = GET_MODE (mem);
17162 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17164 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17165 emit_label (XEXP (label, 0));
17167 emit_load_locked (mode, retval, mem);
17168 emit_move_insn (scratch, val);
17169 emit_store_conditional (mode, cond, mem, scratch);
17171 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17172 emit_unlikely_jump (x, label);
17174 emit_insn (gen_isync ());
17177 void
17178 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17180 enum machine_mode mode = GET_MODE (mem);
17181 rtx addrSI, align, wdst, shift, mask;
17182 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17183 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17185 /* Shift amount for subword relative to aligned word. */
17186 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17187 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17188 shift = gen_reg_rtx (SImode);
17189 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17190 GEN_INT (shift_mask)));
17191 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17193 /* Shift and mask old value into position within word. */
17194 oldval = convert_modes (SImode, mode, oldval, 1);
17195 oldval = expand_binop (SImode, and_optab,
17196 oldval, GEN_INT (imask), NULL_RTX,
17197 1, OPTAB_LIB_WIDEN);
17198 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17200 /* Shift and mask new value into position within word. */
17201 newval = convert_modes (SImode, mode, newval, 1);
17202 newval = expand_binop (SImode, and_optab,
17203 newval, GEN_INT (imask), NULL_RTX,
17204 1, OPTAB_LIB_WIDEN);
17205 emit_insn (gen_ashlsi3 (newval, newval, shift));
17207 /* Mask for insertion. */
17208 mask = gen_reg_rtx (SImode);
17209 emit_move_insn (mask, GEN_INT (imask));
17210 emit_insn (gen_ashlsi3 (mask, mask, shift));
17212 /* Address of aligned word containing subword. */
17213 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17214 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17215 mem = change_address (mem, SImode, align);
17216 set_mem_align (mem, 32);
17217 MEM_VOLATILE_P (mem) = 1;
17219 wdst = gen_reg_rtx (SImode);
17220 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17221 oldval, newval, mem));
17223 /* Shift the result back. */
17224 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17226 emit_move_insn (dst, gen_lowpart (mode, wdst));
17229 void
17230 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17231 rtx oldval, rtx newval, rtx mem,
17232 rtx scratch)
17234 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17236 emit_insn (gen_lwsync ());
17237 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17238 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17239 emit_label (XEXP (label1, 0));
17241 emit_load_locked (SImode, scratch, mem);
17243 /* Mask subword within loaded value for comparison with oldval.
17244 Use UNSPEC_AND to avoid clobber.*/
17245 emit_insn (gen_rtx_SET (SImode, dest,
17246 gen_rtx_UNSPEC (SImode,
17247 gen_rtvec (2, scratch, mask),
17248 UNSPEC_AND)));
17250 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17251 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17253 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17254 emit_unlikely_jump (x, label2);
17256 /* Clear subword within loaded value for insertion of new value. */
17257 emit_insn (gen_rtx_SET (SImode, scratch,
17258 gen_rtx_AND (SImode,
17259 gen_rtx_NOT (SImode, mask), scratch)));
17260 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17261 emit_store_conditional (SImode, cond, mem, scratch);
17263 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17264 emit_unlikely_jump (x, label1);
17266 emit_insn (gen_isync ());
17267 emit_label (XEXP (label2, 0));
17271 /* Emit instructions to move SRC to DST. Called by splitters for
17272 multi-register moves. It will emit at most one instruction for
17273 each register that is accessed; that is, it won't emit li/lis pairs
17274 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17275 register. */
17277 void
17278 rs6000_split_multireg_move (rtx dst, rtx src)
17280 /* The register number of the first register being moved. */
17281 int reg;
17282 /* The mode that is to be moved. */
17283 enum machine_mode mode;
17284 /* The mode that the move is being done in, and its size. */
17285 enum machine_mode reg_mode;
17286 int reg_mode_size;
17287 /* The number of registers that will be moved. */
17288 int nregs;
17290 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17291 mode = GET_MODE (dst);
17292 nregs = hard_regno_nregs[reg][mode];
17293 if (FP_REGNO_P (reg))
17294 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17295 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17296 else if (ALTIVEC_REGNO_P (reg))
17297 reg_mode = V16QImode;
17298 else if (TARGET_E500_DOUBLE && mode == TFmode)
17299 reg_mode = DFmode;
17300 else
17301 reg_mode = word_mode;
17302 reg_mode_size = GET_MODE_SIZE (reg_mode);
17304 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17306 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17308 /* Move register range backwards, if we might have destructive
17309 overlap. */
17310 int i;
17311 for (i = nregs - 1; i >= 0; i--)
17312 emit_insn (gen_rtx_SET (VOIDmode,
17313 simplify_gen_subreg (reg_mode, dst, mode,
17314 i * reg_mode_size),
17315 simplify_gen_subreg (reg_mode, src, mode,
17316 i * reg_mode_size)));
17318 else
17320 int i;
17321 int j = -1;
17322 bool used_update = false;
17323 rtx restore_basereg = NULL_RTX;
17325 if (MEM_P (src) && INT_REGNO_P (reg))
17327 rtx breg;
17329 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17330 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17332 rtx delta_rtx;
17333 breg = XEXP (XEXP (src, 0), 0);
17334 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17335 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17336 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17337 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17338 src = replace_equiv_address (src, breg);
17340 else if (! rs6000_offsettable_memref_p (src))
17342 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17344 rtx basereg = XEXP (XEXP (src, 0), 0);
17345 if (TARGET_UPDATE)
17347 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17348 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17349 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17350 used_update = true;
17352 else
17353 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17354 XEXP (XEXP (src, 0), 1)));
17355 src = replace_equiv_address (src, basereg);
17357 else
17359 rtx basereg = gen_rtx_REG (Pmode, reg);
17360 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17361 src = replace_equiv_address (src, basereg);
17365 breg = XEXP (src, 0);
17366 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17367 breg = XEXP (breg, 0);
17369 /* If the base register we are using to address memory is
17370 also a destination reg, then change that register last. */
17371 if (REG_P (breg)
17372 && REGNO (breg) >= REGNO (dst)
17373 && REGNO (breg) < REGNO (dst) + nregs)
17374 j = REGNO (breg) - REGNO (dst);
17376 else if (MEM_P (dst) && INT_REGNO_P (reg))
17378 rtx breg;
17380 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17381 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17383 rtx delta_rtx;
17384 breg = XEXP (XEXP (dst, 0), 0);
17385 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17386 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17387 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17389 /* We have to update the breg before doing the store.
17390 Use store with update, if available. */
17392 if (TARGET_UPDATE)
17394 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17395 emit_insn (TARGET_32BIT
17396 ? (TARGET_POWERPC64
17397 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17398 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17399 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17400 used_update = true;
17402 else
17403 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17404 dst = replace_equiv_address (dst, breg);
17406 else if (!rs6000_offsettable_memref_p (dst)
17407 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17409 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17411 rtx basereg = XEXP (XEXP (dst, 0), 0);
17412 if (TARGET_UPDATE)
17414 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17415 emit_insn (gen_rtx_SET (VOIDmode,
17416 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17417 used_update = true;
17419 else
17420 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17421 XEXP (XEXP (dst, 0), 1)));
17422 dst = replace_equiv_address (dst, basereg);
17424 else
17426 rtx basereg = XEXP (XEXP (dst, 0), 0);
17427 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17428 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17429 && REG_P (basereg)
17430 && REG_P (offsetreg)
17431 && REGNO (basereg) != REGNO (offsetreg));
17432 if (REGNO (basereg) == 0)
17434 rtx tmp = offsetreg;
17435 offsetreg = basereg;
17436 basereg = tmp;
17438 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17439 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17440 dst = replace_equiv_address (dst, basereg);
17443 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17444 gcc_assert (rs6000_offsettable_memref_p (dst));
17447 for (i = 0; i < nregs; i++)
17449 /* Calculate index to next subword. */
17450 ++j;
17451 if (j == nregs)
17452 j = 0;
17454 /* If compiler already emitted move of first word by
17455 store with update, no need to do anything. */
17456 if (j == 0 && used_update)
17457 continue;
17459 emit_insn (gen_rtx_SET (VOIDmode,
17460 simplify_gen_subreg (reg_mode, dst, mode,
17461 j * reg_mode_size),
17462 simplify_gen_subreg (reg_mode, src, mode,
17463 j * reg_mode_size)));
17465 if (restore_basereg != NULL_RTX)
17466 emit_insn (restore_basereg);
17471 /* This page contains routines that are used to determine what the
17472 function prologue and epilogue code will do and write them out. */
17474 /* Return the first fixed-point register that is required to be
17475 saved. 32 if none. */
17478 first_reg_to_save (void)
17480 int first_reg;
17482 /* Find lowest numbered live register. */
17483 for (first_reg = 13; first_reg <= 31; first_reg++)
17484 if (df_regs_ever_live_p (first_reg)
17485 && (! call_used_regs[first_reg]
17486 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17487 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17488 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17489 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17490 break;
17492 #if TARGET_MACHO
17493 if (flag_pic
17494 && crtl->uses_pic_offset_table
17495 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17496 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17497 #endif
17499 return first_reg;
17502 /* Similar, for FP regs. */
17505 first_fp_reg_to_save (void)
17507 int first_reg;
17509 /* Find lowest numbered live register. */
17510 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17511 if (df_regs_ever_live_p (first_reg))
17512 break;
17514 return first_reg;
17517 /* Similar, for AltiVec regs. */
17519 static int
17520 first_altivec_reg_to_save (void)
17522 int i;
17524 /* Stack frame remains as is unless we are in AltiVec ABI. */
17525 if (! TARGET_ALTIVEC_ABI)
17526 return LAST_ALTIVEC_REGNO + 1;
17528 /* On Darwin, the unwind routines are compiled without
17529 TARGET_ALTIVEC, and use save_world to save/restore the
17530 altivec registers when necessary. */
17531 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17532 && ! TARGET_ALTIVEC)
17533 return FIRST_ALTIVEC_REGNO + 20;
17535 /* Find lowest numbered live register. */
17536 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17537 if (df_regs_ever_live_p (i))
17538 break;
17540 return i;
17543 /* Return a 32-bit mask of the AltiVec registers we need to set in
17544 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17545 the 32-bit word is 0. */
17547 static unsigned int
17548 compute_vrsave_mask (void)
17550 unsigned int i, mask = 0;
17552 /* On Darwin, the unwind routines are compiled without
17553 TARGET_ALTIVEC, and use save_world to save/restore the
17554 call-saved altivec registers when necessary. */
17555 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17556 && ! TARGET_ALTIVEC)
17557 mask |= 0xFFF;
17559 /* First, find out if we use _any_ altivec registers. */
17560 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17561 if (df_regs_ever_live_p (i))
17562 mask |= ALTIVEC_REG_BIT (i);
17564 if (mask == 0)
17565 return mask;
17567 /* Next, remove the argument registers from the set. These must
17568 be in the VRSAVE mask set by the caller, so we don't need to add
17569 them in again. More importantly, the mask we compute here is
17570 used to generate CLOBBERs in the set_vrsave insn, and we do not
17571 wish the argument registers to die. */
17572 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17573 mask &= ~ALTIVEC_REG_BIT (i);
17575 /* Similarly, remove the return value from the set. */
17577 bool yes = false;
17578 diddle_return_value (is_altivec_return_reg, &yes);
17579 if (yes)
17580 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17583 return mask;
17586 /* For a very restricted set of circumstances, we can cut down the
17587 size of prologues/epilogues by calling our own save/restore-the-world
17588 routines. */
17590 static void
17591 compute_save_world_info (rs6000_stack_t *info_ptr)
17593 info_ptr->world_save_p = 1;
17594 info_ptr->world_save_p
17595 = (WORLD_SAVE_P (info_ptr)
17596 && DEFAULT_ABI == ABI_DARWIN
17597 && ! (cfun->calls_setjmp && flag_exceptions)
17598 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17599 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17600 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17601 && info_ptr->cr_save_p);
17603 /* This will not work in conjunction with sibcalls. Make sure there
17604 are none. (This check is expensive, but seldom executed.) */
17605 if (WORLD_SAVE_P (info_ptr))
17607 rtx insn;
17608 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17609 if ( GET_CODE (insn) == CALL_INSN
17610 && SIBLING_CALL_P (insn))
17612 info_ptr->world_save_p = 0;
17613 break;
17617 if (WORLD_SAVE_P (info_ptr))
17619 /* Even if we're not touching VRsave, make sure there's room on the
17620 stack for it, if it looks like we're calling SAVE_WORLD, which
17621 will attempt to save it. */
17622 info_ptr->vrsave_size = 4;
17624 /* If we are going to save the world, we need to save the link register too. */
17625 info_ptr->lr_save_p = 1;
17627 /* "Save" the VRsave register too if we're saving the world. */
17628 if (info_ptr->vrsave_mask == 0)
17629 info_ptr->vrsave_mask = compute_vrsave_mask ();
17631 /* Because the Darwin register save/restore routines only handle
17632 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17633 check. */
17634 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17635 && (info_ptr->first_altivec_reg_save
17636 >= FIRST_SAVED_ALTIVEC_REGNO));
17638 return;
17642 static void
17643 is_altivec_return_reg (rtx reg, void *xyes)
17645 bool *yes = (bool *) xyes;
17646 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17647 *yes = true;
17651 /* Calculate the stack information for the current function. This is
17652 complicated by having two separate calling sequences, the AIX calling
17653 sequence and the V.4 calling sequence.
17655 AIX (and Darwin/Mac OS X) stack frames look like:
17656 32-bit 64-bit
17657 SP----> +---------------------------------------+
17658 | back chain to caller | 0 0
17659 +---------------------------------------+
17660 | saved CR | 4 8 (8-11)
17661 +---------------------------------------+
17662 | saved LR | 8 16
17663 +---------------------------------------+
17664 | reserved for compilers | 12 24
17665 +---------------------------------------+
17666 | reserved for binders | 16 32
17667 +---------------------------------------+
17668 | saved TOC pointer | 20 40
17669 +---------------------------------------+
17670 | Parameter save area (P) | 24 48
17671 +---------------------------------------+
17672 | Alloca space (A) | 24+P etc.
17673 +---------------------------------------+
17674 | Local variable space (L) | 24+P+A
17675 +---------------------------------------+
17676 | Float/int conversion temporary (X) | 24+P+A+L
17677 +---------------------------------------+
17678 | Save area for AltiVec registers (W) | 24+P+A+L+X
17679 +---------------------------------------+
17680 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17681 +---------------------------------------+
17682 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17683 +---------------------------------------+
17684 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17685 +---------------------------------------+
17686 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17687 +---------------------------------------+
17688 old SP->| back chain to caller's caller |
17689 +---------------------------------------+
17691 The required alignment for AIX configurations is two words (i.e., 8
17692 or 16 bytes).
17695 V.4 stack frames look like:
17697 SP----> +---------------------------------------+
17698 | back chain to caller | 0
17699 +---------------------------------------+
17700 | caller's saved LR | 4
17701 +---------------------------------------+
17702 | Parameter save area (P) | 8
17703 +---------------------------------------+
17704 | Alloca space (A) | 8+P
17705 +---------------------------------------+
17706 | Varargs save area (V) | 8+P+A
17707 +---------------------------------------+
17708 | Local variable space (L) | 8+P+A+V
17709 +---------------------------------------+
17710 | Float/int conversion temporary (X) | 8+P+A+V+L
17711 +---------------------------------------+
17712 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17713 +---------------------------------------+
17714 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17715 +---------------------------------------+
17716 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17717 +---------------------------------------+
17718 | SPE: area for 64-bit GP registers |
17719 +---------------------------------------+
17720 | SPE alignment padding |
17721 +---------------------------------------+
17722 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17723 +---------------------------------------+
17724 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17725 +---------------------------------------+
17726 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17727 +---------------------------------------+
17728 old SP->| back chain to caller's caller |
17729 +---------------------------------------+
17731 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17732 given. (But note below and in sysv4.h that we require only 8 and
17733 may round up the size of our stack frame anyways. The historical
17734 reason is early versions of powerpc-linux which didn't properly
17735 align the stack at program startup. A happy side-effect is that
17736 -mno-eabi libraries can be used with -meabi programs.)
17738 The EABI configuration defaults to the V.4 layout. However,
17739 the stack alignment requirements may differ. If -mno-eabi is not
17740 given, the required stack alignment is 8 bytes; if -mno-eabi is
17741 given, the required alignment is 16 bytes. (But see V.4 comment
17742 above.) */
17744 #ifndef ABI_STACK_BOUNDARY
17745 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17746 #endif
17748 static rs6000_stack_t *
17749 rs6000_stack_info (void)
17751 static rs6000_stack_t info;
17752 rs6000_stack_t *info_ptr = &info;
17753 int reg_size = TARGET_32BIT ? 4 : 8;
17754 int ehrd_size;
17755 int save_align;
17756 int first_gp;
17757 HOST_WIDE_INT non_fixed_size;
17759 memset (&info, 0, sizeof (info));
17761 if (TARGET_SPE)
17763 /* Cache value so we don't rescan instruction chain over and over. */
17764 if (cfun->machine->insn_chain_scanned_p == 0)
17765 cfun->machine->insn_chain_scanned_p
17766 = spe_func_has_64bit_regs_p () + 1;
17767 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17770 /* Select which calling sequence. */
17771 info_ptr->abi = DEFAULT_ABI;
17773 /* Calculate which registers need to be saved & save area size. */
17774 info_ptr->first_gp_reg_save = first_reg_to_save ();
17775 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17776 even if it currently looks like we won't. Reload may need it to
17777 get at a constant; if so, it will have already created a constant
17778 pool entry for it. */
17779 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17780 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17781 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17782 && crtl->uses_const_pool
17783 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17784 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17785 else
17786 first_gp = info_ptr->first_gp_reg_save;
17788 info_ptr->gp_size = reg_size * (32 - first_gp);
17790 /* For the SPE, we have an additional upper 32-bits on each GPR.
17791 Ideally we should save the entire 64-bits only when the upper
17792 half is used in SIMD instructions. Since we only record
17793 registers live (not the size they are used in), this proves
17794 difficult because we'd have to traverse the instruction chain at
17795 the right time, taking reload into account. This is a real pain,
17796 so we opt to save the GPRs in 64-bits always if but one register
17797 gets used in 64-bits. Otherwise, all the registers in the frame
17798 get saved in 32-bits.
17800 So... since when we save all GPRs (except the SP) in 64-bits, the
17801 traditional GP save area will be empty. */
17802 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17803 info_ptr->gp_size = 0;
17805 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17806 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17808 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17809 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17810 - info_ptr->first_altivec_reg_save);
17812 /* Does this function call anything? */
17813 info_ptr->calls_p = (! current_function_is_leaf
17814 || cfun->machine->ra_needs_full_frame);
17816 /* Determine if we need to save the link register. */
17817 if ((DEFAULT_ABI == ABI_AIX
17818 && crtl->profile
17819 && !TARGET_PROFILE_KERNEL)
17820 #ifdef TARGET_RELOCATABLE
17821 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17822 #endif
17823 || (info_ptr->first_fp_reg_save != 64
17824 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17825 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17826 || info_ptr->calls_p
17827 || rs6000_ra_ever_killed ())
17829 info_ptr->lr_save_p = 1;
17830 df_set_regs_ever_live (LR_REGNO, true);
17833 /* Determine if we need to save the condition code registers. */
17834 if (df_regs_ever_live_p (CR2_REGNO)
17835 || df_regs_ever_live_p (CR3_REGNO)
17836 || df_regs_ever_live_p (CR4_REGNO))
17838 info_ptr->cr_save_p = 1;
17839 if (DEFAULT_ABI == ABI_V4)
17840 info_ptr->cr_size = reg_size;
17843 /* If the current function calls __builtin_eh_return, then we need
17844 to allocate stack space for registers that will hold data for
17845 the exception handler. */
17846 if (crtl->calls_eh_return)
17848 unsigned int i;
17849 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17850 continue;
17852 /* SPE saves EH registers in 64-bits. */
17853 ehrd_size = i * (TARGET_SPE_ABI
17854 && info_ptr->spe_64bit_regs_used != 0
17855 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17857 else
17858 ehrd_size = 0;
17860 /* Determine various sizes. */
17861 info_ptr->reg_size = reg_size;
17862 info_ptr->fixed_size = RS6000_SAVE_AREA;
17863 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17864 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17865 TARGET_ALTIVEC ? 16 : 8);
17866 if (FRAME_GROWS_DOWNWARD)
17867 info_ptr->vars_size
17868 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17869 + info_ptr->parm_size,
17870 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17871 - (info_ptr->fixed_size + info_ptr->vars_size
17872 + info_ptr->parm_size);
17874 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17875 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17876 else
17877 info_ptr->spe_gp_size = 0;
17879 if (TARGET_ALTIVEC_ABI)
17880 info_ptr->vrsave_mask = compute_vrsave_mask ();
17881 else
17882 info_ptr->vrsave_mask = 0;
17884 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17885 info_ptr->vrsave_size = 4;
17886 else
17887 info_ptr->vrsave_size = 0;
17889 compute_save_world_info (info_ptr);
17891 /* Calculate the offsets. */
17892 switch (DEFAULT_ABI)
17894 case ABI_NONE:
17895 default:
17896 gcc_unreachable ();
17898 case ABI_AIX:
17899 case ABI_DARWIN:
17900 info_ptr->fp_save_offset = - info_ptr->fp_size;
17901 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17903 if (TARGET_ALTIVEC_ABI)
17905 info_ptr->vrsave_save_offset
17906 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17908 /* Align stack so vector save area is on a quadword boundary.
17909 The padding goes above the vectors. */
17910 if (info_ptr->altivec_size != 0)
17911 info_ptr->altivec_padding_size
17912 = info_ptr->vrsave_save_offset & 0xF;
17913 else
17914 info_ptr->altivec_padding_size = 0;
17916 info_ptr->altivec_save_offset
17917 = info_ptr->vrsave_save_offset
17918 - info_ptr->altivec_padding_size
17919 - info_ptr->altivec_size;
17920 gcc_assert (info_ptr->altivec_size == 0
17921 || info_ptr->altivec_save_offset % 16 == 0);
17923 /* Adjust for AltiVec case. */
17924 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17926 else
17927 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17928 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17929 info_ptr->lr_save_offset = 2*reg_size;
17930 break;
17932 case ABI_V4:
17933 info_ptr->fp_save_offset = - info_ptr->fp_size;
17934 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17935 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17937 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17939 /* Align stack so SPE GPR save area is aligned on a
17940 double-word boundary. */
17941 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17942 info_ptr->spe_padding_size
17943 = 8 - (-info_ptr->cr_save_offset % 8);
17944 else
17945 info_ptr->spe_padding_size = 0;
17947 info_ptr->spe_gp_save_offset
17948 = info_ptr->cr_save_offset
17949 - info_ptr->spe_padding_size
17950 - info_ptr->spe_gp_size;
17952 /* Adjust for SPE case. */
17953 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17955 else if (TARGET_ALTIVEC_ABI)
17957 info_ptr->vrsave_save_offset
17958 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17960 /* Align stack so vector save area is on a quadword boundary. */
17961 if (info_ptr->altivec_size != 0)
17962 info_ptr->altivec_padding_size
17963 = 16 - (-info_ptr->vrsave_save_offset % 16);
17964 else
17965 info_ptr->altivec_padding_size = 0;
17967 info_ptr->altivec_save_offset
17968 = info_ptr->vrsave_save_offset
17969 - info_ptr->altivec_padding_size
17970 - info_ptr->altivec_size;
17972 /* Adjust for AltiVec case. */
17973 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17975 else
17976 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17977 info_ptr->ehrd_offset -= ehrd_size;
17978 info_ptr->lr_save_offset = reg_size;
17979 break;
17982 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17983 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17984 + info_ptr->gp_size
17985 + info_ptr->altivec_size
17986 + info_ptr->altivec_padding_size
17987 + info_ptr->spe_gp_size
17988 + info_ptr->spe_padding_size
17989 + ehrd_size
17990 + info_ptr->cr_size
17991 + info_ptr->vrsave_size,
17992 save_align);
17994 non_fixed_size = (info_ptr->vars_size
17995 + info_ptr->parm_size
17996 + info_ptr->save_size);
17998 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17999 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18001 /* Determine if we need to allocate any stack frame:
18003 For AIX we need to push the stack if a frame pointer is needed
18004 (because the stack might be dynamically adjusted), if we are
18005 debugging, if we make calls, or if the sum of fp_save, gp_save,
18006 and local variables are more than the space needed to save all
18007 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18008 + 18*8 = 288 (GPR13 reserved).
18010 For V.4 we don't have the stack cushion that AIX uses, but assume
18011 that the debugger can handle stackless frames. */
18013 if (info_ptr->calls_p)
18014 info_ptr->push_p = 1;
18016 else if (DEFAULT_ABI == ABI_V4)
18017 info_ptr->push_p = non_fixed_size != 0;
18019 else if (frame_pointer_needed)
18020 info_ptr->push_p = 1;
18022 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18023 info_ptr->push_p = 1;
18025 else
18026 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18028 /* Zero offsets if we're not saving those registers. */
18029 if (info_ptr->fp_size == 0)
18030 info_ptr->fp_save_offset = 0;
18032 if (info_ptr->gp_size == 0)
18033 info_ptr->gp_save_offset = 0;
18035 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18036 info_ptr->altivec_save_offset = 0;
18038 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18039 info_ptr->vrsave_save_offset = 0;
18041 if (! TARGET_SPE_ABI
18042 || info_ptr->spe_64bit_regs_used == 0
18043 || info_ptr->spe_gp_size == 0)
18044 info_ptr->spe_gp_save_offset = 0;
18046 if (! info_ptr->lr_save_p)
18047 info_ptr->lr_save_offset = 0;
18049 if (! info_ptr->cr_save_p)
18050 info_ptr->cr_save_offset = 0;
18052 return info_ptr;
18055 /* Return true if the current function uses any GPRs in 64-bit SIMD
18056 mode. */
18058 static bool
18059 spe_func_has_64bit_regs_p (void)
18061 rtx insns, insn;
18063 /* Functions that save and restore all the call-saved registers will
18064 need to save/restore the registers in 64-bits. */
18065 if (crtl->calls_eh_return
18066 || cfun->calls_setjmp
18067 || crtl->has_nonlocal_goto)
18068 return true;
18070 insns = get_insns ();
18072 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18074 if (INSN_P (insn))
18076 rtx i;
18078 /* FIXME: This should be implemented with attributes...
18080 (set_attr "spe64" "true")....then,
18081 if (get_spe64(insn)) return true;
18083 It's the only reliable way to do the stuff below. */
18085 i = PATTERN (insn);
18086 if (GET_CODE (i) == SET)
18088 enum machine_mode mode = GET_MODE (SET_SRC (i));
18090 if (SPE_VECTOR_MODE (mode))
18091 return true;
18092 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18093 return true;
18098 return false;
18101 static void
18102 debug_stack_info (rs6000_stack_t *info)
18104 const char *abi_string;
18106 if (! info)
18107 info = rs6000_stack_info ();
18109 fprintf (stderr, "\nStack information for function %s:\n",
18110 ((current_function_decl && DECL_NAME (current_function_decl))
18111 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18112 : "<unknown>"));
18114 switch (info->abi)
18116 default: abi_string = "Unknown"; break;
18117 case ABI_NONE: abi_string = "NONE"; break;
18118 case ABI_AIX: abi_string = "AIX"; break;
18119 case ABI_DARWIN: abi_string = "Darwin"; break;
18120 case ABI_V4: abi_string = "V.4"; break;
18123 fprintf (stderr, "\tABI = %5s\n", abi_string);
18125 if (TARGET_ALTIVEC_ABI)
18126 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18128 if (TARGET_SPE_ABI)
18129 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18131 if (info->first_gp_reg_save != 32)
18132 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18134 if (info->first_fp_reg_save != 64)
18135 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18137 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18138 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18139 info->first_altivec_reg_save);
18141 if (info->lr_save_p)
18142 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18144 if (info->cr_save_p)
18145 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18147 if (info->vrsave_mask)
18148 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18150 if (info->push_p)
18151 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18153 if (info->calls_p)
18154 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18156 if (info->gp_save_offset)
18157 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18159 if (info->fp_save_offset)
18160 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18162 if (info->altivec_save_offset)
18163 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18164 info->altivec_save_offset);
18166 if (info->spe_gp_save_offset)
18167 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18168 info->spe_gp_save_offset);
18170 if (info->vrsave_save_offset)
18171 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18172 info->vrsave_save_offset);
18174 if (info->lr_save_offset)
18175 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18177 if (info->cr_save_offset)
18178 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18180 if (info->varargs_save_offset)
18181 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18183 if (info->total_size)
18184 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18185 info->total_size);
18187 if (info->vars_size)
18188 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18189 info->vars_size);
18191 if (info->parm_size)
18192 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18194 if (info->fixed_size)
18195 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18197 if (info->gp_size)
18198 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18200 if (info->spe_gp_size)
18201 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18203 if (info->fp_size)
18204 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18206 if (info->altivec_size)
18207 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18209 if (info->vrsave_size)
18210 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18212 if (info->altivec_padding_size)
18213 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18214 info->altivec_padding_size);
18216 if (info->spe_padding_size)
18217 fprintf (stderr, "\tspe_padding_size = %5d\n",
18218 info->spe_padding_size);
18220 if (info->cr_size)
18221 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18223 if (info->save_size)
18224 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18226 if (info->reg_size != 4)
18227 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18229 fprintf (stderr, "\n");
18233 rs6000_return_addr (int count, rtx frame)
18235 /* Currently we don't optimize very well between prolog and body
18236 code and for PIC code the code can be actually quite bad, so
18237 don't try to be too clever here. */
18238 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18240 cfun->machine->ra_needs_full_frame = 1;
18242 return
18243 gen_rtx_MEM
18244 (Pmode,
18245 memory_address
18246 (Pmode,
18247 plus_constant (copy_to_reg
18248 (gen_rtx_MEM (Pmode,
18249 memory_address (Pmode, frame))),
18250 RETURN_ADDRESS_OFFSET)));
18253 cfun->machine->ra_need_lr = 1;
18254 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18257 /* Say whether a function is a candidate for sibcall handling or not.
18258 We do not allow indirect calls to be optimized into sibling calls.
18259 Also, we can't do it if there are any vector parameters; there's
18260 nowhere to put the VRsave code so it works; note that functions with
18261 vector parameters are required to have a prototype, so the argument
18262 type info must be available here. (The tail recursion case can work
18263 with vector parameters, but there's no way to distinguish here.) */
18264 static bool
18265 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18267 tree type;
18268 if (decl)
18270 if (TARGET_ALTIVEC_VRSAVE)
18272 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18273 type; type = TREE_CHAIN (type))
18275 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18276 return false;
18279 if (DEFAULT_ABI == ABI_DARWIN
18280 || ((*targetm.binds_local_p) (decl)
18281 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18283 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18285 if (!lookup_attribute ("longcall", attr_list)
18286 || lookup_attribute ("shortcall", attr_list))
18287 return true;
18290 return false;
18293 /* NULL if INSN insn is valid within a low-overhead loop.
18294 Otherwise return why doloop cannot be applied.
18295 PowerPC uses the COUNT register for branch on table instructions. */
18297 static const char *
18298 rs6000_invalid_within_doloop (const_rtx insn)
18300 if (CALL_P (insn))
18301 return "Function call in the loop.";
18303 if (JUMP_P (insn)
18304 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18305 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18306 return "Computed branch in the loop.";
18308 return NULL;
18311 static int
18312 rs6000_ra_ever_killed (void)
18314 rtx top;
18315 rtx reg;
18316 rtx insn;
18318 if (cfun->is_thunk)
18319 return 0;
18321 if (cfun->machine->lr_save_state)
18322 return cfun->machine->lr_save_state - 1;
18324 /* regs_ever_live has LR marked as used if any sibcalls are present,
18325 but this should not force saving and restoring in the
18326 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18327 clobbers LR, so that is inappropriate. */
18329 /* Also, the prologue can generate a store into LR that
18330 doesn't really count, like this:
18332 move LR->R0
18333 bcl to set PIC register
18334 move LR->R31
18335 move R0->LR
18337 When we're called from the epilogue, we need to avoid counting
18338 this as a store. */
18340 push_topmost_sequence ();
18341 top = get_insns ();
18342 pop_topmost_sequence ();
18343 reg = gen_rtx_REG (Pmode, LR_REGNO);
18345 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18347 if (INSN_P (insn))
18349 if (CALL_P (insn))
18351 if (!SIBLING_CALL_P (insn))
18352 return 1;
18354 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18355 return 1;
18356 else if (set_of (reg, insn) != NULL_RTX
18357 && !prologue_epilogue_contains (insn))
18358 return 1;
18361 return 0;
18364 /* Emit instructions needed to load the TOC register.
18365 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18366 a constant pool; or for SVR4 -fpic. */
18368 void
18369 rs6000_emit_load_toc_table (int fromprolog)
18371 rtx dest;
18372 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18374 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18376 char buf[30];
18377 rtx lab, tmp1, tmp2, got;
18379 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18380 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18381 if (flag_pic == 2)
18382 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18383 else
18384 got = rs6000_got_sym ();
18385 tmp1 = tmp2 = dest;
18386 if (!fromprolog)
18388 tmp1 = gen_reg_rtx (Pmode);
18389 tmp2 = gen_reg_rtx (Pmode);
18391 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18392 emit_move_insn (tmp1,
18393 gen_rtx_REG (Pmode, LR_REGNO));
18394 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18395 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18397 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18399 emit_insn (gen_load_toc_v4_pic_si ());
18400 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18402 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18404 char buf[30];
18405 rtx temp0 = (fromprolog
18406 ? gen_rtx_REG (Pmode, 0)
18407 : gen_reg_rtx (Pmode));
18409 if (fromprolog)
18411 rtx symF, symL;
18413 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18414 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18416 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18417 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18419 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18420 emit_move_insn (dest,
18421 gen_rtx_REG (Pmode, LR_REGNO));
18422 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18424 else
18426 rtx tocsym, lab;
18428 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18429 lab = gen_label_rtx ();
18430 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18431 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18432 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18434 emit_insn (gen_addsi3 (dest, temp0, dest));
18436 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18438 /* This is for AIX code running in non-PIC ELF32. */
18439 char buf[30];
18440 rtx realsym;
18441 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18442 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18444 emit_insn (gen_elf_high (dest, realsym));
18445 emit_insn (gen_elf_low (dest, dest, realsym));
18447 else
18449 gcc_assert (DEFAULT_ABI == ABI_AIX);
18451 if (TARGET_32BIT)
18452 emit_insn (gen_load_toc_aix_si (dest));
18453 else
18454 emit_insn (gen_load_toc_aix_di (dest));
18458 /* Emit instructions to restore the link register after determining where
18459 its value has been stored. */
18461 void
18462 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18464 rs6000_stack_t *info = rs6000_stack_info ();
18465 rtx operands[2];
18467 operands[0] = source;
18468 operands[1] = scratch;
18470 if (info->lr_save_p)
18472 rtx frame_rtx = stack_pointer_rtx;
18473 HOST_WIDE_INT sp_offset = 0;
18474 rtx tmp;
18476 if (frame_pointer_needed
18477 || cfun->calls_alloca
18478 || info->total_size > 32767)
18480 tmp = gen_frame_mem (Pmode, frame_rtx);
18481 emit_move_insn (operands[1], tmp);
18482 frame_rtx = operands[1];
18484 else if (info->push_p)
18485 sp_offset = info->total_size;
18487 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18488 tmp = gen_frame_mem (Pmode, tmp);
18489 emit_move_insn (tmp, operands[0]);
18491 else
18492 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18494 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18495 state of lr_save_p so any change from here on would be a bug. In
18496 particular, stop rs6000_ra_ever_killed from considering the SET
18497 of lr we may have added just above. */
18498 cfun->machine->lr_save_state = info->lr_save_p + 1;
18501 static GTY(()) alias_set_type set = -1;
18503 alias_set_type
18504 get_TOC_alias_set (void)
18506 if (set == -1)
18507 set = new_alias_set ();
18508 return set;
18511 /* This returns nonzero if the current function uses the TOC. This is
18512 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18513 is generated by the ABI_V4 load_toc_* patterns. */
18514 #if TARGET_ELF
18515 static int
18516 uses_TOC (void)
18518 rtx insn;
18520 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18521 if (INSN_P (insn))
18523 rtx pat = PATTERN (insn);
18524 int i;
18526 if (GET_CODE (pat) == PARALLEL)
18527 for (i = 0; i < XVECLEN (pat, 0); i++)
18529 rtx sub = XVECEXP (pat, 0, i);
18530 if (GET_CODE (sub) == USE)
18532 sub = XEXP (sub, 0);
18533 if (GET_CODE (sub) == UNSPEC
18534 && XINT (sub, 1) == UNSPEC_TOC)
18535 return 1;
18539 return 0;
18541 #endif
18544 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18546 rtx tocrel, tocreg;
18548 if (TARGET_DEBUG_ADDR)
18550 if (GET_CODE (symbol) == SYMBOL_REF)
18551 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18552 XSTR (symbol, 0));
18553 else
18555 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18556 GET_RTX_NAME (GET_CODE (symbol)));
18557 debug_rtx (symbol);
18561 if (!can_create_pseudo_p ())
18562 df_set_regs_ever_live (TOC_REGISTER, true);
18564 tocrel = gen_rtx_CONST (Pmode,
18565 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18566 UNSPEC_TOCREL));
18567 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18568 if (TARGET_CMODEL != CMODEL_SMALL)
18570 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18571 if (largetoc_reg != NULL)
18573 emit_move_insn (largetoc_reg, hi);
18574 hi = largetoc_reg;
18576 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18578 else
18579 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18582 /* Issue assembly directives that create a reference to the given DWARF
18583 FRAME_TABLE_LABEL from the current function section. */
18584 void
18585 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18587 fprintf (asm_out_file, "\t.ref %s\n",
18588 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18591 /* If _Unwind_* has been called from within the same module,
18592 toc register is not guaranteed to be saved to 40(1) on function
18593 entry. Save it there in that case. */
18595 void
18596 rs6000_aix_emit_builtin_unwind_init (void)
18598 rtx mem;
18599 rtx stack_top = gen_reg_rtx (Pmode);
18600 rtx opcode_addr = gen_reg_rtx (Pmode);
18601 rtx opcode = gen_reg_rtx (SImode);
18602 rtx tocompare = gen_reg_rtx (SImode);
18603 rtx no_toc_save_needed = gen_label_rtx ();
18605 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18606 emit_move_insn (stack_top, mem);
18608 mem = gen_frame_mem (Pmode,
18609 gen_rtx_PLUS (Pmode, stack_top,
18610 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18611 emit_move_insn (opcode_addr, mem);
18612 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18613 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18614 : 0xE8410028, SImode));
18616 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18617 SImode, NULL_RTX, NULL_RTX,
18618 no_toc_save_needed, -1);
18620 mem = gen_frame_mem (Pmode,
18621 gen_rtx_PLUS (Pmode, stack_top,
18622 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18623 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18624 emit_label (no_toc_save_needed);
18627 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18628 and the change to the stack pointer. */
18630 static void
18631 rs6000_emit_stack_tie (void)
18633 rtx mem = gen_frame_mem (BLKmode,
18634 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18636 emit_insn (gen_stack_tie (mem));
18639 /* Emit the correct code for allocating stack space, as insns.
18640 If COPY_REG, make sure a copy of the old frame is left there.
18641 The generated code may use hard register 0 as a temporary. */
18643 static void
18644 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18646 rtx insn;
18647 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18648 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18649 rtx todec = gen_int_mode (-size, Pmode);
18650 rtx par, set, mem;
18652 if (INTVAL (todec) != -size)
18654 warning (0, "stack frame too large");
18655 emit_insn (gen_trap ());
18656 return;
18659 if (crtl->limit_stack)
18661 if (REG_P (stack_limit_rtx)
18662 && REGNO (stack_limit_rtx) > 1
18663 && REGNO (stack_limit_rtx) <= 31)
18665 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18666 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18667 const0_rtx));
18669 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18670 && TARGET_32BIT
18671 && DEFAULT_ABI == ABI_V4)
18673 rtx toload = gen_rtx_CONST (VOIDmode,
18674 gen_rtx_PLUS (Pmode,
18675 stack_limit_rtx,
18676 GEN_INT (size)));
18678 emit_insn (gen_elf_high (tmp_reg, toload));
18679 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18680 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18681 const0_rtx));
18683 else
18684 warning (0, "stack limit expression is not supported");
18687 if (copy_reg)
18688 emit_move_insn (copy_reg, stack_reg);
18690 if (size > 32767)
18692 /* Need a note here so that try_split doesn't get confused. */
18693 if (get_last_insn () == NULL_RTX)
18694 emit_note (NOTE_INSN_DELETED);
18695 insn = emit_move_insn (tmp_reg, todec);
18696 try_split (PATTERN (insn), insn, 0);
18697 todec = tmp_reg;
18700 insn = emit_insn (TARGET_32BIT
18701 ? gen_movsi_update_stack (stack_reg, stack_reg,
18702 todec, stack_reg)
18703 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18704 todec, stack_reg));
18705 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18706 it now and set the alias set/attributes. The above gen_*_update
18707 calls will generate a PARALLEL with the MEM set being the first
18708 operation. */
18709 par = PATTERN (insn);
18710 gcc_assert (GET_CODE (par) == PARALLEL);
18711 set = XVECEXP (par, 0, 0);
18712 gcc_assert (GET_CODE (set) == SET);
18713 mem = SET_DEST (set);
18714 gcc_assert (MEM_P (mem));
18715 MEM_NOTRAP_P (mem) = 1;
18716 set_mem_alias_set (mem, get_frame_alias_set ());
18718 RTX_FRAME_RELATED_P (insn) = 1;
18719 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18720 gen_rtx_SET (VOIDmode, stack_reg,
18721 gen_rtx_PLUS (Pmode, stack_reg,
18722 GEN_INT (-size))));
18725 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18726 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18727 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18728 deduce these equivalences by itself so it wasn't necessary to hold
18729 its hand so much. */
18731 static void
18732 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18733 rtx reg2, rtx rreg)
18735 rtx real, temp;
18737 /* copy_rtx will not make unique copies of registers, so we need to
18738 ensure we don't have unwanted sharing here. */
18739 if (reg == reg2)
18740 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18742 if (reg == rreg)
18743 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18745 real = copy_rtx (PATTERN (insn));
18747 if (reg2 != NULL_RTX)
18748 real = replace_rtx (real, reg2, rreg);
18750 real = replace_rtx (real, reg,
18751 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18752 STACK_POINTER_REGNUM),
18753 GEN_INT (val)));
18755 /* We expect that 'real' is either a SET or a PARALLEL containing
18756 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18757 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18759 if (GET_CODE (real) == SET)
18761 rtx set = real;
18763 temp = simplify_rtx (SET_SRC (set));
18764 if (temp)
18765 SET_SRC (set) = temp;
18766 temp = simplify_rtx (SET_DEST (set));
18767 if (temp)
18768 SET_DEST (set) = temp;
18769 if (GET_CODE (SET_DEST (set)) == MEM)
18771 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18772 if (temp)
18773 XEXP (SET_DEST (set), 0) = temp;
18776 else
18778 int i;
18780 gcc_assert (GET_CODE (real) == PARALLEL);
18781 for (i = 0; i < XVECLEN (real, 0); i++)
18782 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18784 rtx set = XVECEXP (real, 0, i);
18786 temp = simplify_rtx (SET_SRC (set));
18787 if (temp)
18788 SET_SRC (set) = temp;
18789 temp = simplify_rtx (SET_DEST (set));
18790 if (temp)
18791 SET_DEST (set) = temp;
18792 if (GET_CODE (SET_DEST (set)) == MEM)
18794 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18795 if (temp)
18796 XEXP (SET_DEST (set), 0) = temp;
18798 RTX_FRAME_RELATED_P (set) = 1;
18802 RTX_FRAME_RELATED_P (insn) = 1;
18803 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18806 /* Returns an insn that has a vrsave set operation with the
18807 appropriate CLOBBERs. */
18809 static rtx
18810 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18812 int nclobs, i;
18813 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18814 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18816 clobs[0]
18817 = gen_rtx_SET (VOIDmode,
18818 vrsave,
18819 gen_rtx_UNSPEC_VOLATILE (SImode,
18820 gen_rtvec (2, reg, vrsave),
18821 UNSPECV_SET_VRSAVE));
18823 nclobs = 1;
18825 /* We need to clobber the registers in the mask so the scheduler
18826 does not move sets to VRSAVE before sets of AltiVec registers.
18828 However, if the function receives nonlocal gotos, reload will set
18829 all call saved registers live. We will end up with:
18831 (set (reg 999) (mem))
18832 (parallel [ (set (reg vrsave) (unspec blah))
18833 (clobber (reg 999))])
18835 The clobber will cause the store into reg 999 to be dead, and
18836 flow will attempt to delete an epilogue insn. In this case, we
18837 need an unspec use/set of the register. */
18839 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18840 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18842 if (!epiloguep || call_used_regs [i])
18843 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18844 gen_rtx_REG (V4SImode, i));
18845 else
18847 rtx reg = gen_rtx_REG (V4SImode, i);
18849 clobs[nclobs++]
18850 = gen_rtx_SET (VOIDmode,
18851 reg,
18852 gen_rtx_UNSPEC (V4SImode,
18853 gen_rtvec (1, reg), 27));
18857 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18859 for (i = 0; i < nclobs; ++i)
18860 XVECEXP (insn, 0, i) = clobs[i];
18862 return insn;
18865 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18866 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18868 static void
18869 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18870 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18872 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18873 rtx replacea, replaceb;
18875 int_rtx = GEN_INT (offset);
18877 /* Some cases that need register indexed addressing. */
18878 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18879 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18880 || (TARGET_E500_DOUBLE && mode == DFmode)
18881 || (TARGET_SPE_ABI
18882 && SPE_VECTOR_MODE (mode)
18883 && !SPE_CONST_OFFSET_OK (offset)))
18885 /* Whomever calls us must make sure r11 is available in the
18886 flow path of instructions in the prologue. */
18887 offset_rtx = gen_rtx_REG (Pmode, 11);
18888 emit_move_insn (offset_rtx, int_rtx);
18890 replacea = offset_rtx;
18891 replaceb = int_rtx;
18893 else
18895 offset_rtx = int_rtx;
18896 replacea = NULL_RTX;
18897 replaceb = NULL_RTX;
18900 reg = gen_rtx_REG (mode, regno);
18901 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18902 mem = gen_frame_mem (mode, addr);
18904 insn = emit_move_insn (mem, reg);
18906 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18909 /* Emit an offset memory reference suitable for a frame store, while
18910 converting to a valid addressing mode. */
18912 static rtx
18913 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18915 rtx int_rtx, offset_rtx;
18917 int_rtx = GEN_INT (offset);
18919 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18920 || (TARGET_E500_DOUBLE && mode == DFmode))
18922 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18923 emit_move_insn (offset_rtx, int_rtx);
18925 else
18926 offset_rtx = int_rtx;
18928 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18931 /* Look for user-defined global regs. We should not save and restore these,
18932 and cannot use stmw/lmw if there are any in its range. */
18934 static bool
18935 no_global_regs_above (int first, bool gpr)
18937 int i;
18938 int last = gpr ? 32 : 64;
18939 for (i = first; i < last; i++)
18940 if (global_regs[i])
18941 return false;
18942 return true;
18945 #ifndef TARGET_FIX_AND_CONTINUE
18946 #define TARGET_FIX_AND_CONTINUE 0
18947 #endif
18949 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18950 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18951 #define LAST_SAVRES_REGISTER 31
18952 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18954 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18956 /* Temporary holding space for an out-of-line register save/restore
18957 routine name. */
18958 static char savres_routine_name[30];
18960 /* Return the name for an out-of-line register save/restore routine.
18961 We are saving/restoring GPRs if GPR is true. */
18963 static char *
18964 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18965 bool savep, bool gpr, bool lr)
18967 const char *prefix = "";
18968 const char *suffix = "";
18970 /* Different targets are supposed to define
18971 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18972 routine name could be defined with:
18974 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18976 This is a nice idea in practice, but in reality, things are
18977 complicated in several ways:
18979 - ELF targets have save/restore routines for GPRs.
18981 - SPE targets use different prefixes for 32/64-bit registers, and
18982 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18984 - PPC64 ELF targets have routines for save/restore of GPRs that
18985 differ in what they do with the link register, so having a set
18986 prefix doesn't work. (We only use one of the save routines at
18987 the moment, though.)
18989 - PPC32 elf targets have "exit" versions of the restore routines
18990 that restore the link register and can save some extra space.
18991 These require an extra suffix. (There are also "tail" versions
18992 of the restore routines and "GOT" versions of the save routines,
18993 but we don't generate those at present. Same problems apply,
18994 though.)
18996 We deal with all this by synthesizing our own prefix/suffix and
18997 using that for the simple sprintf call shown above. */
18998 if (TARGET_SPE)
19000 /* No floating point saves on the SPE. */
19001 gcc_assert (gpr);
19003 if (savep)
19004 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19005 else
19006 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19008 if (lr)
19009 suffix = "_x";
19011 else if (DEFAULT_ABI == ABI_V4)
19013 if (TARGET_64BIT)
19014 goto aix_names;
19016 if (gpr)
19017 prefix = savep ? "_savegpr_" : "_restgpr_";
19018 else
19019 prefix = savep ? "_savefpr_" : "_restfpr_";
19021 if (lr)
19022 suffix = "_x";
19024 else if (DEFAULT_ABI == ABI_AIX)
19026 #ifndef POWERPC_LINUX
19027 /* No out-of-line save/restore routines for GPRs on AIX. */
19028 gcc_assert (!TARGET_AIX || !gpr);
19029 #endif
19031 aix_names:
19032 if (gpr)
19033 prefix = (savep
19034 ? (lr ? "_savegpr0_" : "_savegpr1_")
19035 : (lr ? "_restgpr0_" : "_restgpr1_"));
19036 #ifdef POWERPC_LINUX
19037 else if (lr)
19038 prefix = (savep ? "_savefpr_" : "_restfpr_");
19039 #endif
19040 else
19042 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19043 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19046 else if (DEFAULT_ABI == ABI_DARWIN)
19047 sorry ("Out-of-line save/restore routines not supported on Darwin");
19049 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19051 return savres_routine_name;
19054 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19055 We are saving/restoring GPRs if GPR is true. */
19057 static rtx
19058 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19059 bool gpr, bool lr)
19061 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19062 rtx sym;
19063 int select = ((savep ? 1 : 0) << 2
19064 | ((TARGET_SPE_ABI
19065 /* On the SPE, we never have any FPRs, but we do have
19066 32/64-bit versions of the routines. */
19067 ? (info->spe_64bit_regs_used ? 1 : 0)
19068 : (gpr ? 1 : 0)) << 1)
19069 | (lr ? 1: 0));
19071 /* Don't generate bogus routine names. */
19072 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19073 && regno <= LAST_SAVRES_REGISTER);
19075 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19077 if (sym == NULL)
19079 char *name;
19081 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19083 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19084 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19085 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19088 return sym;
19091 /* Emit a sequence of insns, including a stack tie if needed, for
19092 resetting the stack pointer. If SAVRES is true, then don't reset the
19093 stack pointer, but move the base of the frame into r11 for use by
19094 out-of-line register restore routines. */
19096 static rtx
19097 rs6000_emit_stack_reset (rs6000_stack_t *info,
19098 rtx sp_reg_rtx, rtx frame_reg_rtx,
19099 int sp_offset, bool savres)
19101 /* This blockage is needed so that sched doesn't decide to move
19102 the sp change before the register restores. */
19103 if (frame_reg_rtx != sp_reg_rtx
19104 || (TARGET_SPE_ABI
19105 && info->spe_64bit_regs_used != 0
19106 && info->first_gp_reg_save != 32))
19107 rs6000_emit_stack_tie ();
19109 if (frame_reg_rtx != sp_reg_rtx)
19111 if (sp_offset != 0)
19113 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19114 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19115 GEN_INT (sp_offset)));
19117 else if (!savres)
19118 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19120 else if (sp_offset != 0)
19122 /* If we are restoring registers out-of-line, we will be using the
19123 "exit" variants of the restore routines, which will reset the
19124 stack for us. But we do need to point r11 into the right place
19125 for those routines. */
19126 rtx dest_reg = (savres
19127 ? gen_rtx_REG (Pmode, 11)
19128 : sp_reg_rtx);
19130 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19131 GEN_INT (sp_offset)));
19132 if (!savres)
19133 return insn;
19135 return NULL_RTX;
19138 /* Construct a parallel rtx describing the effect of a call to an
19139 out-of-line register save/restore routine. */
19141 static rtx
19142 rs6000_make_savres_rtx (rs6000_stack_t *info,
19143 rtx frame_reg_rtx, int save_area_offset,
19144 enum machine_mode reg_mode,
19145 bool savep, bool gpr, bool lr)
19147 int i;
19148 int offset, start_reg, end_reg, n_regs;
19149 int reg_size = GET_MODE_SIZE (reg_mode);
19150 rtx sym;
19151 rtvec p;
19153 offset = 0;
19154 start_reg = (gpr
19155 ? info->first_gp_reg_save
19156 : info->first_fp_reg_save);
19157 end_reg = gpr ? 32 : 64;
19158 n_regs = end_reg - start_reg;
19159 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19161 if (!savep && lr)
19162 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19164 RTVEC_ELT (p, offset++)
19165 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19167 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19168 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19169 RTVEC_ELT (p, offset++)
19170 = gen_rtx_USE (VOIDmode,
19171 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19172 : gpr && !lr ? 12
19173 : 1));
19175 for (i = 0; i < end_reg - start_reg; i++)
19177 rtx addr, reg, mem;
19178 reg = gen_rtx_REG (reg_mode, start_reg + i);
19179 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19180 GEN_INT (save_area_offset + reg_size*i));
19181 mem = gen_frame_mem (reg_mode, addr);
19183 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19184 savep ? mem : reg,
19185 savep ? reg : mem);
19188 if (savep && lr)
19190 rtx addr, reg, mem;
19191 reg = gen_rtx_REG (Pmode, 0);
19192 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19193 GEN_INT (info->lr_save_offset));
19194 mem = gen_frame_mem (Pmode, addr);
19195 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19198 return gen_rtx_PARALLEL (VOIDmode, p);
19201 /* Determine whether the gp REG is really used. */
19203 static bool
19204 rs6000_reg_live_or_pic_offset_p (int reg)
19206 return ((df_regs_ever_live_p (reg)
19207 && (!call_used_regs[reg]
19208 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19209 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19210 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19211 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19212 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19215 enum {
19216 SAVRES_MULTIPLE = 0x1,
19217 SAVRES_INLINE_FPRS = 0x2,
19218 SAVRES_INLINE_GPRS = 0x4,
19219 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19220 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19221 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19224 /* Determine the strategy for savings/restoring registers. */
19226 static int
19227 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19228 int using_static_chain_p, int sibcall)
19230 bool using_multiple_p;
19231 bool common;
19232 bool savres_fprs_inline;
19233 bool savres_gprs_inline;
19234 bool noclobber_global_gprs
19235 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19236 int strategy;
19238 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19239 && (!TARGET_SPE_ABI
19240 || info->spe_64bit_regs_used == 0)
19241 && info->first_gp_reg_save < 31
19242 && noclobber_global_gprs);
19243 /* Don't bother to try to save things out-of-line if r11 is occupied
19244 by the static chain. It would require too much fiddling and the
19245 static chain is rarely used anyway. */
19246 common = (using_static_chain_p
19247 || sibcall
19248 || crtl->calls_eh_return
19249 || !info->lr_save_p
19250 || cfun->machine->ra_need_lr
19251 || info->total_size > 32767);
19252 savres_fprs_inline = (common
19253 || info->first_fp_reg_save == 64
19254 || !no_global_regs_above (info->first_fp_reg_save,
19255 /*gpr=*/false)
19256 /* The out-of-line FP routines use
19257 double-precision stores; we can't use those
19258 routines if we don't have such stores. */
19259 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19260 || FP_SAVE_INLINE (info->first_fp_reg_save));
19261 savres_gprs_inline = (common
19262 /* Saving CR interferes with the exit routines
19263 used on the SPE, so just punt here. */
19264 || (!savep
19265 && TARGET_SPE_ABI
19266 && info->spe_64bit_regs_used != 0
19267 && info->cr_save_p != 0)
19268 || info->first_gp_reg_save == 32
19269 || !noclobber_global_gprs
19270 || GP_SAVE_INLINE (info->first_gp_reg_save));
19272 if (savep)
19273 /* If we are going to use store multiple, then don't even bother
19274 with the out-of-line routines, since the store-multiple instruction
19275 will always be smaller. */
19276 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19277 else
19279 /* The situation is more complicated with load multiple. We'd
19280 prefer to use the out-of-line routines for restores, since the
19281 "exit" out-of-line routines can handle the restore of LR and
19282 the frame teardown. But we can only use the out-of-line
19283 routines if we know that we've used store multiple or
19284 out-of-line routines in the prologue, i.e. if we've saved all
19285 the registers from first_gp_reg_save. Otherwise, we risk
19286 loading garbage from the stack. Furthermore, we can only use
19287 the "exit" out-of-line gpr restore if we haven't saved any
19288 fprs. */
19289 bool saved_all = !savres_gprs_inline || using_multiple_p;
19291 if (saved_all && info->first_fp_reg_save != 64)
19292 /* We can't use the exit routine; use load multiple if it's
19293 available. */
19294 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19297 strategy = (using_multiple_p
19298 | (savres_fprs_inline << 1)
19299 | (savres_gprs_inline << 2));
19300 #ifdef POWERPC_LINUX
19301 if (TARGET_64BIT)
19303 if (!savres_fprs_inline)
19304 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19305 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19306 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19308 #else
19309 if (TARGET_AIX && !savres_fprs_inline)
19310 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19311 #endif
19312 return strategy;
19315 /* Emit function prologue as insns. */
19317 void
19318 rs6000_emit_prologue (void)
19320 rs6000_stack_t *info = rs6000_stack_info ();
19321 enum machine_mode reg_mode = Pmode;
19322 int reg_size = TARGET_32BIT ? 4 : 8;
19323 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19324 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19325 rtx frame_reg_rtx = sp_reg_rtx;
19326 rtx cr_save_rtx = NULL_RTX;
19327 rtx insn;
19328 int strategy;
19329 int saving_FPRs_inline;
19330 int saving_GPRs_inline;
19331 int using_store_multiple;
19332 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19333 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19334 && call_used_regs[STATIC_CHAIN_REGNUM]);
19335 HOST_WIDE_INT sp_offset = 0;
19337 if (TARGET_FIX_AND_CONTINUE)
19339 /* gdb on darwin arranges to forward a function from the old
19340 address by modifying the first 5 instructions of the function
19341 to branch to the overriding function. This is necessary to
19342 permit function pointers that point to the old function to
19343 actually forward to the new function. */
19344 emit_insn (gen_nop ());
19345 emit_insn (gen_nop ());
19346 emit_insn (gen_nop ());
19347 emit_insn (gen_nop ());
19348 emit_insn (gen_nop ());
19351 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19353 reg_mode = V2SImode;
19354 reg_size = 8;
19357 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19358 /*static_chain_p=*/using_static_chain_p,
19359 /*sibcall=*/0);
19360 using_store_multiple = strategy & SAVRES_MULTIPLE;
19361 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19362 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19364 /* For V.4, update stack before we do any saving and set back pointer. */
19365 if (! WORLD_SAVE_P (info)
19366 && info->push_p
19367 && (DEFAULT_ABI == ABI_V4
19368 || crtl->calls_eh_return))
19370 bool need_r11 = (TARGET_SPE
19371 ? (!saving_GPRs_inline
19372 && info->spe_64bit_regs_used == 0)
19373 : (!saving_FPRs_inline || !saving_GPRs_inline));
19374 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19376 if (info->total_size < 32767)
19377 sp_offset = info->total_size;
19378 else if (need_r11)
19379 frame_reg_rtx = copy_reg;
19380 else if (info->cr_save_p
19381 || info->lr_save_p
19382 || info->first_fp_reg_save < 64
19383 || info->first_gp_reg_save < 32
19384 || info->altivec_size != 0
19385 || info->vrsave_mask != 0
19386 || crtl->calls_eh_return)
19388 copy_reg = frame_ptr_rtx;
19389 frame_reg_rtx = copy_reg;
19391 else
19393 /* The prologue won't be saving any regs so there is no need
19394 to set up a frame register to access any frame save area.
19395 We also won't be using sp_offset anywhere below, but set
19396 the correct value anyway to protect against future
19397 changes to this function. */
19398 sp_offset = info->total_size;
19400 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19401 if (frame_reg_rtx != sp_reg_rtx)
19402 rs6000_emit_stack_tie ();
19405 /* Handle world saves specially here. */
19406 if (WORLD_SAVE_P (info))
19408 int i, j, sz;
19409 rtx treg;
19410 rtvec p;
19411 rtx reg0;
19413 /* save_world expects lr in r0. */
19414 reg0 = gen_rtx_REG (Pmode, 0);
19415 if (info->lr_save_p)
19417 insn = emit_move_insn (reg0,
19418 gen_rtx_REG (Pmode, LR_REGNO));
19419 RTX_FRAME_RELATED_P (insn) = 1;
19422 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19423 assumptions about the offsets of various bits of the stack
19424 frame. */
19425 gcc_assert (info->gp_save_offset == -220
19426 && info->fp_save_offset == -144
19427 && info->lr_save_offset == 8
19428 && info->cr_save_offset == 4
19429 && info->push_p
19430 && info->lr_save_p
19431 && (!crtl->calls_eh_return
19432 || info->ehrd_offset == -432)
19433 && info->vrsave_save_offset == -224
19434 && info->altivec_save_offset == -416);
19436 treg = gen_rtx_REG (SImode, 11);
19437 emit_move_insn (treg, GEN_INT (-info->total_size));
19439 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19440 in R11. It also clobbers R12, so beware! */
19442 /* Preserve CR2 for save_world prologues */
19443 sz = 5;
19444 sz += 32 - info->first_gp_reg_save;
19445 sz += 64 - info->first_fp_reg_save;
19446 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19447 p = rtvec_alloc (sz);
19448 j = 0;
19449 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19450 gen_rtx_REG (SImode,
19451 LR_REGNO));
19452 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19453 gen_rtx_SYMBOL_REF (Pmode,
19454 "*save_world"));
19455 /* We do floats first so that the instruction pattern matches
19456 properly. */
19457 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19459 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19460 ? DFmode : SFmode),
19461 info->first_fp_reg_save + i);
19462 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19463 GEN_INT (info->fp_save_offset
19464 + sp_offset + 8 * i));
19465 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19466 ? DFmode : SFmode), addr);
19468 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19470 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19472 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19473 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19474 GEN_INT (info->altivec_save_offset
19475 + sp_offset + 16 * i));
19476 rtx mem = gen_frame_mem (V4SImode, addr);
19478 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19480 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19482 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19483 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19484 GEN_INT (info->gp_save_offset
19485 + sp_offset + reg_size * i));
19486 rtx mem = gen_frame_mem (reg_mode, addr);
19488 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19492 /* CR register traditionally saved as CR2. */
19493 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19494 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19495 GEN_INT (info->cr_save_offset
19496 + sp_offset));
19497 rtx mem = gen_frame_mem (reg_mode, addr);
19499 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19501 /* Explain about use of R0. */
19502 if (info->lr_save_p)
19504 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19505 GEN_INT (info->lr_save_offset
19506 + sp_offset));
19507 rtx mem = gen_frame_mem (reg_mode, addr);
19509 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19511 /* Explain what happens to the stack pointer. */
19513 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19514 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19517 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19518 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19519 treg, GEN_INT (-info->total_size));
19520 sp_offset = info->total_size;
19523 /* If we use the link register, get it into r0. */
19524 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19526 rtx addr, reg, mem;
19528 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19529 gen_rtx_REG (Pmode, LR_REGNO));
19530 RTX_FRAME_RELATED_P (insn) = 1;
19532 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
19533 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
19535 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19536 GEN_INT (info->lr_save_offset + sp_offset));
19537 reg = gen_rtx_REG (Pmode, 0);
19538 mem = gen_rtx_MEM (Pmode, addr);
19539 /* This should not be of rs6000_sr_alias_set, because of
19540 __builtin_return_address. */
19542 insn = emit_move_insn (mem, reg);
19543 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19544 NULL_RTX, NULL_RTX);
19548 /* If we need to save CR, put it into r12 or r11. */
19549 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
19551 rtx set;
19553 cr_save_rtx
19554 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
19555 ? 11 : 12);
19556 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19557 RTX_FRAME_RELATED_P (insn) = 1;
19558 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19559 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19560 But that's OK. All we have to do is specify that _one_ condition
19561 code register is saved in this stack slot. The thrower's epilogue
19562 will then restore all the call-saved registers.
19563 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19564 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
19565 gen_rtx_REG (SImode, CR2_REGNO));
19566 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19569 /* Do any required saving of fpr's. If only one or two to save, do
19570 it ourselves. Otherwise, call function. */
19571 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
19573 int i;
19574 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19575 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19576 && ! call_used_regs[info->first_fp_reg_save+i]))
19577 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
19578 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19579 ? DFmode : SFmode,
19580 info->first_fp_reg_save + i,
19581 info->fp_save_offset + sp_offset + 8 * i,
19582 info->total_size);
19584 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
19586 rtx par;
19588 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19589 info->fp_save_offset + sp_offset,
19590 DFmode,
19591 /*savep=*/true, /*gpr=*/false,
19592 /*lr=*/(strategy
19593 & SAVRES_NOINLINE_FPRS_SAVES_LR)
19594 != 0);
19595 insn = emit_insn (par);
19596 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19597 NULL_RTX, NULL_RTX);
19600 /* Save GPRs. This is done as a PARALLEL if we are using
19601 the store-multiple instructions. */
19602 if (!WORLD_SAVE_P (info)
19603 && TARGET_SPE_ABI
19604 && info->spe_64bit_regs_used != 0
19605 && info->first_gp_reg_save != 32)
19607 int i;
19608 rtx spe_save_area_ptr;
19610 /* Determine whether we can address all of the registers that need
19611 to be saved with an offset from the stack pointer that fits in
19612 the small const field for SPE memory instructions. */
19613 int spe_regs_addressable_via_sp
19614 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19615 + (32 - info->first_gp_reg_save - 1) * reg_size)
19616 && saving_GPRs_inline);
19617 int spe_offset;
19619 if (spe_regs_addressable_via_sp)
19621 spe_save_area_ptr = frame_reg_rtx;
19622 spe_offset = info->spe_gp_save_offset + sp_offset;
19624 else
19626 /* Make r11 point to the start of the SPE save area. We need
19627 to be careful here if r11 is holding the static chain. If
19628 it is, then temporarily save it in r0. We would use r0 as
19629 our base register here, but using r0 as a base register in
19630 loads and stores means something different from what we
19631 would like. */
19632 int ool_adjust = (saving_GPRs_inline
19634 : (info->first_gp_reg_save
19635 - (FIRST_SAVRES_REGISTER+1))*8);
19636 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19637 + sp_offset - ool_adjust);
19639 if (using_static_chain_p)
19641 rtx r0 = gen_rtx_REG (Pmode, 0);
19642 gcc_assert (info->first_gp_reg_save > 11);
19644 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19647 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19648 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19649 frame_reg_rtx,
19650 GEN_INT (offset)));
19651 /* We need to make sure the move to r11 gets noted for
19652 properly outputting unwind information. */
19653 if (!saving_GPRs_inline)
19654 rs6000_frame_related (insn, frame_reg_rtx, offset,
19655 NULL_RTX, NULL_RTX);
19656 spe_offset = 0;
19659 if (saving_GPRs_inline)
19661 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19662 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19664 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19665 rtx offset, addr, mem;
19667 /* We're doing all this to ensure that the offset fits into
19668 the immediate offset of 'evstdd'. */
19669 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19671 offset = GEN_INT (reg_size * i + spe_offset);
19672 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19673 mem = gen_rtx_MEM (V2SImode, addr);
19675 insn = emit_move_insn (mem, reg);
19677 rs6000_frame_related (insn, spe_save_area_ptr,
19678 info->spe_gp_save_offset
19679 + sp_offset + reg_size * i,
19680 offset, const0_rtx);
19683 else
19685 rtx par;
19687 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19688 0, reg_mode,
19689 /*savep=*/true, /*gpr=*/true,
19690 /*lr=*/false);
19691 insn = emit_insn (par);
19692 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19693 NULL_RTX, NULL_RTX);
19697 /* Move the static chain pointer back. */
19698 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19699 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19701 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19703 rtx par;
19705 /* Need to adjust r11 (r12) if we saved any FPRs. */
19706 if (info->first_fp_reg_save != 64)
19708 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19709 ? 12 : 11);
19710 rtx offset = GEN_INT (sp_offset
19711 + (-8 * (64-info->first_fp_reg_save)));
19712 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19715 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19716 info->gp_save_offset + sp_offset,
19717 reg_mode,
19718 /*savep=*/true, /*gpr=*/true,
19719 /*lr=*/(strategy
19720 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19721 != 0);
19722 insn = emit_insn (par);
19723 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19724 NULL_RTX, NULL_RTX);
19726 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19728 rtvec p;
19729 int i;
19730 p = rtvec_alloc (32 - info->first_gp_reg_save);
19731 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19733 rtx addr, reg, mem;
19734 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19735 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19736 GEN_INT (info->gp_save_offset
19737 + sp_offset
19738 + reg_size * i));
19739 mem = gen_frame_mem (reg_mode, addr);
19741 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19743 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19744 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19745 NULL_RTX, NULL_RTX);
19747 else if (!WORLD_SAVE_P (info))
19749 int i;
19750 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19751 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19753 rtx addr, reg, mem;
19754 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19756 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19757 GEN_INT (info->gp_save_offset
19758 + sp_offset
19759 + reg_size * i));
19760 mem = gen_frame_mem (reg_mode, addr);
19762 insn = emit_move_insn (mem, reg);
19763 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19764 NULL_RTX, NULL_RTX);
19768 /* ??? There's no need to emit actual instructions here, but it's the
19769 easiest way to get the frame unwind information emitted. */
19770 if (crtl->calls_eh_return)
19772 unsigned int i, regno;
19774 /* In AIX ABI we need to pretend we save r2 here. */
19775 if (TARGET_AIX)
19777 rtx addr, reg, mem;
19779 reg = gen_rtx_REG (reg_mode, 2);
19780 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19781 GEN_INT (sp_offset + 5 * reg_size));
19782 mem = gen_frame_mem (reg_mode, addr);
19784 insn = emit_move_insn (mem, reg);
19785 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19786 NULL_RTX, NULL_RTX);
19787 PATTERN (insn) = gen_blockage ();
19790 for (i = 0; ; ++i)
19792 regno = EH_RETURN_DATA_REGNO (i);
19793 if (regno == INVALID_REGNUM)
19794 break;
19796 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19797 info->ehrd_offset + sp_offset
19798 + reg_size * (int) i,
19799 info->total_size);
19803 /* Save CR if we use any that must be preserved. */
19804 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19806 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19807 GEN_INT (info->cr_save_offset + sp_offset));
19808 rtx mem = gen_frame_mem (SImode, addr);
19809 /* See the large comment above about why CR2_REGNO is used. */
19810 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19812 /* If r12 was used to hold the original sp, copy cr into r0 now
19813 that it's free. */
19814 if (REGNO (frame_reg_rtx) == 12)
19816 rtx set;
19818 cr_save_rtx = gen_rtx_REG (SImode, 0);
19819 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19820 RTX_FRAME_RELATED_P (insn) = 1;
19821 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19822 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19824 insn = emit_move_insn (mem, cr_save_rtx);
19826 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19827 NULL_RTX, NULL_RTX);
19830 /* Update stack and set back pointer unless this is V.4,
19831 for which it was done previously. */
19832 if (!WORLD_SAVE_P (info) && info->push_p
19833 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19835 rtx copy_reg = NULL;
19837 if (info->total_size < 32767)
19838 sp_offset = info->total_size;
19839 else if (info->altivec_size != 0
19840 || info->vrsave_mask != 0)
19842 copy_reg = frame_ptr_rtx;
19843 frame_reg_rtx = copy_reg;
19845 else
19846 sp_offset = info->total_size;
19847 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19848 if (frame_reg_rtx != sp_reg_rtx)
19849 rs6000_emit_stack_tie ();
19852 /* Set frame pointer, if needed. */
19853 if (frame_pointer_needed)
19855 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19856 sp_reg_rtx);
19857 RTX_FRAME_RELATED_P (insn) = 1;
19860 /* Save AltiVec registers if needed. Save here because the red zone does
19861 not include AltiVec registers. */
19862 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19864 int i;
19866 /* There should be a non inline version of this, for when we
19867 are saving lots of vector registers. */
19868 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19869 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19871 rtx areg, savereg, mem;
19872 int offset;
19874 offset = info->altivec_save_offset + sp_offset
19875 + 16 * (i - info->first_altivec_reg_save);
19877 savereg = gen_rtx_REG (V4SImode, i);
19879 areg = gen_rtx_REG (Pmode, 0);
19880 emit_move_insn (areg, GEN_INT (offset));
19882 /* AltiVec addressing mode is [reg+reg]. */
19883 mem = gen_frame_mem (V4SImode,
19884 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19886 insn = emit_move_insn (mem, savereg);
19888 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19889 areg, GEN_INT (offset));
19893 /* VRSAVE is a bit vector representing which AltiVec registers
19894 are used. The OS uses this to determine which vector
19895 registers to save on a context switch. We need to save
19896 VRSAVE on the stack frame, add whatever AltiVec registers we
19897 used in this function, and do the corresponding magic in the
19898 epilogue. */
19900 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19901 && info->vrsave_mask != 0)
19903 rtx reg, mem, vrsave;
19904 int offset;
19906 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19907 as frame_reg_rtx and r11 as the static chain pointer for
19908 nested functions. */
19909 reg = gen_rtx_REG (SImode, 0);
19910 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19911 if (TARGET_MACHO)
19912 emit_insn (gen_get_vrsave_internal (reg));
19913 else
19914 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19916 if (!WORLD_SAVE_P (info))
19918 /* Save VRSAVE. */
19919 offset = info->vrsave_save_offset + sp_offset;
19920 mem = gen_frame_mem (SImode,
19921 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19922 GEN_INT (offset)));
19923 insn = emit_move_insn (mem, reg);
19926 /* Include the registers in the mask. */
19927 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19929 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19932 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19933 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19934 || (DEFAULT_ABI == ABI_V4
19935 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19936 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19938 /* If emit_load_toc_table will use the link register, we need to save
19939 it. We use R12 for this purpose because emit_load_toc_table
19940 can use register 0. This allows us to use a plain 'blr' to return
19941 from the procedure more often. */
19942 int save_LR_around_toc_setup = (TARGET_ELF
19943 && DEFAULT_ABI != ABI_AIX
19944 && flag_pic
19945 && ! info->lr_save_p
19946 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19947 if (save_LR_around_toc_setup)
19949 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19951 insn = emit_move_insn (frame_ptr_rtx, lr);
19952 RTX_FRAME_RELATED_P (insn) = 1;
19954 rs6000_emit_load_toc_table (TRUE);
19956 insn = emit_move_insn (lr, frame_ptr_rtx);
19957 RTX_FRAME_RELATED_P (insn) = 1;
19959 else
19960 rs6000_emit_load_toc_table (TRUE);
19963 #if TARGET_MACHO
19964 if (DEFAULT_ABI == ABI_DARWIN
19965 && flag_pic && crtl->uses_pic_offset_table)
19967 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19968 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19970 /* Save and restore LR locally around this call (in R0). */
19971 if (!info->lr_save_p)
19972 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19974 emit_insn (gen_load_macho_picbase (src));
19976 emit_move_insn (gen_rtx_REG (Pmode,
19977 RS6000_PIC_OFFSET_TABLE_REGNUM),
19978 lr);
19980 if (!info->lr_save_p)
19981 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19983 #endif
19986 /* Write function prologue. */
19988 static void
19989 rs6000_output_function_prologue (FILE *file,
19990 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19992 rs6000_stack_t *info = rs6000_stack_info ();
19994 if (TARGET_DEBUG_STACK)
19995 debug_stack_info (info);
19997 /* Write .extern for any function we will call to save and restore
19998 fp values. */
19999 if (info->first_fp_reg_save < 64
20000 && !FP_SAVE_INLINE (info->first_fp_reg_save))
20002 char *name;
20003 int regno = info->first_fp_reg_save - 32;
20005 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20006 /*gpr=*/false, /*lr=*/false);
20007 fprintf (file, "\t.extern %s\n", name);
20009 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20010 /*gpr=*/false, /*lr=*/true);
20011 fprintf (file, "\t.extern %s\n", name);
20014 /* Write .extern for AIX common mode routines, if needed. */
20015 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20017 fputs ("\t.extern __mulh\n", file);
20018 fputs ("\t.extern __mull\n", file);
20019 fputs ("\t.extern __divss\n", file);
20020 fputs ("\t.extern __divus\n", file);
20021 fputs ("\t.extern __quoss\n", file);
20022 fputs ("\t.extern __quous\n", file);
20023 common_mode_defined = 1;
20026 if (! HAVE_prologue)
20028 rtx prologue;
20030 start_sequence ();
20032 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20033 the "toplevel" insn chain. */
20034 emit_note (NOTE_INSN_DELETED);
20035 rs6000_emit_prologue ();
20036 emit_note (NOTE_INSN_DELETED);
20038 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20040 rtx insn;
20041 unsigned addr = 0;
20042 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20044 INSN_ADDRESSES_NEW (insn, addr);
20045 addr += 4;
20049 prologue = get_insns ();
20050 end_sequence ();
20052 if (TARGET_DEBUG_STACK)
20053 debug_rtx_list (prologue, 100);
20055 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20056 ENTRY_BLOCK_PTR);
20059 rs6000_pic_labelno++;
20062 /* Non-zero if vmx regs are restored before the frame pop, zero if
20063 we restore after the pop when possible. */
20064 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20066 /* Reload CR from REG. */
20068 static void
20069 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20071 int count = 0;
20072 int i;
20074 if (using_mfcr_multiple)
20076 for (i = 0; i < 8; i++)
20077 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20078 count++;
20079 gcc_assert (count);
20082 if (using_mfcr_multiple && count > 1)
20084 rtvec p;
20085 int ndx;
20087 p = rtvec_alloc (count);
20089 ndx = 0;
20090 for (i = 0; i < 8; i++)
20091 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20093 rtvec r = rtvec_alloc (2);
20094 RTVEC_ELT (r, 0) = reg;
20095 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20096 RTVEC_ELT (p, ndx) =
20097 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20098 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20099 ndx++;
20101 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20102 gcc_assert (ndx == count);
20104 else
20105 for (i = 0; i < 8; i++)
20106 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20108 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20109 CR0_REGNO+i),
20110 reg));
20114 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20115 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20116 below stack pointer not cloberred by signals. */
20118 static inline bool
20119 offset_below_red_zone_p (HOST_WIDE_INT offset)
20121 return offset < (DEFAULT_ABI == ABI_V4
20123 : TARGET_32BIT ? -220 : -288);
20126 /* Emit function epilogue as insns. */
20128 void
20129 rs6000_emit_epilogue (int sibcall)
20131 rs6000_stack_t *info;
20132 int restoring_GPRs_inline;
20133 int restoring_FPRs_inline;
20134 int using_load_multiple;
20135 int using_mtcr_multiple;
20136 int use_backchain_to_restore_sp;
20137 int restore_lr;
20138 int strategy;
20139 int sp_offset = 0;
20140 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20141 rtx frame_reg_rtx = sp_reg_rtx;
20142 rtx cfa_restores = NULL_RTX;
20143 rtx insn;
20144 rtx cr_save_reg = NULL_RTX;
20145 enum machine_mode reg_mode = Pmode;
20146 int reg_size = TARGET_32BIT ? 4 : 8;
20147 int i;
20149 info = rs6000_stack_info ();
20151 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20153 reg_mode = V2SImode;
20154 reg_size = 8;
20157 strategy = rs6000_savres_strategy (info, /*savep=*/false,
20158 /*static_chain_p=*/0, sibcall);
20159 using_load_multiple = strategy & SAVRES_MULTIPLE;
20160 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
20161 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
20162 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20163 || rs6000_cpu == PROCESSOR_PPC603
20164 || rs6000_cpu == PROCESSOR_PPC750
20165 || optimize_size);
20166 /* Restore via the backchain when we have a large frame, since this
20167 is more efficient than an addis, addi pair. The second condition
20168 here will not trigger at the moment; We don't actually need a
20169 frame pointer for alloca, but the generic parts of the compiler
20170 give us one anyway. */
20171 use_backchain_to_restore_sp = (info->total_size > 32767
20172 || info->total_size
20173 + (info->lr_save_p ? info->lr_save_offset : 0)
20174 > 32767
20175 || (cfun->calls_alloca
20176 && !frame_pointer_needed));
20177 restore_lr = (info->lr_save_p
20178 && (restoring_FPRs_inline
20179 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20180 && (restoring_GPRs_inline
20181 || info->first_fp_reg_save < 64));
20183 if (WORLD_SAVE_P (info))
20185 int i, j;
20186 char rname[30];
20187 const char *alloc_rname;
20188 rtvec p;
20190 /* eh_rest_world_r10 will return to the location saved in the LR
20191 stack slot (which is not likely to be our caller.)
20192 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20193 rest_world is similar, except any R10 parameter is ignored.
20194 The exception-handling stuff that was here in 2.95 is no
20195 longer necessary. */
20197 p = rtvec_alloc (9
20199 + 32 - info->first_gp_reg_save
20200 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20201 + 63 + 1 - info->first_fp_reg_save);
20203 strcpy (rname, ((crtl->calls_eh_return) ?
20204 "*eh_rest_world_r10" : "*rest_world"));
20205 alloc_rname = ggc_strdup (rname);
20207 j = 0;
20208 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20209 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20210 gen_rtx_REG (Pmode,
20211 LR_REGNO));
20212 RTVEC_ELT (p, j++)
20213 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20214 /* The instruction pattern requires a clobber here;
20215 it is shared with the restVEC helper. */
20216 RTVEC_ELT (p, j++)
20217 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20220 /* CR register traditionally saved as CR2. */
20221 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20222 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20223 GEN_INT (info->cr_save_offset));
20224 rtx mem = gen_frame_mem (reg_mode, addr);
20226 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20229 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20231 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20232 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20233 GEN_INT (info->gp_save_offset
20234 + reg_size * i));
20235 rtx mem = gen_frame_mem (reg_mode, addr);
20237 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20239 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20241 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20242 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20243 GEN_INT (info->altivec_save_offset
20244 + 16 * i));
20245 rtx mem = gen_frame_mem (V4SImode, addr);
20247 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20249 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20251 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20252 ? DFmode : SFmode),
20253 info->first_fp_reg_save + i);
20254 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20255 GEN_INT (info->fp_save_offset
20256 + 8 * i));
20257 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20258 ? DFmode : SFmode), addr);
20260 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20262 RTVEC_ELT (p, j++)
20263 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20264 RTVEC_ELT (p, j++)
20265 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20266 RTVEC_ELT (p, j++)
20267 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20268 RTVEC_ELT (p, j++)
20269 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20270 RTVEC_ELT (p, j++)
20271 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20272 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20274 return;
20277 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20278 if (info->push_p)
20279 sp_offset = info->total_size;
20281 /* Restore AltiVec registers if we must do so before adjusting the
20282 stack. */
20283 if (TARGET_ALTIVEC_ABI
20284 && info->altivec_size != 0
20285 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20286 || (DEFAULT_ABI != ABI_V4
20287 && offset_below_red_zone_p (info->altivec_save_offset))))
20289 int i;
20291 if (use_backchain_to_restore_sp)
20293 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20294 emit_move_insn (frame_reg_rtx,
20295 gen_rtx_MEM (Pmode, sp_reg_rtx));
20296 sp_offset = 0;
20298 else if (frame_pointer_needed)
20299 frame_reg_rtx = hard_frame_pointer_rtx;
20301 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20302 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20304 rtx addr, areg, mem, reg;
20306 areg = gen_rtx_REG (Pmode, 0);
20307 emit_move_insn
20308 (areg, GEN_INT (info->altivec_save_offset
20309 + sp_offset
20310 + 16 * (i - info->first_altivec_reg_save)));
20312 /* AltiVec addressing mode is [reg+reg]. */
20313 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20314 mem = gen_frame_mem (V4SImode, addr);
20316 reg = gen_rtx_REG (V4SImode, i);
20317 emit_move_insn (reg, mem);
20318 if (offset_below_red_zone_p (info->altivec_save_offset
20319 + (i - info->first_altivec_reg_save)
20320 * 16))
20321 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20322 cfa_restores);
20326 /* Restore VRSAVE if we must do so before adjusting the stack. */
20327 if (TARGET_ALTIVEC
20328 && TARGET_ALTIVEC_VRSAVE
20329 && info->vrsave_mask != 0
20330 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20331 || (DEFAULT_ABI != ABI_V4
20332 && offset_below_red_zone_p (info->vrsave_save_offset))))
20334 rtx addr, mem, reg;
20336 if (frame_reg_rtx == sp_reg_rtx)
20338 if (use_backchain_to_restore_sp)
20340 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20341 emit_move_insn (frame_reg_rtx,
20342 gen_rtx_MEM (Pmode, sp_reg_rtx));
20343 sp_offset = 0;
20345 else if (frame_pointer_needed)
20346 frame_reg_rtx = hard_frame_pointer_rtx;
20349 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20350 GEN_INT (info->vrsave_save_offset + sp_offset));
20351 mem = gen_frame_mem (SImode, addr);
20352 reg = gen_rtx_REG (SImode, 12);
20353 emit_move_insn (reg, mem);
20355 emit_insn (generate_set_vrsave (reg, info, 1));
20358 insn = NULL_RTX;
20359 /* If we have a large stack frame, restore the old stack pointer
20360 using the backchain. */
20361 if (use_backchain_to_restore_sp)
20363 if (frame_reg_rtx == sp_reg_rtx)
20365 /* Under V.4, don't reset the stack pointer until after we're done
20366 loading the saved registers. */
20367 if (DEFAULT_ABI == ABI_V4)
20368 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20370 insn = emit_move_insn (frame_reg_rtx,
20371 gen_rtx_MEM (Pmode, sp_reg_rtx));
20372 sp_offset = 0;
20374 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20375 && DEFAULT_ABI == ABI_V4)
20376 /* frame_reg_rtx has been set up by the altivec restore. */
20378 else
20380 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20381 frame_reg_rtx = sp_reg_rtx;
20384 /* If we have a frame pointer, we can restore the old stack pointer
20385 from it. */
20386 else if (frame_pointer_needed)
20388 frame_reg_rtx = sp_reg_rtx;
20389 if (DEFAULT_ABI == ABI_V4)
20390 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20391 /* Prevent reordering memory accesses against stack pointer restore. */
20392 else if (cfun->calls_alloca
20393 || offset_below_red_zone_p (-info->total_size))
20395 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20396 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20397 MEM_NOTRAP_P (mem1) = 1;
20398 MEM_NOTRAP_P (mem2) = 1;
20399 emit_insn (gen_frame_tie (mem1, mem2));
20402 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20403 GEN_INT (info->total_size)));
20404 sp_offset = 0;
20406 else if (info->push_p
20407 && DEFAULT_ABI != ABI_V4
20408 && !crtl->calls_eh_return)
20410 /* Prevent reordering memory accesses against stack pointer restore. */
20411 if (cfun->calls_alloca
20412 || offset_below_red_zone_p (-info->total_size))
20414 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20415 MEM_NOTRAP_P (mem) = 1;
20416 emit_insn (gen_stack_tie (mem));
20418 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20419 GEN_INT (info->total_size)));
20420 sp_offset = 0;
20422 if (insn && frame_reg_rtx == sp_reg_rtx)
20424 if (cfa_restores)
20426 REG_NOTES (insn) = cfa_restores;
20427 cfa_restores = NULL_RTX;
20429 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20430 RTX_FRAME_RELATED_P (insn) = 1;
20433 /* Restore AltiVec registers if we have not done so already. */
20434 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20435 && TARGET_ALTIVEC_ABI
20436 && info->altivec_size != 0
20437 && (DEFAULT_ABI == ABI_V4
20438 || !offset_below_red_zone_p (info->altivec_save_offset)))
20440 int i;
20442 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20443 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20445 rtx addr, areg, mem, reg;
20447 areg = gen_rtx_REG (Pmode, 0);
20448 emit_move_insn
20449 (areg, GEN_INT (info->altivec_save_offset
20450 + sp_offset
20451 + 16 * (i - info->first_altivec_reg_save)));
20453 /* AltiVec addressing mode is [reg+reg]. */
20454 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20455 mem = gen_frame_mem (V4SImode, addr);
20457 reg = gen_rtx_REG (V4SImode, i);
20458 emit_move_insn (reg, mem);
20459 if (DEFAULT_ABI == ABI_V4)
20460 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20461 cfa_restores);
20465 /* Restore VRSAVE if we have not done so already. */
20466 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20467 && TARGET_ALTIVEC
20468 && TARGET_ALTIVEC_VRSAVE
20469 && info->vrsave_mask != 0
20470 && (DEFAULT_ABI == ABI_V4
20471 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20473 rtx addr, mem, reg;
20475 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20476 GEN_INT (info->vrsave_save_offset + sp_offset));
20477 mem = gen_frame_mem (SImode, addr);
20478 reg = gen_rtx_REG (SImode, 12);
20479 emit_move_insn (reg, mem);
20481 emit_insn (generate_set_vrsave (reg, info, 1));
20484 /* Get the old lr if we saved it. If we are restoring registers
20485 out-of-line, then the out-of-line routines can do this for us. */
20486 if (restore_lr && restoring_GPRs_inline)
20488 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20489 info->lr_save_offset + sp_offset);
20491 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20494 /* Get the old cr if we saved it. */
20495 if (info->cr_save_p)
20497 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20498 GEN_INT (info->cr_save_offset + sp_offset));
20499 rtx mem = gen_frame_mem (SImode, addr);
20501 cr_save_reg = gen_rtx_REG (SImode,
20502 DEFAULT_ABI == ABI_AIX
20503 && !restoring_GPRs_inline
20504 && info->first_fp_reg_save < 64
20505 ? 11 : 12);
20506 emit_move_insn (cr_save_reg, mem);
20509 /* Set LR here to try to overlap restores below. LR is always saved
20510 above incoming stack, so it never needs REG_CFA_RESTORE. */
20511 if (restore_lr && restoring_GPRs_inline)
20512 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20513 gen_rtx_REG (Pmode, 0));
20515 /* Load exception handler data registers, if needed. */
20516 if (crtl->calls_eh_return)
20518 unsigned int i, regno;
20520 if (TARGET_AIX)
20522 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20523 GEN_INT (sp_offset + 5 * reg_size));
20524 rtx mem = gen_frame_mem (reg_mode, addr);
20526 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
20529 for (i = 0; ; ++i)
20531 rtx mem;
20533 regno = EH_RETURN_DATA_REGNO (i);
20534 if (regno == INVALID_REGNUM)
20535 break;
20537 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
20538 info->ehrd_offset + sp_offset
20539 + reg_size * (int) i);
20541 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
20545 /* Restore GPRs. This is done as a PARALLEL if we are using
20546 the load-multiple instructions. */
20547 if (TARGET_SPE_ABI
20548 && info->spe_64bit_regs_used != 0
20549 && info->first_gp_reg_save != 32)
20551 /* Determine whether we can address all of the registers that need
20552 to be saved with an offset from the stack pointer that fits in
20553 the small const field for SPE memory instructions. */
20554 int spe_regs_addressable_via_sp
20555 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20556 + (32 - info->first_gp_reg_save - 1) * reg_size)
20557 && restoring_GPRs_inline);
20558 int spe_offset;
20560 if (spe_regs_addressable_via_sp)
20561 spe_offset = info->spe_gp_save_offset + sp_offset;
20562 else
20564 rtx old_frame_reg_rtx = frame_reg_rtx;
20565 /* Make r11 point to the start of the SPE save area. We worried about
20566 not clobbering it when we were saving registers in the prologue.
20567 There's no need to worry here because the static chain is passed
20568 anew to every function. */
20569 int ool_adjust = (restoring_GPRs_inline
20571 : (info->first_gp_reg_save
20572 - (FIRST_SAVRES_REGISTER+1))*8);
20574 if (frame_reg_rtx == sp_reg_rtx)
20575 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20576 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
20577 GEN_INT (info->spe_gp_save_offset
20578 + sp_offset
20579 - ool_adjust)));
20580 /* Keep the invariant that frame_reg_rtx + sp_offset points
20581 at the top of the stack frame. */
20582 sp_offset = -info->spe_gp_save_offset;
20584 spe_offset = 0;
20587 if (restoring_GPRs_inline)
20589 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20590 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20592 rtx offset, addr, mem, reg;
20594 /* We're doing all this to ensure that the immediate offset
20595 fits into the immediate field of 'evldd'. */
20596 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
20598 offset = GEN_INT (spe_offset + reg_size * i);
20599 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
20600 mem = gen_rtx_MEM (V2SImode, addr);
20601 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20603 insn = emit_move_insn (reg, mem);
20604 if (DEFAULT_ABI == ABI_V4)
20606 if (frame_pointer_needed
20607 && info->first_gp_reg_save + i
20608 == HARD_FRAME_POINTER_REGNUM)
20610 add_reg_note (insn, REG_CFA_DEF_CFA,
20611 plus_constant (frame_reg_rtx,
20612 sp_offset));
20613 RTX_FRAME_RELATED_P (insn) = 1;
20616 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20617 cfa_restores);
20621 else
20623 rtx par;
20625 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20626 0, reg_mode,
20627 /*savep=*/false, /*gpr=*/true,
20628 /*lr=*/true);
20629 emit_jump_insn (par);
20630 /* We don't want anybody else emitting things after we jumped
20631 back. */
20632 return;
20635 else if (!restoring_GPRs_inline)
20637 /* We are jumping to an out-of-line function. */
20638 bool can_use_exit = info->first_fp_reg_save == 64;
20639 rtx par;
20641 /* Emit stack reset code if we need it. */
20642 if (can_use_exit)
20643 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20644 sp_offset, can_use_exit);
20645 else
20647 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20648 ? 12 : 11),
20649 frame_reg_rtx,
20650 GEN_INT (sp_offset - info->fp_size)));
20651 if (REGNO (frame_reg_rtx) == 11)
20652 sp_offset += info->fp_size;
20655 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20656 info->gp_save_offset, reg_mode,
20657 /*savep=*/false, /*gpr=*/true,
20658 /*lr=*/can_use_exit);
20660 if (can_use_exit)
20662 if (info->cr_save_p)
20664 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20665 if (DEFAULT_ABI == ABI_V4)
20666 cfa_restores
20667 = alloc_reg_note (REG_CFA_RESTORE,
20668 gen_rtx_REG (SImode, CR2_REGNO),
20669 cfa_restores);
20672 emit_jump_insn (par);
20674 /* We don't want anybody else emitting things after we jumped
20675 back. */
20676 return;
20679 insn = emit_insn (par);
20680 if (DEFAULT_ABI == ABI_V4)
20682 if (frame_pointer_needed)
20684 add_reg_note (insn, REG_CFA_DEF_CFA,
20685 plus_constant (frame_reg_rtx, sp_offset));
20686 RTX_FRAME_RELATED_P (insn) = 1;
20689 for (i = info->first_gp_reg_save; i < 32; i++)
20690 cfa_restores
20691 = alloc_reg_note (REG_CFA_RESTORE,
20692 gen_rtx_REG (reg_mode, i), cfa_restores);
20695 else if (using_load_multiple)
20697 rtvec p;
20698 p = rtvec_alloc (32 - info->first_gp_reg_save);
20699 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20701 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20702 GEN_INT (info->gp_save_offset
20703 + sp_offset
20704 + reg_size * i));
20705 rtx mem = gen_frame_mem (reg_mode, addr);
20706 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20708 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20709 if (DEFAULT_ABI == ABI_V4)
20710 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20711 cfa_restores);
20713 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20714 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20716 add_reg_note (insn, REG_CFA_DEF_CFA,
20717 plus_constant (frame_reg_rtx, sp_offset));
20718 RTX_FRAME_RELATED_P (insn) = 1;
20721 else
20723 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20724 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20726 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20727 GEN_INT (info->gp_save_offset
20728 + sp_offset
20729 + reg_size * i));
20730 rtx mem = gen_frame_mem (reg_mode, addr);
20731 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20733 insn = emit_move_insn (reg, mem);
20734 if (DEFAULT_ABI == ABI_V4)
20736 if (frame_pointer_needed
20737 && info->first_gp_reg_save + i
20738 == HARD_FRAME_POINTER_REGNUM)
20740 add_reg_note (insn, REG_CFA_DEF_CFA,
20741 plus_constant (frame_reg_rtx, sp_offset));
20742 RTX_FRAME_RELATED_P (insn) = 1;
20745 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20746 cfa_restores);
20751 if (restore_lr && !restoring_GPRs_inline)
20753 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20754 info->lr_save_offset + sp_offset);
20756 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20757 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20758 gen_rtx_REG (Pmode, 0));
20761 /* Restore fpr's if we need to do it without calling a function. */
20762 if (restoring_FPRs_inline)
20763 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20764 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20765 && ! call_used_regs[info->first_fp_reg_save+i]))
20767 rtx addr, mem, reg;
20768 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20769 GEN_INT (info->fp_save_offset
20770 + sp_offset
20771 + 8 * i));
20772 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20773 ? DFmode : SFmode), addr);
20774 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20775 ? DFmode : SFmode),
20776 info->first_fp_reg_save + i);
20778 emit_move_insn (reg, mem);
20779 if (DEFAULT_ABI == ABI_V4)
20780 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20781 cfa_restores);
20784 /* If we saved cr, restore it here. Just those that were used. */
20785 if (info->cr_save_p)
20787 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20788 if (DEFAULT_ABI == ABI_V4)
20789 cfa_restores
20790 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20791 cfa_restores);
20794 /* If this is V.4, unwind the stack pointer after all of the loads
20795 have been done. */
20796 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20797 sp_offset, !restoring_FPRs_inline);
20798 if (insn)
20800 if (cfa_restores)
20802 REG_NOTES (insn) = cfa_restores;
20803 cfa_restores = NULL_RTX;
20805 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20806 RTX_FRAME_RELATED_P (insn) = 1;
20809 if (crtl->calls_eh_return)
20811 rtx sa = EH_RETURN_STACKADJ_RTX;
20812 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20815 if (!sibcall)
20817 rtvec p;
20818 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20819 if (! restoring_FPRs_inline)
20820 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20821 else
20822 p = rtvec_alloc (2);
20824 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20825 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20826 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20827 : gen_rtx_CLOBBER (VOIDmode,
20828 gen_rtx_REG (Pmode, 65)));
20830 /* If we have to restore more than two FP registers, branch to the
20831 restore function. It will return to our caller. */
20832 if (! restoring_FPRs_inline)
20834 int i;
20835 rtx sym;
20837 sym = rs6000_savres_routine_sym (info,
20838 /*savep=*/false,
20839 /*gpr=*/false,
20840 /*lr=*/lr);
20841 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20842 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20843 gen_rtx_REG (Pmode,
20844 DEFAULT_ABI == ABI_AIX
20845 ? 1 : 11));
20846 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20848 rtx addr, mem;
20849 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20850 GEN_INT (info->fp_save_offset + 8*i));
20851 mem = gen_frame_mem (DFmode, addr);
20853 RTVEC_ELT (p, i+4) =
20854 gen_rtx_SET (VOIDmode,
20855 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20856 mem);
20860 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20864 /* Write function epilogue. */
20866 static void
20867 rs6000_output_function_epilogue (FILE *file,
20868 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20870 if (! HAVE_epilogue)
20872 rtx insn = get_last_insn ();
20873 /* If the last insn was a BARRIER, we don't have to write anything except
20874 the trace table. */
20875 if (GET_CODE (insn) == NOTE)
20876 insn = prev_nonnote_insn (insn);
20877 if (insn == 0 || GET_CODE (insn) != BARRIER)
20879 /* This is slightly ugly, but at least we don't have two
20880 copies of the epilogue-emitting code. */
20881 start_sequence ();
20883 /* A NOTE_INSN_DELETED is supposed to be at the start
20884 and end of the "toplevel" insn chain. */
20885 emit_note (NOTE_INSN_DELETED);
20886 rs6000_emit_epilogue (FALSE);
20887 emit_note (NOTE_INSN_DELETED);
20889 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20891 rtx insn;
20892 unsigned addr = 0;
20893 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20895 INSN_ADDRESSES_NEW (insn, addr);
20896 addr += 4;
20900 if (TARGET_DEBUG_STACK)
20901 debug_rtx_list (get_insns (), 100);
20902 final (get_insns (), file, FALSE);
20903 end_sequence ();
20907 #if TARGET_MACHO
20908 macho_branch_islands ();
20909 /* Mach-O doesn't support labels at the end of objects, so if
20910 it looks like we might want one, insert a NOP. */
20912 rtx insn = get_last_insn ();
20913 while (insn
20914 && NOTE_P (insn)
20915 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20916 insn = PREV_INSN (insn);
20917 if (insn
20918 && (LABEL_P (insn)
20919 || (NOTE_P (insn)
20920 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20921 fputs ("\tnop\n", file);
20923 #endif
20925 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20926 on its format.
20928 We don't output a traceback table if -finhibit-size-directive was
20929 used. The documentation for -finhibit-size-directive reads
20930 ``don't output a @code{.size} assembler directive, or anything
20931 else that would cause trouble if the function is split in the
20932 middle, and the two halves are placed at locations far apart in
20933 memory.'' The traceback table has this property, since it
20934 includes the offset from the start of the function to the
20935 traceback table itself.
20937 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20938 different traceback table. */
20939 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20940 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20942 const char *fname = NULL;
20943 const char *language_string = lang_hooks.name;
20944 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20945 int i;
20946 int optional_tbtab;
20947 rs6000_stack_t *info = rs6000_stack_info ();
20949 if (rs6000_traceback == traceback_full)
20950 optional_tbtab = 1;
20951 else if (rs6000_traceback == traceback_part)
20952 optional_tbtab = 0;
20953 else
20954 optional_tbtab = !optimize_size && !TARGET_ELF;
20956 if (optional_tbtab)
20958 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20959 while (*fname == '.') /* V.4 encodes . in the name */
20960 fname++;
20962 /* Need label immediately before tbtab, so we can compute
20963 its offset from the function start. */
20964 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20965 ASM_OUTPUT_LABEL (file, fname);
20968 /* The .tbtab pseudo-op can only be used for the first eight
20969 expressions, since it can't handle the possibly variable
20970 length fields that follow. However, if you omit the optional
20971 fields, the assembler outputs zeros for all optional fields
20972 anyways, giving each variable length field is minimum length
20973 (as defined in sys/debug.h). Thus we can not use the .tbtab
20974 pseudo-op at all. */
20976 /* An all-zero word flags the start of the tbtab, for debuggers
20977 that have to find it by searching forward from the entry
20978 point or from the current pc. */
20979 fputs ("\t.long 0\n", file);
20981 /* Tbtab format type. Use format type 0. */
20982 fputs ("\t.byte 0,", file);
20984 /* Language type. Unfortunately, there does not seem to be any
20985 official way to discover the language being compiled, so we
20986 use language_string.
20987 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20988 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20989 a number, so for now use 9. LTO isn't assigned a number either,
20990 so for now use 0. */
20991 if (! strcmp (language_string, "GNU C")
20992 || ! strcmp (language_string, "GNU GIMPLE"))
20993 i = 0;
20994 else if (! strcmp (language_string, "GNU F77")
20995 || ! strcmp (language_string, "GNU Fortran"))
20996 i = 1;
20997 else if (! strcmp (language_string, "GNU Pascal"))
20998 i = 2;
20999 else if (! strcmp (language_string, "GNU Ada"))
21000 i = 3;
21001 else if (! strcmp (language_string, "GNU C++")
21002 || ! strcmp (language_string, "GNU Objective-C++"))
21003 i = 9;
21004 else if (! strcmp (language_string, "GNU Java"))
21005 i = 13;
21006 else if (! strcmp (language_string, "GNU Objective-C"))
21007 i = 14;
21008 else
21009 gcc_unreachable ();
21010 fprintf (file, "%d,", i);
21012 /* 8 single bit fields: global linkage (not set for C extern linkage,
21013 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21014 from start of procedure stored in tbtab, internal function, function
21015 has controlled storage, function has no toc, function uses fp,
21016 function logs/aborts fp operations. */
21017 /* Assume that fp operations are used if any fp reg must be saved. */
21018 fprintf (file, "%d,",
21019 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21021 /* 6 bitfields: function is interrupt handler, name present in
21022 proc table, function calls alloca, on condition directives
21023 (controls stack walks, 3 bits), saves condition reg, saves
21024 link reg. */
21025 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21026 set up as a frame pointer, even when there is no alloca call. */
21027 fprintf (file, "%d,",
21028 ((optional_tbtab << 6)
21029 | ((optional_tbtab & frame_pointer_needed) << 5)
21030 | (info->cr_save_p << 1)
21031 | (info->lr_save_p)));
21033 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21034 (6 bits). */
21035 fprintf (file, "%d,",
21036 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21038 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21039 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21041 if (optional_tbtab)
21043 /* Compute the parameter info from the function decl argument
21044 list. */
21045 tree decl;
21046 int next_parm_info_bit = 31;
21048 for (decl = DECL_ARGUMENTS (current_function_decl);
21049 decl; decl = DECL_CHAIN (decl))
21051 rtx parameter = DECL_INCOMING_RTL (decl);
21052 enum machine_mode mode = GET_MODE (parameter);
21054 if (GET_CODE (parameter) == REG)
21056 if (SCALAR_FLOAT_MODE_P (mode))
21058 int bits;
21060 float_parms++;
21062 switch (mode)
21064 case SFmode:
21065 case SDmode:
21066 bits = 0x2;
21067 break;
21069 case DFmode:
21070 case DDmode:
21071 case TFmode:
21072 case TDmode:
21073 bits = 0x3;
21074 break;
21076 default:
21077 gcc_unreachable ();
21080 /* If only one bit will fit, don't or in this entry. */
21081 if (next_parm_info_bit > 0)
21082 parm_info |= (bits << (next_parm_info_bit - 1));
21083 next_parm_info_bit -= 2;
21085 else
21087 fixed_parms += ((GET_MODE_SIZE (mode)
21088 + (UNITS_PER_WORD - 1))
21089 / UNITS_PER_WORD);
21090 next_parm_info_bit -= 1;
21096 /* Number of fixed point parameters. */
21097 /* This is actually the number of words of fixed point parameters; thus
21098 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21099 fprintf (file, "%d,", fixed_parms);
21101 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21102 all on stack. */
21103 /* This is actually the number of fp registers that hold parameters;
21104 and thus the maximum value is 13. */
21105 /* Set parameters on stack bit if parameters are not in their original
21106 registers, regardless of whether they are on the stack? Xlc
21107 seems to set the bit when not optimizing. */
21108 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21110 if (! optional_tbtab)
21111 return;
21113 /* Optional fields follow. Some are variable length. */
21115 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21116 11 double float. */
21117 /* There is an entry for each parameter in a register, in the order that
21118 they occur in the parameter list. Any intervening arguments on the
21119 stack are ignored. If the list overflows a long (max possible length
21120 34 bits) then completely leave off all elements that don't fit. */
21121 /* Only emit this long if there was at least one parameter. */
21122 if (fixed_parms || float_parms)
21123 fprintf (file, "\t.long %d\n", parm_info);
21125 /* Offset from start of code to tb table. */
21126 fputs ("\t.long ", file);
21127 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21128 RS6000_OUTPUT_BASENAME (file, fname);
21129 putc ('-', file);
21130 rs6000_output_function_entry (file, fname);
21131 putc ('\n', file);
21133 /* Interrupt handler mask. */
21134 /* Omit this long, since we never set the interrupt handler bit
21135 above. */
21137 /* Number of CTL (controlled storage) anchors. */
21138 /* Omit this long, since the has_ctl bit is never set above. */
21140 /* Displacement into stack of each CTL anchor. */
21141 /* Omit this list of longs, because there are no CTL anchors. */
21143 /* Length of function name. */
21144 if (*fname == '*')
21145 ++fname;
21146 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21148 /* Function name. */
21149 assemble_string (fname, strlen (fname));
21151 /* Register for alloca automatic storage; this is always reg 31.
21152 Only emit this if the alloca bit was set above. */
21153 if (frame_pointer_needed)
21154 fputs ("\t.byte 31\n", file);
21156 fputs ("\t.align 2\n", file);
21160 /* A C compound statement that outputs the assembler code for a thunk
21161 function, used to implement C++ virtual function calls with
21162 multiple inheritance. The thunk acts as a wrapper around a virtual
21163 function, adjusting the implicit object parameter before handing
21164 control off to the real function.
21166 First, emit code to add the integer DELTA to the location that
21167 contains the incoming first argument. Assume that this argument
21168 contains a pointer, and is the one used to pass the `this' pointer
21169 in C++. This is the incoming argument *before* the function
21170 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21171 values of all other incoming arguments.
21173 After the addition, emit code to jump to FUNCTION, which is a
21174 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21175 not touch the return address. Hence returning from FUNCTION will
21176 return to whoever called the current `thunk'.
21178 The effect must be as if FUNCTION had been called directly with the
21179 adjusted first argument. This macro is responsible for emitting
21180 all of the code for a thunk function; output_function_prologue()
21181 and output_function_epilogue() are not invoked.
21183 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21184 been extracted from it.) It might possibly be useful on some
21185 targets, but probably not.
21187 If you do not define this macro, the target-independent code in the
21188 C++ frontend will generate a less efficient heavyweight thunk that
21189 calls FUNCTION instead of jumping to it. The generic approach does
21190 not support varargs. */
21192 static void
21193 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21194 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21195 tree function)
21197 rtx this_rtx, insn, funexp;
21199 reload_completed = 1;
21200 epilogue_completed = 1;
21202 /* Mark the end of the (empty) prologue. */
21203 emit_note (NOTE_INSN_PROLOGUE_END);
21205 /* Find the "this" pointer. If the function returns a structure,
21206 the structure return pointer is in r3. */
21207 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21208 this_rtx = gen_rtx_REG (Pmode, 4);
21209 else
21210 this_rtx = gen_rtx_REG (Pmode, 3);
21212 /* Apply the constant offset, if required. */
21213 if (delta)
21214 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21216 /* Apply the offset from the vtable, if required. */
21217 if (vcall_offset)
21219 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21220 rtx tmp = gen_rtx_REG (Pmode, 12);
21222 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21223 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21225 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21226 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21228 else
21230 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21232 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21234 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21237 /* Generate a tail call to the target function. */
21238 if (!TREE_USED (function))
21240 assemble_external (function);
21241 TREE_USED (function) = 1;
21243 funexp = XEXP (DECL_RTL (function), 0);
21244 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21246 #if TARGET_MACHO
21247 if (MACHOPIC_INDIRECT)
21248 funexp = machopic_indirect_call_target (funexp);
21249 #endif
21251 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21252 generate sibcall RTL explicitly. */
21253 insn = emit_call_insn (
21254 gen_rtx_PARALLEL (VOIDmode,
21255 gen_rtvec (4,
21256 gen_rtx_CALL (VOIDmode,
21257 funexp, const0_rtx),
21258 gen_rtx_USE (VOIDmode, const0_rtx),
21259 gen_rtx_USE (VOIDmode,
21260 gen_rtx_REG (SImode,
21261 LR_REGNO)),
21262 gen_rtx_RETURN (VOIDmode))));
21263 SIBLING_CALL_P (insn) = 1;
21264 emit_barrier ();
21266 /* Run just enough of rest_of_compilation to get the insns emitted.
21267 There's not really enough bulk here to make other passes such as
21268 instruction scheduling worth while. Note that use_thunk calls
21269 assemble_start_function and assemble_end_function. */
21270 insn = get_insns ();
21271 insn_locators_alloc ();
21272 shorten_branches (insn);
21273 final_start_function (insn, file, 1);
21274 final (insn, file, 1);
21275 final_end_function ();
21277 reload_completed = 0;
21278 epilogue_completed = 0;
21281 /* A quick summary of the various types of 'constant-pool tables'
21282 under PowerPC:
21284 Target Flags Name One table per
21285 AIX (none) AIX TOC object file
21286 AIX -mfull-toc AIX TOC object file
21287 AIX -mminimal-toc AIX minimal TOC translation unit
21288 SVR4/EABI (none) SVR4 SDATA object file
21289 SVR4/EABI -fpic SVR4 pic object file
21290 SVR4/EABI -fPIC SVR4 PIC translation unit
21291 SVR4/EABI -mrelocatable EABI TOC function
21292 SVR4/EABI -maix AIX TOC object file
21293 SVR4/EABI -maix -mminimal-toc
21294 AIX minimal TOC translation unit
21296 Name Reg. Set by entries contains:
21297 made by addrs? fp? sum?
21299 AIX TOC 2 crt0 as Y option option
21300 AIX minimal TOC 30 prolog gcc Y Y option
21301 SVR4 SDATA 13 crt0 gcc N Y N
21302 SVR4 pic 30 prolog ld Y not yet N
21303 SVR4 PIC 30 prolog gcc Y option option
21304 EABI TOC 30 prolog gcc Y option option
21308 /* Hash functions for the hash table. */
21310 static unsigned
21311 rs6000_hash_constant (rtx k)
21313 enum rtx_code code = GET_CODE (k);
21314 enum machine_mode mode = GET_MODE (k);
21315 unsigned result = (code << 3) ^ mode;
21316 const char *format;
21317 int flen, fidx;
21319 format = GET_RTX_FORMAT (code);
21320 flen = strlen (format);
21321 fidx = 0;
21323 switch (code)
21325 case LABEL_REF:
21326 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21328 case CONST_DOUBLE:
21329 if (mode != VOIDmode)
21330 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21331 flen = 2;
21332 break;
21334 case CODE_LABEL:
21335 fidx = 3;
21336 break;
21338 default:
21339 break;
21342 for (; fidx < flen; fidx++)
21343 switch (format[fidx])
21345 case 's':
21347 unsigned i, len;
21348 const char *str = XSTR (k, fidx);
21349 len = strlen (str);
21350 result = result * 613 + len;
21351 for (i = 0; i < len; i++)
21352 result = result * 613 + (unsigned) str[i];
21353 break;
21355 case 'u':
21356 case 'e':
21357 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21358 break;
21359 case 'i':
21360 case 'n':
21361 result = result * 613 + (unsigned) XINT (k, fidx);
21362 break;
21363 case 'w':
21364 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21365 result = result * 613 + (unsigned) XWINT (k, fidx);
21366 else
21368 size_t i;
21369 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21370 result = result * 613 + (unsigned) (XWINT (k, fidx)
21371 >> CHAR_BIT * i);
21373 break;
21374 case '0':
21375 break;
21376 default:
21377 gcc_unreachable ();
21380 return result;
21383 static unsigned
21384 toc_hash_function (const void *hash_entry)
21386 const struct toc_hash_struct *thc =
21387 (const struct toc_hash_struct *) hash_entry;
21388 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21391 /* Compare H1 and H2 for equivalence. */
21393 static int
21394 toc_hash_eq (const void *h1, const void *h2)
21396 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21397 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21399 if (((const struct toc_hash_struct *) h1)->key_mode
21400 != ((const struct toc_hash_struct *) h2)->key_mode)
21401 return 0;
21403 return rtx_equal_p (r1, r2);
21406 /* These are the names given by the C++ front-end to vtables, and
21407 vtable-like objects. Ideally, this logic should not be here;
21408 instead, there should be some programmatic way of inquiring as
21409 to whether or not an object is a vtable. */
21411 #define VTABLE_NAME_P(NAME) \
21412 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21413 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21414 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21415 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21416 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21418 #ifdef NO_DOLLAR_IN_LABEL
21419 /* Return a GGC-allocated character string translating dollar signs in
21420 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21422 const char *
21423 rs6000_xcoff_strip_dollar (const char *name)
21425 char *strip, *p;
21426 int len;
21428 p = strchr (name, '$');
21430 if (p == 0 || p == name)
21431 return name;
21433 len = strlen (name);
21434 strip = (char *) alloca (len + 1);
21435 strcpy (strip, name);
21436 p = strchr (strip, '$');
21437 while (p)
21439 *p = '_';
21440 p = strchr (p + 1, '$');
21443 return ggc_alloc_string (strip, len);
21445 #endif
21447 void
21448 rs6000_output_symbol_ref (FILE *file, rtx x)
21450 /* Currently C++ toc references to vtables can be emitted before it
21451 is decided whether the vtable is public or private. If this is
21452 the case, then the linker will eventually complain that there is
21453 a reference to an unknown section. Thus, for vtables only,
21454 we emit the TOC reference to reference the symbol and not the
21455 section. */
21456 const char *name = XSTR (x, 0);
21458 if (VTABLE_NAME_P (name))
21460 RS6000_OUTPUT_BASENAME (file, name);
21462 else
21463 assemble_name (file, name);
21466 /* Output a TOC entry. We derive the entry name from what is being
21467 written. */
21469 void
21470 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21472 char buf[256];
21473 const char *name = buf;
21474 rtx base = x;
21475 HOST_WIDE_INT offset = 0;
21477 gcc_assert (!TARGET_NO_TOC);
21479 /* When the linker won't eliminate them, don't output duplicate
21480 TOC entries (this happens on AIX if there is any kind of TOC,
21481 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21482 CODE_LABELs. */
21483 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21485 struct toc_hash_struct *h;
21486 void * * found;
21488 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21489 time because GGC is not initialized at that point. */
21490 if (toc_hash_table == NULL)
21491 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21492 toc_hash_eq, NULL);
21494 h = ggc_alloc_toc_hash_struct ();
21495 h->key = x;
21496 h->key_mode = mode;
21497 h->labelno = labelno;
21499 found = htab_find_slot (toc_hash_table, h, INSERT);
21500 if (*found == NULL)
21501 *found = h;
21502 else /* This is indeed a duplicate.
21503 Set this label equal to that label. */
21505 fputs ("\t.set ", file);
21506 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21507 fprintf (file, "%d,", labelno);
21508 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21509 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21510 found)->labelno));
21511 return;
21515 /* If we're going to put a double constant in the TOC, make sure it's
21516 aligned properly when strict alignment is on. */
21517 if (GET_CODE (x) == CONST_DOUBLE
21518 && STRICT_ALIGNMENT
21519 && GET_MODE_BITSIZE (mode) >= 64
21520 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21521 ASM_OUTPUT_ALIGN (file, 3);
21524 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21526 /* Handle FP constants specially. Note that if we have a minimal
21527 TOC, things we put here aren't actually in the TOC, so we can allow
21528 FP constants. */
21529 if (GET_CODE (x) == CONST_DOUBLE &&
21530 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
21532 REAL_VALUE_TYPE rv;
21533 long k[4];
21535 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21536 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21537 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
21538 else
21539 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
21541 if (TARGET_64BIT)
21543 if (TARGET_MINIMAL_TOC)
21544 fputs (DOUBLE_INT_ASM_OP, file);
21545 else
21546 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21547 k[0] & 0xffffffff, k[1] & 0xffffffff,
21548 k[2] & 0xffffffff, k[3] & 0xffffffff);
21549 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
21550 k[0] & 0xffffffff, k[1] & 0xffffffff,
21551 k[2] & 0xffffffff, k[3] & 0xffffffff);
21552 return;
21554 else
21556 if (TARGET_MINIMAL_TOC)
21557 fputs ("\t.long ", file);
21558 else
21559 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21560 k[0] & 0xffffffff, k[1] & 0xffffffff,
21561 k[2] & 0xffffffff, k[3] & 0xffffffff);
21562 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
21563 k[0] & 0xffffffff, k[1] & 0xffffffff,
21564 k[2] & 0xffffffff, k[3] & 0xffffffff);
21565 return;
21568 else if (GET_CODE (x) == CONST_DOUBLE &&
21569 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
21571 REAL_VALUE_TYPE rv;
21572 long k[2];
21574 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21576 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21577 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
21578 else
21579 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
21581 if (TARGET_64BIT)
21583 if (TARGET_MINIMAL_TOC)
21584 fputs (DOUBLE_INT_ASM_OP, file);
21585 else
21586 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21587 k[0] & 0xffffffff, k[1] & 0xffffffff);
21588 fprintf (file, "0x%lx%08lx\n",
21589 k[0] & 0xffffffff, k[1] & 0xffffffff);
21590 return;
21592 else
21594 if (TARGET_MINIMAL_TOC)
21595 fputs ("\t.long ", file);
21596 else
21597 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21598 k[0] & 0xffffffff, k[1] & 0xffffffff);
21599 fprintf (file, "0x%lx,0x%lx\n",
21600 k[0] & 0xffffffff, k[1] & 0xffffffff);
21601 return;
21604 else if (GET_CODE (x) == CONST_DOUBLE &&
21605 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
21607 REAL_VALUE_TYPE rv;
21608 long l;
21610 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21611 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21612 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
21613 else
21614 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
21616 if (TARGET_64BIT)
21618 if (TARGET_MINIMAL_TOC)
21619 fputs (DOUBLE_INT_ASM_OP, file);
21620 else
21621 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21622 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
21623 return;
21625 else
21627 if (TARGET_MINIMAL_TOC)
21628 fputs ("\t.long ", file);
21629 else
21630 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21631 fprintf (file, "0x%lx\n", l & 0xffffffff);
21632 return;
21635 else if (GET_MODE (x) == VOIDmode
21636 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
21638 unsigned HOST_WIDE_INT low;
21639 HOST_WIDE_INT high;
21641 if (GET_CODE (x) == CONST_DOUBLE)
21643 low = CONST_DOUBLE_LOW (x);
21644 high = CONST_DOUBLE_HIGH (x);
21646 else
21647 #if HOST_BITS_PER_WIDE_INT == 32
21649 low = INTVAL (x);
21650 high = (low & 0x80000000) ? ~0 : 0;
21652 #else
21654 low = INTVAL (x) & 0xffffffff;
21655 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21657 #endif
21659 /* TOC entries are always Pmode-sized, but since this
21660 is a bigendian machine then if we're putting smaller
21661 integer constants in the TOC we have to pad them.
21662 (This is still a win over putting the constants in
21663 a separate constant pool, because then we'd have
21664 to have both a TOC entry _and_ the actual constant.)
21666 For a 32-bit target, CONST_INT values are loaded and shifted
21667 entirely within `low' and can be stored in one TOC entry. */
21669 /* It would be easy to make this work, but it doesn't now. */
21670 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21672 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21674 #if HOST_BITS_PER_WIDE_INT == 32
21675 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21676 POINTER_SIZE, &low, &high, 0);
21677 #else
21678 low |= high << 32;
21679 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21680 high = (HOST_WIDE_INT) low >> 32;
21681 low &= 0xffffffff;
21682 #endif
21685 if (TARGET_64BIT)
21687 if (TARGET_MINIMAL_TOC)
21688 fputs (DOUBLE_INT_ASM_OP, file);
21689 else
21690 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21691 (long) high & 0xffffffff, (long) low & 0xffffffff);
21692 fprintf (file, "0x%lx%08lx\n",
21693 (long) high & 0xffffffff, (long) low & 0xffffffff);
21694 return;
21696 else
21698 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21700 if (TARGET_MINIMAL_TOC)
21701 fputs ("\t.long ", file);
21702 else
21703 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21704 (long) high & 0xffffffff, (long) low & 0xffffffff);
21705 fprintf (file, "0x%lx,0x%lx\n",
21706 (long) high & 0xffffffff, (long) low & 0xffffffff);
21708 else
21710 if (TARGET_MINIMAL_TOC)
21711 fputs ("\t.long ", file);
21712 else
21713 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21714 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21716 return;
21720 if (GET_CODE (x) == CONST)
21722 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21723 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21725 base = XEXP (XEXP (x, 0), 0);
21726 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21729 switch (GET_CODE (base))
21731 case SYMBOL_REF:
21732 name = XSTR (base, 0);
21733 break;
21735 case LABEL_REF:
21736 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21737 CODE_LABEL_NUMBER (XEXP (base, 0)));
21738 break;
21740 case CODE_LABEL:
21741 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21742 break;
21744 default:
21745 gcc_unreachable ();
21748 if (TARGET_MINIMAL_TOC)
21749 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21750 else
21752 fputs ("\t.tc ", file);
21753 RS6000_OUTPUT_BASENAME (file, name);
21755 if (offset < 0)
21756 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21757 else if (offset)
21758 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21760 fputs ("[TC],", file);
21763 /* Currently C++ toc references to vtables can be emitted before it
21764 is decided whether the vtable is public or private. If this is
21765 the case, then the linker will eventually complain that there is
21766 a TOC reference to an unknown section. Thus, for vtables only,
21767 we emit the TOC reference to reference the symbol and not the
21768 section. */
21769 if (VTABLE_NAME_P (name))
21771 RS6000_OUTPUT_BASENAME (file, name);
21772 if (offset < 0)
21773 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21774 else if (offset > 0)
21775 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21777 else
21778 output_addr_const (file, x);
21779 putc ('\n', file);
21782 /* Output an assembler pseudo-op to write an ASCII string of N characters
21783 starting at P to FILE.
21785 On the RS/6000, we have to do this using the .byte operation and
21786 write out special characters outside the quoted string.
21787 Also, the assembler is broken; very long strings are truncated,
21788 so we must artificially break them up early. */
21790 void
21791 output_ascii (FILE *file, const char *p, int n)
21793 char c;
21794 int i, count_string;
21795 const char *for_string = "\t.byte \"";
21796 const char *for_decimal = "\t.byte ";
21797 const char *to_close = NULL;
21799 count_string = 0;
21800 for (i = 0; i < n; i++)
21802 c = *p++;
21803 if (c >= ' ' && c < 0177)
21805 if (for_string)
21806 fputs (for_string, file);
21807 putc (c, file);
21809 /* Write two quotes to get one. */
21810 if (c == '"')
21812 putc (c, file);
21813 ++count_string;
21816 for_string = NULL;
21817 for_decimal = "\"\n\t.byte ";
21818 to_close = "\"\n";
21819 ++count_string;
21821 if (count_string >= 512)
21823 fputs (to_close, file);
21825 for_string = "\t.byte \"";
21826 for_decimal = "\t.byte ";
21827 to_close = NULL;
21828 count_string = 0;
21831 else
21833 if (for_decimal)
21834 fputs (for_decimal, file);
21835 fprintf (file, "%d", c);
21837 for_string = "\n\t.byte \"";
21838 for_decimal = ", ";
21839 to_close = "\n";
21840 count_string = 0;
21844 /* Now close the string if we have written one. Then end the line. */
21845 if (to_close)
21846 fputs (to_close, file);
21849 /* Generate a unique section name for FILENAME for a section type
21850 represented by SECTION_DESC. Output goes into BUF.
21852 SECTION_DESC can be any string, as long as it is different for each
21853 possible section type.
21855 We name the section in the same manner as xlc. The name begins with an
21856 underscore followed by the filename (after stripping any leading directory
21857 names) with the last period replaced by the string SECTION_DESC. If
21858 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21859 the name. */
21861 void
21862 rs6000_gen_section_name (char **buf, const char *filename,
21863 const char *section_desc)
21865 const char *q, *after_last_slash, *last_period = 0;
21866 char *p;
21867 int len;
21869 after_last_slash = filename;
21870 for (q = filename; *q; q++)
21872 if (*q == '/')
21873 after_last_slash = q + 1;
21874 else if (*q == '.')
21875 last_period = q;
21878 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21879 *buf = (char *) xmalloc (len);
21881 p = *buf;
21882 *p++ = '_';
21884 for (q = after_last_slash; *q; q++)
21886 if (q == last_period)
21888 strcpy (p, section_desc);
21889 p += strlen (section_desc);
21890 break;
21893 else if (ISALNUM (*q))
21894 *p++ = *q;
21897 if (last_period == 0)
21898 strcpy (p, section_desc);
21899 else
21900 *p = '\0';
21903 /* Emit profile function. */
21905 void
21906 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21908 /* Non-standard profiling for kernels, which just saves LR then calls
21909 _mcount without worrying about arg saves. The idea is to change
21910 the function prologue as little as possible as it isn't easy to
21911 account for arg save/restore code added just for _mcount. */
21912 if (TARGET_PROFILE_KERNEL)
21913 return;
21915 if (DEFAULT_ABI == ABI_AIX)
21917 #ifndef NO_PROFILE_COUNTERS
21918 # define NO_PROFILE_COUNTERS 0
21919 #endif
21920 if (NO_PROFILE_COUNTERS)
21921 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21922 LCT_NORMAL, VOIDmode, 0);
21923 else
21925 char buf[30];
21926 const char *label_name;
21927 rtx fun;
21929 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21930 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21931 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21933 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21934 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21937 else if (DEFAULT_ABI == ABI_DARWIN)
21939 const char *mcount_name = RS6000_MCOUNT;
21940 int caller_addr_regno = LR_REGNO;
21942 /* Be conservative and always set this, at least for now. */
21943 crtl->uses_pic_offset_table = 1;
21945 #if TARGET_MACHO
21946 /* For PIC code, set up a stub and collect the caller's address
21947 from r0, which is where the prologue puts it. */
21948 if (MACHOPIC_INDIRECT
21949 && crtl->uses_pic_offset_table)
21950 caller_addr_regno = 0;
21951 #endif
21952 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21953 LCT_NORMAL, VOIDmode, 1,
21954 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21958 /* Write function profiler code. */
21960 void
21961 output_function_profiler (FILE *file, int labelno)
21963 char buf[100];
21965 switch (DEFAULT_ABI)
21967 default:
21968 gcc_unreachable ();
21970 case ABI_V4:
21971 if (!TARGET_32BIT)
21973 warning (0, "no profiling of 64-bit code for this ABI");
21974 return;
21976 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21977 fprintf (file, "\tmflr %s\n", reg_names[0]);
21978 if (NO_PROFILE_COUNTERS)
21980 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21981 reg_names[0], reg_names[1]);
21983 else if (TARGET_SECURE_PLT && flag_pic)
21985 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21986 reg_names[0], reg_names[1]);
21987 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21988 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21989 reg_names[12], reg_names[12]);
21990 assemble_name (file, buf);
21991 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21992 assemble_name (file, buf);
21993 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21995 else if (flag_pic == 1)
21997 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21998 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21999 reg_names[0], reg_names[1]);
22000 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22001 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22002 assemble_name (file, buf);
22003 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22005 else if (flag_pic > 1)
22007 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22008 reg_names[0], reg_names[1]);
22009 /* Now, we need to get the address of the label. */
22010 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22011 assemble_name (file, buf);
22012 fputs ("-.\n1:", file);
22013 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22014 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22015 reg_names[0], reg_names[11]);
22016 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22017 reg_names[0], reg_names[0], reg_names[11]);
22019 else
22021 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22022 assemble_name (file, buf);
22023 fputs ("@ha\n", file);
22024 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22025 reg_names[0], reg_names[1]);
22026 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22027 assemble_name (file, buf);
22028 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22031 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22032 fprintf (file, "\tbl %s%s\n",
22033 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22034 break;
22036 case ABI_AIX:
22037 case ABI_DARWIN:
22038 if (!TARGET_PROFILE_KERNEL)
22040 /* Don't do anything, done in output_profile_hook (). */
22042 else
22044 gcc_assert (!TARGET_32BIT);
22046 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22047 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22049 if (cfun->static_chain_decl != NULL)
22051 asm_fprintf (file, "\tstd %s,24(%s)\n",
22052 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22053 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22054 asm_fprintf (file, "\tld %s,24(%s)\n",
22055 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22057 else
22058 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22060 break;
22066 /* The following variable value is the last issued insn. */
22068 static rtx last_scheduled_insn;
22070 /* The following variable helps to balance issuing of load and
22071 store instructions */
22073 static int load_store_pendulum;
22075 /* Power4 load update and store update instructions are cracked into a
22076 load or store and an integer insn which are executed in the same cycle.
22077 Branches have their own dispatch slot which does not count against the
22078 GCC issue rate, but it changes the program flow so there are no other
22079 instructions to issue in this cycle. */
22081 static int
22082 rs6000_variable_issue_1 (rtx insn, int more)
22084 last_scheduled_insn = insn;
22085 if (GET_CODE (PATTERN (insn)) == USE
22086 || GET_CODE (PATTERN (insn)) == CLOBBER)
22088 cached_can_issue_more = more;
22089 return cached_can_issue_more;
22092 if (insn_terminates_group_p (insn, current_group))
22094 cached_can_issue_more = 0;
22095 return cached_can_issue_more;
22098 /* If no reservation, but reach here */
22099 if (recog_memoized (insn) < 0)
22100 return more;
22102 if (rs6000_sched_groups)
22104 if (is_microcoded_insn (insn))
22105 cached_can_issue_more = 0;
22106 else if (is_cracked_insn (insn))
22107 cached_can_issue_more = more > 2 ? more - 2 : 0;
22108 else
22109 cached_can_issue_more = more - 1;
22111 return cached_can_issue_more;
22114 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22115 return 0;
22117 cached_can_issue_more = more - 1;
22118 return cached_can_issue_more;
22121 static int
22122 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22124 int r = rs6000_variable_issue_1 (insn, more);
22125 if (verbose)
22126 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22127 return r;
22130 /* Adjust the cost of a scheduling dependency. Return the new cost of
22131 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22133 static int
22134 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22136 enum attr_type attr_type;
22138 if (! recog_memoized (insn))
22139 return 0;
22141 switch (REG_NOTE_KIND (link))
22143 case REG_DEP_TRUE:
22145 /* Data dependency; DEP_INSN writes a register that INSN reads
22146 some cycles later. */
22148 /* Separate a load from a narrower, dependent store. */
22149 if (rs6000_sched_groups
22150 && GET_CODE (PATTERN (insn)) == SET
22151 && GET_CODE (PATTERN (dep_insn)) == SET
22152 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22153 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22154 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22155 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22156 return cost + 14;
22158 attr_type = get_attr_type (insn);
22160 switch (attr_type)
22162 case TYPE_JMPREG:
22163 /* Tell the first scheduling pass about the latency between
22164 a mtctr and bctr (and mtlr and br/blr). The first
22165 scheduling pass will not know about this latency since
22166 the mtctr instruction, which has the latency associated
22167 to it, will be generated by reload. */
22168 return TARGET_POWER ? 5 : 4;
22169 case TYPE_BRANCH:
22170 /* Leave some extra cycles between a compare and its
22171 dependent branch, to inhibit expensive mispredicts. */
22172 if ((rs6000_cpu_attr == CPU_PPC603
22173 || rs6000_cpu_attr == CPU_PPC604
22174 || rs6000_cpu_attr == CPU_PPC604E
22175 || rs6000_cpu_attr == CPU_PPC620
22176 || rs6000_cpu_attr == CPU_PPC630
22177 || rs6000_cpu_attr == CPU_PPC750
22178 || rs6000_cpu_attr == CPU_PPC7400
22179 || rs6000_cpu_attr == CPU_PPC7450
22180 || rs6000_cpu_attr == CPU_POWER4
22181 || rs6000_cpu_attr == CPU_POWER5
22182 || rs6000_cpu_attr == CPU_POWER7
22183 || rs6000_cpu_attr == CPU_CELL)
22184 && recog_memoized (dep_insn)
22185 && (INSN_CODE (dep_insn) >= 0))
22187 switch (get_attr_type (dep_insn))
22189 case TYPE_CMP:
22190 case TYPE_COMPARE:
22191 case TYPE_DELAYED_COMPARE:
22192 case TYPE_IMUL_COMPARE:
22193 case TYPE_LMUL_COMPARE:
22194 case TYPE_FPCOMPARE:
22195 case TYPE_CR_LOGICAL:
22196 case TYPE_DELAYED_CR:
22197 return cost + 2;
22198 default:
22199 break;
22201 break;
22203 case TYPE_STORE:
22204 case TYPE_STORE_U:
22205 case TYPE_STORE_UX:
22206 case TYPE_FPSTORE:
22207 case TYPE_FPSTORE_U:
22208 case TYPE_FPSTORE_UX:
22209 if ((rs6000_cpu == PROCESSOR_POWER6)
22210 && recog_memoized (dep_insn)
22211 && (INSN_CODE (dep_insn) >= 0))
22214 if (GET_CODE (PATTERN (insn)) != SET)
22215 /* If this happens, we have to extend this to schedule
22216 optimally. Return default for now. */
22217 return cost;
22219 /* Adjust the cost for the case where the value written
22220 by a fixed point operation is used as the address
22221 gen value on a store. */
22222 switch (get_attr_type (dep_insn))
22224 case TYPE_LOAD:
22225 case TYPE_LOAD_U:
22226 case TYPE_LOAD_UX:
22227 case TYPE_CNTLZ:
22229 if (! store_data_bypass_p (dep_insn, insn))
22230 return 4;
22231 break;
22233 case TYPE_LOAD_EXT:
22234 case TYPE_LOAD_EXT_U:
22235 case TYPE_LOAD_EXT_UX:
22236 case TYPE_VAR_SHIFT_ROTATE:
22237 case TYPE_VAR_DELAYED_COMPARE:
22239 if (! store_data_bypass_p (dep_insn, insn))
22240 return 6;
22241 break;
22243 case TYPE_INTEGER:
22244 case TYPE_COMPARE:
22245 case TYPE_FAST_COMPARE:
22246 case TYPE_EXTS:
22247 case TYPE_SHIFT:
22248 case TYPE_INSERT_WORD:
22249 case TYPE_INSERT_DWORD:
22250 case TYPE_FPLOAD_U:
22251 case TYPE_FPLOAD_UX:
22252 case TYPE_STORE_U:
22253 case TYPE_STORE_UX:
22254 case TYPE_FPSTORE_U:
22255 case TYPE_FPSTORE_UX:
22257 if (! store_data_bypass_p (dep_insn, insn))
22258 return 3;
22259 break;
22261 case TYPE_IMUL:
22262 case TYPE_IMUL2:
22263 case TYPE_IMUL3:
22264 case TYPE_LMUL:
22265 case TYPE_IMUL_COMPARE:
22266 case TYPE_LMUL_COMPARE:
22268 if (! store_data_bypass_p (dep_insn, insn))
22269 return 17;
22270 break;
22272 case TYPE_IDIV:
22274 if (! store_data_bypass_p (dep_insn, insn))
22275 return 45;
22276 break;
22278 case TYPE_LDIV:
22280 if (! store_data_bypass_p (dep_insn, insn))
22281 return 57;
22282 break;
22284 default:
22285 break;
22288 break;
22290 case TYPE_LOAD:
22291 case TYPE_LOAD_U:
22292 case TYPE_LOAD_UX:
22293 case TYPE_LOAD_EXT:
22294 case TYPE_LOAD_EXT_U:
22295 case TYPE_LOAD_EXT_UX:
22296 if ((rs6000_cpu == PROCESSOR_POWER6)
22297 && recog_memoized (dep_insn)
22298 && (INSN_CODE (dep_insn) >= 0))
22301 /* Adjust the cost for the case where the value written
22302 by a fixed point instruction is used within the address
22303 gen portion of a subsequent load(u)(x) */
22304 switch (get_attr_type (dep_insn))
22306 case TYPE_LOAD:
22307 case TYPE_LOAD_U:
22308 case TYPE_LOAD_UX:
22309 case TYPE_CNTLZ:
22311 if (set_to_load_agen (dep_insn, insn))
22312 return 4;
22313 break;
22315 case TYPE_LOAD_EXT:
22316 case TYPE_LOAD_EXT_U:
22317 case TYPE_LOAD_EXT_UX:
22318 case TYPE_VAR_SHIFT_ROTATE:
22319 case TYPE_VAR_DELAYED_COMPARE:
22321 if (set_to_load_agen (dep_insn, insn))
22322 return 6;
22323 break;
22325 case TYPE_INTEGER:
22326 case TYPE_COMPARE:
22327 case TYPE_FAST_COMPARE:
22328 case TYPE_EXTS:
22329 case TYPE_SHIFT:
22330 case TYPE_INSERT_WORD:
22331 case TYPE_INSERT_DWORD:
22332 case TYPE_FPLOAD_U:
22333 case TYPE_FPLOAD_UX:
22334 case TYPE_STORE_U:
22335 case TYPE_STORE_UX:
22336 case TYPE_FPSTORE_U:
22337 case TYPE_FPSTORE_UX:
22339 if (set_to_load_agen (dep_insn, insn))
22340 return 3;
22341 break;
22343 case TYPE_IMUL:
22344 case TYPE_IMUL2:
22345 case TYPE_IMUL3:
22346 case TYPE_LMUL:
22347 case TYPE_IMUL_COMPARE:
22348 case TYPE_LMUL_COMPARE:
22350 if (set_to_load_agen (dep_insn, insn))
22351 return 17;
22352 break;
22354 case TYPE_IDIV:
22356 if (set_to_load_agen (dep_insn, insn))
22357 return 45;
22358 break;
22360 case TYPE_LDIV:
22362 if (set_to_load_agen (dep_insn, insn))
22363 return 57;
22364 break;
22366 default:
22367 break;
22370 break;
22372 case TYPE_FPLOAD:
22373 if ((rs6000_cpu == PROCESSOR_POWER6)
22374 && recog_memoized (dep_insn)
22375 && (INSN_CODE (dep_insn) >= 0)
22376 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22377 return 2;
22379 default:
22380 break;
22383 /* Fall out to return default cost. */
22385 break;
22387 case REG_DEP_OUTPUT:
22388 /* Output dependency; DEP_INSN writes a register that INSN writes some
22389 cycles later. */
22390 if ((rs6000_cpu == PROCESSOR_POWER6)
22391 && recog_memoized (dep_insn)
22392 && (INSN_CODE (dep_insn) >= 0))
22394 attr_type = get_attr_type (insn);
22396 switch (attr_type)
22398 case TYPE_FP:
22399 if (get_attr_type (dep_insn) == TYPE_FP)
22400 return 1;
22401 break;
22402 case TYPE_FPLOAD:
22403 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22404 return 2;
22405 break;
22406 default:
22407 break;
22410 case REG_DEP_ANTI:
22411 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22412 cycles later. */
22413 return 0;
22415 default:
22416 gcc_unreachable ();
22419 return cost;
22422 /* Debug version of rs6000_adjust_cost. */
22424 static int
22425 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22427 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22429 if (ret != cost)
22431 const char *dep;
22433 switch (REG_NOTE_KIND (link))
22435 default: dep = "unknown depencency"; break;
22436 case REG_DEP_TRUE: dep = "data dependency"; break;
22437 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22438 case REG_DEP_ANTI: dep = "anti depencency"; break;
22441 fprintf (stderr,
22442 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22443 "%s, insn:\n", ret, cost, dep);
22445 debug_rtx (insn);
22448 return ret;
22451 /* The function returns a true if INSN is microcoded.
22452 Return false otherwise. */
22454 static bool
22455 is_microcoded_insn (rtx insn)
22457 if (!insn || !NONDEBUG_INSN_P (insn)
22458 || GET_CODE (PATTERN (insn)) == USE
22459 || GET_CODE (PATTERN (insn)) == CLOBBER)
22460 return false;
22462 if (rs6000_cpu_attr == CPU_CELL)
22463 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22465 if (rs6000_sched_groups)
22467 enum attr_type type = get_attr_type (insn);
22468 if (type == TYPE_LOAD_EXT_U
22469 || type == TYPE_LOAD_EXT_UX
22470 || type == TYPE_LOAD_UX
22471 || type == TYPE_STORE_UX
22472 || type == TYPE_MFCR)
22473 return true;
22476 return false;
22479 /* The function returns true if INSN is cracked into 2 instructions
22480 by the processor (and therefore occupies 2 issue slots). */
22482 static bool
22483 is_cracked_insn (rtx insn)
22485 if (!insn || !NONDEBUG_INSN_P (insn)
22486 || GET_CODE (PATTERN (insn)) == USE
22487 || GET_CODE (PATTERN (insn)) == CLOBBER)
22488 return false;
22490 if (rs6000_sched_groups)
22492 enum attr_type type = get_attr_type (insn);
22493 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22494 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22495 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22496 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22497 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22498 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22499 || type == TYPE_IDIV || type == TYPE_LDIV
22500 || type == TYPE_INSERT_WORD)
22501 return true;
22504 return false;
22507 /* The function returns true if INSN can be issued only from
22508 the branch slot. */
22510 static bool
22511 is_branch_slot_insn (rtx insn)
22513 if (!insn || !NONDEBUG_INSN_P (insn)
22514 || GET_CODE (PATTERN (insn)) == USE
22515 || GET_CODE (PATTERN (insn)) == CLOBBER)
22516 return false;
22518 if (rs6000_sched_groups)
22520 enum attr_type type = get_attr_type (insn);
22521 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22522 return true;
22523 return false;
22526 return false;
22529 /* The function returns true if out_inst sets a value that is
22530 used in the address generation computation of in_insn */
22531 static bool
22532 set_to_load_agen (rtx out_insn, rtx in_insn)
22534 rtx out_set, in_set;
22536 /* For performance reasons, only handle the simple case where
22537 both loads are a single_set. */
22538 out_set = single_set (out_insn);
22539 if (out_set)
22541 in_set = single_set (in_insn);
22542 if (in_set)
22543 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
22546 return false;
22549 /* The function returns true if the target storage location of
22550 out_insn is adjacent to the target storage location of in_insn */
22551 /* Return 1 if memory locations are adjacent. */
22553 static bool
22554 adjacent_mem_locations (rtx insn1, rtx insn2)
22557 rtx a = get_store_dest (PATTERN (insn1));
22558 rtx b = get_store_dest (PATTERN (insn2));
22560 if ((GET_CODE (XEXP (a, 0)) == REG
22561 || (GET_CODE (XEXP (a, 0)) == PLUS
22562 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
22563 && (GET_CODE (XEXP (b, 0)) == REG
22564 || (GET_CODE (XEXP (b, 0)) == PLUS
22565 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
22567 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
22568 rtx reg0, reg1;
22570 if (GET_CODE (XEXP (a, 0)) == PLUS)
22572 reg0 = XEXP (XEXP (a, 0), 0);
22573 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
22575 else
22576 reg0 = XEXP (a, 0);
22578 if (GET_CODE (XEXP (b, 0)) == PLUS)
22580 reg1 = XEXP (XEXP (b, 0), 0);
22581 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
22583 else
22584 reg1 = XEXP (b, 0);
22586 val_diff = val1 - val0;
22588 return ((REGNO (reg0) == REGNO (reg1))
22589 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
22590 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
22593 return false;
22596 /* A C statement (sans semicolon) to update the integer scheduling
22597 priority INSN_PRIORITY (INSN). Increase the priority to execute the
22598 INSN earlier, reduce the priority to execute INSN later. Do not
22599 define this macro if you do not need to adjust the scheduling
22600 priorities of insns. */
22602 static int
22603 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
22605 /* On machines (like the 750) which have asymmetric integer units,
22606 where one integer unit can do multiply and divides and the other
22607 can't, reduce the priority of multiply/divide so it is scheduled
22608 before other integer operations. */
22610 #if 0
22611 if (! INSN_P (insn))
22612 return priority;
22614 if (GET_CODE (PATTERN (insn)) == USE)
22615 return priority;
22617 switch (rs6000_cpu_attr) {
22618 case CPU_PPC750:
22619 switch (get_attr_type (insn))
22621 default:
22622 break;
22624 case TYPE_IMUL:
22625 case TYPE_IDIV:
22626 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
22627 priority, priority);
22628 if (priority >= 0 && priority < 0x01000000)
22629 priority >>= 3;
22630 break;
22633 #endif
22635 if (insn_must_be_first_in_group (insn)
22636 && reload_completed
22637 && current_sched_info->sched_max_insns_priority
22638 && rs6000_sched_restricted_insns_priority)
22641 /* Prioritize insns that can be dispatched only in the first
22642 dispatch slot. */
22643 if (rs6000_sched_restricted_insns_priority == 1)
22644 /* Attach highest priority to insn. This means that in
22645 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22646 precede 'priority' (critical path) considerations. */
22647 return current_sched_info->sched_max_insns_priority;
22648 else if (rs6000_sched_restricted_insns_priority == 2)
22649 /* Increase priority of insn by a minimal amount. This means that in
22650 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22651 considerations precede dispatch-slot restriction considerations. */
22652 return (priority + 1);
22655 if (rs6000_cpu == PROCESSOR_POWER6
22656 && ((load_store_pendulum == -2 && is_load_insn (insn))
22657 || (load_store_pendulum == 2 && is_store_insn (insn))))
22658 /* Attach highest priority to insn if the scheduler has just issued two
22659 stores and this instruction is a load, or two loads and this instruction
22660 is a store. Power6 wants loads and stores scheduled alternately
22661 when possible */
22662 return current_sched_info->sched_max_insns_priority;
22664 return priority;
22667 /* Return true if the instruction is nonpipelined on the Cell. */
22668 static bool
22669 is_nonpipeline_insn (rtx insn)
22671 enum attr_type type;
22672 if (!insn || !NONDEBUG_INSN_P (insn)
22673 || GET_CODE (PATTERN (insn)) == USE
22674 || GET_CODE (PATTERN (insn)) == CLOBBER)
22675 return false;
22677 type = get_attr_type (insn);
22678 if (type == TYPE_IMUL
22679 || type == TYPE_IMUL2
22680 || type == TYPE_IMUL3
22681 || type == TYPE_LMUL
22682 || type == TYPE_IDIV
22683 || type == TYPE_LDIV
22684 || type == TYPE_SDIV
22685 || type == TYPE_DDIV
22686 || type == TYPE_SSQRT
22687 || type == TYPE_DSQRT
22688 || type == TYPE_MFCR
22689 || type == TYPE_MFCRF
22690 || type == TYPE_MFJMPR)
22692 return true;
22694 return false;
22698 /* Return how many instructions the machine can issue per cycle. */
22700 static int
22701 rs6000_issue_rate (void)
22703 /* Unless scheduling for register pressure, use issue rate of 1 for
22704 first scheduling pass to decrease degradation. */
22705 if (!reload_completed && !flag_sched_pressure)
22706 return 1;
22708 switch (rs6000_cpu_attr) {
22709 case CPU_RIOS1: /* ? */
22710 case CPU_RS64A:
22711 case CPU_PPC601: /* ? */
22712 case CPU_PPC7450:
22713 return 3;
22714 case CPU_PPC440:
22715 case CPU_PPC603:
22716 case CPU_PPC750:
22717 case CPU_PPC7400:
22718 case CPU_PPC8540:
22719 case CPU_CELL:
22720 case CPU_PPCE300C2:
22721 case CPU_PPCE300C3:
22722 case CPU_PPCE500MC:
22723 case CPU_PPCE500MC64:
22724 case CPU_TITAN:
22725 return 2;
22726 case CPU_RIOS2:
22727 case CPU_PPC476:
22728 case CPU_PPC604:
22729 case CPU_PPC604E:
22730 case CPU_PPC620:
22731 case CPU_PPC630:
22732 return 4;
22733 case CPU_POWER4:
22734 case CPU_POWER5:
22735 case CPU_POWER6:
22736 case CPU_POWER7:
22737 return 5;
22738 default:
22739 return 1;
22743 /* Return how many instructions to look ahead for better insn
22744 scheduling. */
22746 static int
22747 rs6000_use_sched_lookahead (void)
22749 if (rs6000_cpu_attr == CPU_PPC8540)
22750 return 4;
22751 if (rs6000_cpu_attr == CPU_CELL)
22752 return (reload_completed ? 8 : 0);
22753 return 0;
22756 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22757 static int
22758 rs6000_use_sched_lookahead_guard (rtx insn)
22760 if (rs6000_cpu_attr != CPU_CELL)
22761 return 1;
22763 if (insn == NULL_RTX || !INSN_P (insn))
22764 abort ();
22766 if (!reload_completed
22767 || is_nonpipeline_insn (insn)
22768 || is_microcoded_insn (insn))
22769 return 0;
22771 return 1;
22774 /* Determine is PAT refers to memory. */
22776 static bool
22777 is_mem_ref (rtx pat)
22779 const char * fmt;
22780 int i, j;
22781 bool ret = false;
22783 /* stack_tie does not produce any real memory traffic. */
22784 if (GET_CODE (pat) == UNSPEC
22785 && XINT (pat, 1) == UNSPEC_TIE)
22786 return false;
22788 if (GET_CODE (pat) == MEM)
22789 return true;
22791 /* Recursively process the pattern. */
22792 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22794 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22796 if (fmt[i] == 'e')
22797 ret |= is_mem_ref (XEXP (pat, i));
22798 else if (fmt[i] == 'E')
22799 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22800 ret |= is_mem_ref (XVECEXP (pat, i, j));
22803 return ret;
22806 /* Determine if PAT is a PATTERN of a load insn. */
22808 static bool
22809 is_load_insn1 (rtx pat)
22811 if (!pat || pat == NULL_RTX)
22812 return false;
22814 if (GET_CODE (pat) == SET)
22815 return is_mem_ref (SET_SRC (pat));
22817 if (GET_CODE (pat) == PARALLEL)
22819 int i;
22821 for (i = 0; i < XVECLEN (pat, 0); i++)
22822 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22823 return true;
22826 return false;
22829 /* Determine if INSN loads from memory. */
22831 static bool
22832 is_load_insn (rtx insn)
22834 if (!insn || !INSN_P (insn))
22835 return false;
22837 if (GET_CODE (insn) == CALL_INSN)
22838 return false;
22840 return is_load_insn1 (PATTERN (insn));
22843 /* Determine if PAT is a PATTERN of a store insn. */
22845 static bool
22846 is_store_insn1 (rtx pat)
22848 if (!pat || pat == NULL_RTX)
22849 return false;
22851 if (GET_CODE (pat) == SET)
22852 return is_mem_ref (SET_DEST (pat));
22854 if (GET_CODE (pat) == PARALLEL)
22856 int i;
22858 for (i = 0; i < XVECLEN (pat, 0); i++)
22859 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22860 return true;
22863 return false;
22866 /* Determine if INSN stores to memory. */
22868 static bool
22869 is_store_insn (rtx insn)
22871 if (!insn || !INSN_P (insn))
22872 return false;
22874 return is_store_insn1 (PATTERN (insn));
22877 /* Return the dest of a store insn. */
22879 static rtx
22880 get_store_dest (rtx pat)
22882 gcc_assert (is_store_insn1 (pat));
22884 if (GET_CODE (pat) == SET)
22885 return SET_DEST (pat);
22886 else if (GET_CODE (pat) == PARALLEL)
22888 int i;
22890 for (i = 0; i < XVECLEN (pat, 0); i++)
22892 rtx inner_pat = XVECEXP (pat, 0, i);
22893 if (GET_CODE (inner_pat) == SET
22894 && is_mem_ref (SET_DEST (inner_pat)))
22895 return inner_pat;
22898 /* We shouldn't get here, because we should have either a simple
22899 store insn or a store with update which are covered above. */
22900 gcc_unreachable();
22903 /* Returns whether the dependence between INSN and NEXT is considered
22904 costly by the given target. */
22906 static bool
22907 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22909 rtx insn;
22910 rtx next;
22912 /* If the flag is not enabled - no dependence is considered costly;
22913 allow all dependent insns in the same group.
22914 This is the most aggressive option. */
22915 if (rs6000_sched_costly_dep == no_dep_costly)
22916 return false;
22918 /* If the flag is set to 1 - a dependence is always considered costly;
22919 do not allow dependent instructions in the same group.
22920 This is the most conservative option. */
22921 if (rs6000_sched_costly_dep == all_deps_costly)
22922 return true;
22924 insn = DEP_PRO (dep);
22925 next = DEP_CON (dep);
22927 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22928 && is_load_insn (next)
22929 && is_store_insn (insn))
22930 /* Prevent load after store in the same group. */
22931 return true;
22933 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22934 && is_load_insn (next)
22935 && is_store_insn (insn)
22936 && DEP_TYPE (dep) == REG_DEP_TRUE)
22937 /* Prevent load after store in the same group if it is a true
22938 dependence. */
22939 return true;
22941 /* The flag is set to X; dependences with latency >= X are considered costly,
22942 and will not be scheduled in the same group. */
22943 if (rs6000_sched_costly_dep <= max_dep_latency
22944 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22945 return true;
22947 return false;
22950 /* Return the next insn after INSN that is found before TAIL is reached,
22951 skipping any "non-active" insns - insns that will not actually occupy
22952 an issue slot. Return NULL_RTX if such an insn is not found. */
22954 static rtx
22955 get_next_active_insn (rtx insn, rtx tail)
22957 if (insn == NULL_RTX || insn == tail)
22958 return NULL_RTX;
22960 while (1)
22962 insn = NEXT_INSN (insn);
22963 if (insn == NULL_RTX || insn == tail)
22964 return NULL_RTX;
22966 if (CALL_P (insn)
22967 || JUMP_P (insn)
22968 || (NONJUMP_INSN_P (insn)
22969 && GET_CODE (PATTERN (insn)) != USE
22970 && GET_CODE (PATTERN (insn)) != CLOBBER
22971 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22972 break;
22974 return insn;
22977 /* We are about to begin issuing insns for this clock cycle. */
22979 static int
22980 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22981 rtx *ready ATTRIBUTE_UNUSED,
22982 int *pn_ready ATTRIBUTE_UNUSED,
22983 int clock_var ATTRIBUTE_UNUSED)
22985 int n_ready = *pn_ready;
22987 if (sched_verbose)
22988 fprintf (dump, "// rs6000_sched_reorder :\n");
22990 /* Reorder the ready list, if the second to last ready insn
22991 is a nonepipeline insn. */
22992 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22994 if (is_nonpipeline_insn (ready[n_ready - 1])
22995 && (recog_memoized (ready[n_ready - 2]) > 0))
22996 /* Simply swap first two insns. */
22998 rtx tmp = ready[n_ready - 1];
22999 ready[n_ready - 1] = ready[n_ready - 2];
23000 ready[n_ready - 2] = tmp;
23004 if (rs6000_cpu == PROCESSOR_POWER6)
23005 load_store_pendulum = 0;
23007 return rs6000_issue_rate ();
23010 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23012 static int
23013 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23014 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23016 if (sched_verbose)
23017 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23019 /* For Power6, we need to handle some special cases to try and keep the
23020 store queue from overflowing and triggering expensive flushes.
23022 This code monitors how load and store instructions are being issued
23023 and skews the ready list one way or the other to increase the likelihood
23024 that a desired instruction is issued at the proper time.
23026 A couple of things are done. First, we maintain a "load_store_pendulum"
23027 to track the current state of load/store issue.
23029 - If the pendulum is at zero, then no loads or stores have been
23030 issued in the current cycle so we do nothing.
23032 - If the pendulum is 1, then a single load has been issued in this
23033 cycle and we attempt to locate another load in the ready list to
23034 issue with it.
23036 - If the pendulum is -2, then two stores have already been
23037 issued in this cycle, so we increase the priority of the first load
23038 in the ready list to increase it's likelihood of being chosen first
23039 in the next cycle.
23041 - If the pendulum is -1, then a single store has been issued in this
23042 cycle and we attempt to locate another store in the ready list to
23043 issue with it, preferring a store to an adjacent memory location to
23044 facilitate store pairing in the store queue.
23046 - If the pendulum is 2, then two loads have already been
23047 issued in this cycle, so we increase the priority of the first store
23048 in the ready list to increase it's likelihood of being chosen first
23049 in the next cycle.
23051 - If the pendulum < -2 or > 2, then do nothing.
23053 Note: This code covers the most common scenarios. There exist non
23054 load/store instructions which make use of the LSU and which
23055 would need to be accounted for to strictly model the behavior
23056 of the machine. Those instructions are currently unaccounted
23057 for to help minimize compile time overhead of this code.
23059 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23061 int pos;
23062 int i;
23063 rtx tmp;
23065 if (is_store_insn (last_scheduled_insn))
23066 /* Issuing a store, swing the load_store_pendulum to the left */
23067 load_store_pendulum--;
23068 else if (is_load_insn (last_scheduled_insn))
23069 /* Issuing a load, swing the load_store_pendulum to the right */
23070 load_store_pendulum++;
23071 else
23072 return cached_can_issue_more;
23074 /* If the pendulum is balanced, or there is only one instruction on
23075 the ready list, then all is well, so return. */
23076 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23077 return cached_can_issue_more;
23079 if (load_store_pendulum == 1)
23081 /* A load has been issued in this cycle. Scan the ready list
23082 for another load to issue with it */
23083 pos = *pn_ready-1;
23085 while (pos >= 0)
23087 if (is_load_insn (ready[pos]))
23089 /* Found a load. Move it to the head of the ready list,
23090 and adjust it's priority so that it is more likely to
23091 stay there */
23092 tmp = ready[pos];
23093 for (i=pos; i<*pn_ready-1; i++)
23094 ready[i] = ready[i + 1];
23095 ready[*pn_ready-1] = tmp;
23097 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23098 INSN_PRIORITY (tmp)++;
23099 break;
23101 pos--;
23104 else if (load_store_pendulum == -2)
23106 /* Two stores have been issued in this cycle. Increase the
23107 priority of the first load in the ready list to favor it for
23108 issuing in the next cycle. */
23109 pos = *pn_ready-1;
23111 while (pos >= 0)
23113 if (is_load_insn (ready[pos])
23114 && !sel_sched_p ()
23115 && INSN_PRIORITY_KNOWN (ready[pos]))
23117 INSN_PRIORITY (ready[pos])++;
23119 /* Adjust the pendulum to account for the fact that a load
23120 was found and increased in priority. This is to prevent
23121 increasing the priority of multiple loads */
23122 load_store_pendulum--;
23124 break;
23126 pos--;
23129 else if (load_store_pendulum == -1)
23131 /* A store has been issued in this cycle. Scan the ready list for
23132 another store to issue with it, preferring a store to an adjacent
23133 memory location */
23134 int first_store_pos = -1;
23136 pos = *pn_ready-1;
23138 while (pos >= 0)
23140 if (is_store_insn (ready[pos]))
23142 /* Maintain the index of the first store found on the
23143 list */
23144 if (first_store_pos == -1)
23145 first_store_pos = pos;
23147 if (is_store_insn (last_scheduled_insn)
23148 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23150 /* Found an adjacent store. Move it to the head of the
23151 ready list, and adjust it's priority so that it is
23152 more likely to stay there */
23153 tmp = ready[pos];
23154 for (i=pos; i<*pn_ready-1; i++)
23155 ready[i] = ready[i + 1];
23156 ready[*pn_ready-1] = tmp;
23158 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23159 INSN_PRIORITY (tmp)++;
23161 first_store_pos = -1;
23163 break;
23166 pos--;
23169 if (first_store_pos >= 0)
23171 /* An adjacent store wasn't found, but a non-adjacent store was,
23172 so move the non-adjacent store to the front of the ready
23173 list, and adjust its priority so that it is more likely to
23174 stay there. */
23175 tmp = ready[first_store_pos];
23176 for (i=first_store_pos; i<*pn_ready-1; i++)
23177 ready[i] = ready[i + 1];
23178 ready[*pn_ready-1] = tmp;
23179 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23180 INSN_PRIORITY (tmp)++;
23183 else if (load_store_pendulum == 2)
23185 /* Two loads have been issued in this cycle. Increase the priority
23186 of the first store in the ready list to favor it for issuing in
23187 the next cycle. */
23188 pos = *pn_ready-1;
23190 while (pos >= 0)
23192 if (is_store_insn (ready[pos])
23193 && !sel_sched_p ()
23194 && INSN_PRIORITY_KNOWN (ready[pos]))
23196 INSN_PRIORITY (ready[pos])++;
23198 /* Adjust the pendulum to account for the fact that a store
23199 was found and increased in priority. This is to prevent
23200 increasing the priority of multiple stores */
23201 load_store_pendulum++;
23203 break;
23205 pos--;
23210 return cached_can_issue_more;
23213 /* Return whether the presence of INSN causes a dispatch group termination
23214 of group WHICH_GROUP.
23216 If WHICH_GROUP == current_group, this function will return true if INSN
23217 causes the termination of the current group (i.e, the dispatch group to
23218 which INSN belongs). This means that INSN will be the last insn in the
23219 group it belongs to.
23221 If WHICH_GROUP == previous_group, this function will return true if INSN
23222 causes the termination of the previous group (i.e, the dispatch group that
23223 precedes the group to which INSN belongs). This means that INSN will be
23224 the first insn in the group it belongs to). */
23226 static bool
23227 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23229 bool first, last;
23231 if (! insn)
23232 return false;
23234 first = insn_must_be_first_in_group (insn);
23235 last = insn_must_be_last_in_group (insn);
23237 if (first && last)
23238 return true;
23240 if (which_group == current_group)
23241 return last;
23242 else if (which_group == previous_group)
23243 return first;
23245 return false;
23249 static bool
23250 insn_must_be_first_in_group (rtx insn)
23252 enum attr_type type;
23254 if (!insn
23255 || GET_CODE (insn) == NOTE
23256 || DEBUG_INSN_P (insn)
23257 || GET_CODE (PATTERN (insn)) == USE
23258 || GET_CODE (PATTERN (insn)) == CLOBBER)
23259 return false;
23261 switch (rs6000_cpu)
23263 case PROCESSOR_POWER5:
23264 if (is_cracked_insn (insn))
23265 return true;
23266 case PROCESSOR_POWER4:
23267 if (is_microcoded_insn (insn))
23268 return true;
23270 if (!rs6000_sched_groups)
23271 return false;
23273 type = get_attr_type (insn);
23275 switch (type)
23277 case TYPE_MFCR:
23278 case TYPE_MFCRF:
23279 case TYPE_MTCR:
23280 case TYPE_DELAYED_CR:
23281 case TYPE_CR_LOGICAL:
23282 case TYPE_MTJMPR:
23283 case TYPE_MFJMPR:
23284 case TYPE_IDIV:
23285 case TYPE_LDIV:
23286 case TYPE_LOAD_L:
23287 case TYPE_STORE_C:
23288 case TYPE_ISYNC:
23289 case TYPE_SYNC:
23290 return true;
23291 default:
23292 break;
23294 break;
23295 case PROCESSOR_POWER6:
23296 type = get_attr_type (insn);
23298 switch (type)
23300 case TYPE_INSERT_DWORD:
23301 case TYPE_EXTS:
23302 case TYPE_CNTLZ:
23303 case TYPE_SHIFT:
23304 case TYPE_VAR_SHIFT_ROTATE:
23305 case TYPE_TRAP:
23306 case TYPE_IMUL:
23307 case TYPE_IMUL2:
23308 case TYPE_IMUL3:
23309 case TYPE_LMUL:
23310 case TYPE_IDIV:
23311 case TYPE_INSERT_WORD:
23312 case TYPE_DELAYED_COMPARE:
23313 case TYPE_IMUL_COMPARE:
23314 case TYPE_LMUL_COMPARE:
23315 case TYPE_FPCOMPARE:
23316 case TYPE_MFCR:
23317 case TYPE_MTCR:
23318 case TYPE_MFJMPR:
23319 case TYPE_MTJMPR:
23320 case TYPE_ISYNC:
23321 case TYPE_SYNC:
23322 case TYPE_LOAD_L:
23323 case TYPE_STORE_C:
23324 case TYPE_LOAD_U:
23325 case TYPE_LOAD_UX:
23326 case TYPE_LOAD_EXT_UX:
23327 case TYPE_STORE_U:
23328 case TYPE_STORE_UX:
23329 case TYPE_FPLOAD_U:
23330 case TYPE_FPLOAD_UX:
23331 case TYPE_FPSTORE_U:
23332 case TYPE_FPSTORE_UX:
23333 return true;
23334 default:
23335 break;
23337 break;
23338 case PROCESSOR_POWER7:
23339 type = get_attr_type (insn);
23341 switch (type)
23343 case TYPE_CR_LOGICAL:
23344 case TYPE_MFCR:
23345 case TYPE_MFCRF:
23346 case TYPE_MTCR:
23347 case TYPE_IDIV:
23348 case TYPE_LDIV:
23349 case TYPE_COMPARE:
23350 case TYPE_DELAYED_COMPARE:
23351 case TYPE_VAR_DELAYED_COMPARE:
23352 case TYPE_ISYNC:
23353 case TYPE_LOAD_L:
23354 case TYPE_STORE_C:
23355 case TYPE_LOAD_U:
23356 case TYPE_LOAD_UX:
23357 case TYPE_LOAD_EXT:
23358 case TYPE_LOAD_EXT_U:
23359 case TYPE_LOAD_EXT_UX:
23360 case TYPE_STORE_U:
23361 case TYPE_STORE_UX:
23362 case TYPE_FPLOAD_U:
23363 case TYPE_FPLOAD_UX:
23364 case TYPE_FPSTORE_U:
23365 case TYPE_FPSTORE_UX:
23366 case TYPE_MFJMPR:
23367 case TYPE_MTJMPR:
23368 return true;
23369 default:
23370 break;
23372 break;
23373 default:
23374 break;
23377 return false;
23380 static bool
23381 insn_must_be_last_in_group (rtx insn)
23383 enum attr_type type;
23385 if (!insn
23386 || GET_CODE (insn) == NOTE
23387 || DEBUG_INSN_P (insn)
23388 || GET_CODE (PATTERN (insn)) == USE
23389 || GET_CODE (PATTERN (insn)) == CLOBBER)
23390 return false;
23392 switch (rs6000_cpu) {
23393 case PROCESSOR_POWER4:
23394 case PROCESSOR_POWER5:
23395 if (is_microcoded_insn (insn))
23396 return true;
23398 if (is_branch_slot_insn (insn))
23399 return true;
23401 break;
23402 case PROCESSOR_POWER6:
23403 type = get_attr_type (insn);
23405 switch (type)
23407 case TYPE_EXTS:
23408 case TYPE_CNTLZ:
23409 case TYPE_SHIFT:
23410 case TYPE_VAR_SHIFT_ROTATE:
23411 case TYPE_TRAP:
23412 case TYPE_IMUL:
23413 case TYPE_IMUL2:
23414 case TYPE_IMUL3:
23415 case TYPE_LMUL:
23416 case TYPE_IDIV:
23417 case TYPE_DELAYED_COMPARE:
23418 case TYPE_IMUL_COMPARE:
23419 case TYPE_LMUL_COMPARE:
23420 case TYPE_FPCOMPARE:
23421 case TYPE_MFCR:
23422 case TYPE_MTCR:
23423 case TYPE_MFJMPR:
23424 case TYPE_MTJMPR:
23425 case TYPE_ISYNC:
23426 case TYPE_SYNC:
23427 case TYPE_LOAD_L:
23428 case TYPE_STORE_C:
23429 return true;
23430 default:
23431 break;
23433 break;
23434 case PROCESSOR_POWER7:
23435 type = get_attr_type (insn);
23437 switch (type)
23439 case TYPE_ISYNC:
23440 case TYPE_SYNC:
23441 case TYPE_LOAD_L:
23442 case TYPE_STORE_C:
23443 case TYPE_LOAD_EXT_U:
23444 case TYPE_LOAD_EXT_UX:
23445 case TYPE_STORE_UX:
23446 return true;
23447 default:
23448 break;
23450 break;
23451 default:
23452 break;
23455 return false;
23458 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23459 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23461 static bool
23462 is_costly_group (rtx *group_insns, rtx next_insn)
23464 int i;
23465 int issue_rate = rs6000_issue_rate ();
23467 for (i = 0; i < issue_rate; i++)
23469 sd_iterator_def sd_it;
23470 dep_t dep;
23471 rtx insn = group_insns[i];
23473 if (!insn)
23474 continue;
23476 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23478 rtx next = DEP_CON (dep);
23480 if (next == next_insn
23481 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23482 return true;
23486 return false;
23489 /* Utility of the function redefine_groups.
23490 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23491 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23492 to keep it "far" (in a separate group) from GROUP_INSNS, following
23493 one of the following schemes, depending on the value of the flag
23494 -minsert_sched_nops = X:
23495 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23496 in order to force NEXT_INSN into a separate group.
23497 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23498 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23499 insertion (has a group just ended, how many vacant issue slots remain in the
23500 last group, and how many dispatch groups were encountered so far). */
23502 static int
23503 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23504 rtx next_insn, bool *group_end, int can_issue_more,
23505 int *group_count)
23507 rtx nop;
23508 bool force;
23509 int issue_rate = rs6000_issue_rate ();
23510 bool end = *group_end;
23511 int i;
23513 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23514 return can_issue_more;
23516 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23517 return can_issue_more;
23519 force = is_costly_group (group_insns, next_insn);
23520 if (!force)
23521 return can_issue_more;
23523 if (sched_verbose > 6)
23524 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23525 *group_count ,can_issue_more);
23527 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23529 if (*group_end)
23530 can_issue_more = 0;
23532 /* Since only a branch can be issued in the last issue_slot, it is
23533 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23534 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23535 in this case the last nop will start a new group and the branch
23536 will be forced to the new group. */
23537 if (can_issue_more && !is_branch_slot_insn (next_insn))
23538 can_issue_more--;
23540 while (can_issue_more > 0)
23542 nop = gen_nop ();
23543 emit_insn_before (nop, next_insn);
23544 can_issue_more--;
23547 *group_end = true;
23548 return 0;
23551 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
23553 int n_nops = rs6000_sched_insert_nops;
23555 /* Nops can't be issued from the branch slot, so the effective
23556 issue_rate for nops is 'issue_rate - 1'. */
23557 if (can_issue_more == 0)
23558 can_issue_more = issue_rate;
23559 can_issue_more--;
23560 if (can_issue_more == 0)
23562 can_issue_more = issue_rate - 1;
23563 (*group_count)++;
23564 end = true;
23565 for (i = 0; i < issue_rate; i++)
23567 group_insns[i] = 0;
23571 while (n_nops > 0)
23573 nop = gen_nop ();
23574 emit_insn_before (nop, next_insn);
23575 if (can_issue_more == issue_rate - 1) /* new group begins */
23576 end = false;
23577 can_issue_more--;
23578 if (can_issue_more == 0)
23580 can_issue_more = issue_rate - 1;
23581 (*group_count)++;
23582 end = true;
23583 for (i = 0; i < issue_rate; i++)
23585 group_insns[i] = 0;
23588 n_nops--;
23591 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
23592 can_issue_more++;
23594 /* Is next_insn going to start a new group? */
23595 *group_end
23596 = (end
23597 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23598 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23599 || (can_issue_more < issue_rate &&
23600 insn_terminates_group_p (next_insn, previous_group)));
23601 if (*group_end && end)
23602 (*group_count)--;
23604 if (sched_verbose > 6)
23605 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
23606 *group_count, can_issue_more);
23607 return can_issue_more;
23610 return can_issue_more;
23613 /* This function tries to synch the dispatch groups that the compiler "sees"
23614 with the dispatch groups that the processor dispatcher is expected to
23615 form in practice. It tries to achieve this synchronization by forcing the
23616 estimated processor grouping on the compiler (as opposed to the function
23617 'pad_goups' which tries to force the scheduler's grouping on the processor).
23619 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
23620 examines the (estimated) dispatch groups that will be formed by the processor
23621 dispatcher. It marks these group boundaries to reflect the estimated
23622 processor grouping, overriding the grouping that the scheduler had marked.
23623 Depending on the value of the flag '-minsert-sched-nops' this function can
23624 force certain insns into separate groups or force a certain distance between
23625 them by inserting nops, for example, if there exists a "costly dependence"
23626 between the insns.
23628 The function estimates the group boundaries that the processor will form as
23629 follows: It keeps track of how many vacant issue slots are available after
23630 each insn. A subsequent insn will start a new group if one of the following
23631 4 cases applies:
23632 - no more vacant issue slots remain in the current dispatch group.
23633 - only the last issue slot, which is the branch slot, is vacant, but the next
23634 insn is not a branch.
23635 - only the last 2 or less issue slots, including the branch slot, are vacant,
23636 which means that a cracked insn (which occupies two issue slots) can't be
23637 issued in this group.
23638 - less than 'issue_rate' slots are vacant, and the next insn always needs to
23639 start a new group. */
23641 static int
23642 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23644 rtx insn, next_insn;
23645 int issue_rate;
23646 int can_issue_more;
23647 int slot, i;
23648 bool group_end;
23649 int group_count = 0;
23650 rtx *group_insns;
23652 /* Initialize. */
23653 issue_rate = rs6000_issue_rate ();
23654 group_insns = XALLOCAVEC (rtx, issue_rate);
23655 for (i = 0; i < issue_rate; i++)
23657 group_insns[i] = 0;
23659 can_issue_more = issue_rate;
23660 slot = 0;
23661 insn = get_next_active_insn (prev_head_insn, tail);
23662 group_end = false;
23664 while (insn != NULL_RTX)
23666 slot = (issue_rate - can_issue_more);
23667 group_insns[slot] = insn;
23668 can_issue_more =
23669 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23670 if (insn_terminates_group_p (insn, current_group))
23671 can_issue_more = 0;
23673 next_insn = get_next_active_insn (insn, tail);
23674 if (next_insn == NULL_RTX)
23675 return group_count + 1;
23677 /* Is next_insn going to start a new group? */
23678 group_end
23679 = (can_issue_more == 0
23680 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23681 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23682 || (can_issue_more < issue_rate &&
23683 insn_terminates_group_p (next_insn, previous_group)));
23685 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23686 next_insn, &group_end, can_issue_more,
23687 &group_count);
23689 if (group_end)
23691 group_count++;
23692 can_issue_more = 0;
23693 for (i = 0; i < issue_rate; i++)
23695 group_insns[i] = 0;
23699 if (GET_MODE (next_insn) == TImode && can_issue_more)
23700 PUT_MODE (next_insn, VOIDmode);
23701 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23702 PUT_MODE (next_insn, TImode);
23704 insn = next_insn;
23705 if (can_issue_more == 0)
23706 can_issue_more = issue_rate;
23707 } /* while */
23709 return group_count;
23712 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23713 dispatch group boundaries that the scheduler had marked. Pad with nops
23714 any dispatch groups which have vacant issue slots, in order to force the
23715 scheduler's grouping on the processor dispatcher. The function
23716 returns the number of dispatch groups found. */
23718 static int
23719 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23721 rtx insn, next_insn;
23722 rtx nop;
23723 int issue_rate;
23724 int can_issue_more;
23725 int group_end;
23726 int group_count = 0;
23728 /* Initialize issue_rate. */
23729 issue_rate = rs6000_issue_rate ();
23730 can_issue_more = issue_rate;
23732 insn = get_next_active_insn (prev_head_insn, tail);
23733 next_insn = get_next_active_insn (insn, tail);
23735 while (insn != NULL_RTX)
23737 can_issue_more =
23738 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23740 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23742 if (next_insn == NULL_RTX)
23743 break;
23745 if (group_end)
23747 /* If the scheduler had marked group termination at this location
23748 (between insn and next_insn), and neither insn nor next_insn will
23749 force group termination, pad the group with nops to force group
23750 termination. */
23751 if (can_issue_more
23752 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23753 && !insn_terminates_group_p (insn, current_group)
23754 && !insn_terminates_group_p (next_insn, previous_group))
23756 if (!is_branch_slot_insn (next_insn))
23757 can_issue_more--;
23759 while (can_issue_more)
23761 nop = gen_nop ();
23762 emit_insn_before (nop, next_insn);
23763 can_issue_more--;
23767 can_issue_more = issue_rate;
23768 group_count++;
23771 insn = next_insn;
23772 next_insn = get_next_active_insn (insn, tail);
23775 return group_count;
23778 /* We're beginning a new block. Initialize data structures as necessary. */
23780 static void
23781 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23782 int sched_verbose ATTRIBUTE_UNUSED,
23783 int max_ready ATTRIBUTE_UNUSED)
23785 last_scheduled_insn = NULL_RTX;
23786 load_store_pendulum = 0;
23789 /* The following function is called at the end of scheduling BB.
23790 After reload, it inserts nops at insn group bundling. */
23792 static void
23793 rs6000_sched_finish (FILE *dump, int sched_verbose)
23795 int n_groups;
23797 if (sched_verbose)
23798 fprintf (dump, "=== Finishing schedule.\n");
23800 if (reload_completed && rs6000_sched_groups)
23802 /* Do not run sched_finish hook when selective scheduling enabled. */
23803 if (sel_sched_p ())
23804 return;
23806 if (rs6000_sched_insert_nops == sched_finish_none)
23807 return;
23809 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23810 n_groups = pad_groups (dump, sched_verbose,
23811 current_sched_info->prev_head,
23812 current_sched_info->next_tail);
23813 else
23814 n_groups = redefine_groups (dump, sched_verbose,
23815 current_sched_info->prev_head,
23816 current_sched_info->next_tail);
23818 if (sched_verbose >= 6)
23820 fprintf (dump, "ngroups = %d\n", n_groups);
23821 print_rtl (dump, current_sched_info->prev_head);
23822 fprintf (dump, "Done finish_sched\n");
23827 struct _rs6000_sched_context
23829 short cached_can_issue_more;
23830 rtx last_scheduled_insn;
23831 int load_store_pendulum;
23834 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23835 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23837 /* Allocate store for new scheduling context. */
23838 static void *
23839 rs6000_alloc_sched_context (void)
23841 return xmalloc (sizeof (rs6000_sched_context_def));
23844 /* If CLEAN_P is true then initializes _SC with clean data,
23845 and from the global context otherwise. */
23846 static void
23847 rs6000_init_sched_context (void *_sc, bool clean_p)
23849 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23851 if (clean_p)
23853 sc->cached_can_issue_more = 0;
23854 sc->last_scheduled_insn = NULL_RTX;
23855 sc->load_store_pendulum = 0;
23857 else
23859 sc->cached_can_issue_more = cached_can_issue_more;
23860 sc->last_scheduled_insn = last_scheduled_insn;
23861 sc->load_store_pendulum = load_store_pendulum;
23865 /* Sets the global scheduling context to the one pointed to by _SC. */
23866 static void
23867 rs6000_set_sched_context (void *_sc)
23869 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23871 gcc_assert (sc != NULL);
23873 cached_can_issue_more = sc->cached_can_issue_more;
23874 last_scheduled_insn = sc->last_scheduled_insn;
23875 load_store_pendulum = sc->load_store_pendulum;
23878 /* Free _SC. */
23879 static void
23880 rs6000_free_sched_context (void *_sc)
23882 gcc_assert (_sc != NULL);
23884 free (_sc);
23888 /* Length in units of the trampoline for entering a nested function. */
23891 rs6000_trampoline_size (void)
23893 int ret = 0;
23895 switch (DEFAULT_ABI)
23897 default:
23898 gcc_unreachable ();
23900 case ABI_AIX:
23901 ret = (TARGET_32BIT) ? 12 : 24;
23902 break;
23904 case ABI_DARWIN:
23905 case ABI_V4:
23906 ret = (TARGET_32BIT) ? 40 : 48;
23907 break;
23910 return ret;
23913 /* Emit RTL insns to initialize the variable parts of a trampoline.
23914 FNADDR is an RTX for the address of the function's pure code.
23915 CXT is an RTX for the static chain value for the function. */
23917 static void
23918 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23920 int regsize = (TARGET_32BIT) ? 4 : 8;
23921 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23922 rtx ctx_reg = force_reg (Pmode, cxt);
23923 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23925 switch (DEFAULT_ABI)
23927 default:
23928 gcc_unreachable ();
23930 /* Under AIX, just build the 3 word function descriptor */
23931 case ABI_AIX:
23933 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23934 rtx fn_reg = gen_reg_rtx (Pmode);
23935 rtx toc_reg = gen_reg_rtx (Pmode);
23937 /* Macro to shorten the code expansions below. */
23938 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23940 m_tramp = replace_equiv_address (m_tramp, addr);
23942 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23943 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23944 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23945 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23946 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23948 # undef MEM_PLUS
23950 break;
23952 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23953 case ABI_DARWIN:
23954 case ABI_V4:
23955 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23956 LCT_NORMAL, VOIDmode, 4,
23957 addr, Pmode,
23958 GEN_INT (rs6000_trampoline_size ()), SImode,
23959 fnaddr, Pmode,
23960 ctx_reg, Pmode);
23961 break;
23966 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
23967 identifier as an argument, so the front end shouldn't look it up. */
23969 static bool
23970 rs6000_attribute_takes_identifier_p (const_tree attr_id)
23972 return is_attribute_p ("altivec", attr_id);
23975 /* Handle the "altivec" attribute. The attribute may have
23976 arguments as follows:
23978 __attribute__((altivec(vector__)))
23979 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23980 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23982 and may appear more than once (e.g., 'vector bool char') in a
23983 given declaration. */
23985 static tree
23986 rs6000_handle_altivec_attribute (tree *node,
23987 tree name ATTRIBUTE_UNUSED,
23988 tree args,
23989 int flags ATTRIBUTE_UNUSED,
23990 bool *no_add_attrs)
23992 tree type = *node, result = NULL_TREE;
23993 enum machine_mode mode;
23994 int unsigned_p;
23995 char altivec_type
23996 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23997 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23998 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23999 : '?');
24001 while (POINTER_TYPE_P (type)
24002 || TREE_CODE (type) == FUNCTION_TYPE
24003 || TREE_CODE (type) == METHOD_TYPE
24004 || TREE_CODE (type) == ARRAY_TYPE)
24005 type = TREE_TYPE (type);
24007 mode = TYPE_MODE (type);
24009 /* Check for invalid AltiVec type qualifiers. */
24010 if (type == long_double_type_node)
24011 error ("use of %<long double%> in AltiVec types is invalid");
24012 else if (type == boolean_type_node)
24013 error ("use of boolean types in AltiVec types is invalid");
24014 else if (TREE_CODE (type) == COMPLEX_TYPE)
24015 error ("use of %<complex%> in AltiVec types is invalid");
24016 else if (DECIMAL_FLOAT_MODE_P (mode))
24017 error ("use of decimal floating point types in AltiVec types is invalid");
24018 else if (!TARGET_VSX)
24020 if (type == long_unsigned_type_node || type == long_integer_type_node)
24022 if (TARGET_64BIT)
24023 error ("use of %<long%> in AltiVec types is invalid for "
24024 "64-bit code without -mvsx");
24025 else if (rs6000_warn_altivec_long)
24026 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24027 "use %<int%>");
24029 else if (type == long_long_unsigned_type_node
24030 || type == long_long_integer_type_node)
24031 error ("use of %<long long%> in AltiVec types is invalid without "
24032 "-mvsx");
24033 else if (type == double_type_node)
24034 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24037 switch (altivec_type)
24039 case 'v':
24040 unsigned_p = TYPE_UNSIGNED (type);
24041 switch (mode)
24043 case DImode:
24044 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24045 break;
24046 case SImode:
24047 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24048 break;
24049 case HImode:
24050 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24051 break;
24052 case QImode:
24053 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24054 break;
24055 case SFmode: result = V4SF_type_node; break;
24056 case DFmode: result = V2DF_type_node; break;
24057 /* If the user says 'vector int bool', we may be handed the 'bool'
24058 attribute _before_ the 'vector' attribute, and so select the
24059 proper type in the 'b' case below. */
24060 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24061 case V2DImode: case V2DFmode:
24062 result = type;
24063 default: break;
24065 break;
24066 case 'b':
24067 switch (mode)
24069 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24070 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24071 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24072 case QImode: case V16QImode: result = bool_V16QI_type_node;
24073 default: break;
24075 break;
24076 case 'p':
24077 switch (mode)
24079 case V8HImode: result = pixel_V8HI_type_node;
24080 default: break;
24082 default: break;
24085 /* Propagate qualifiers attached to the element type
24086 onto the vector type. */
24087 if (result && result != type && TYPE_QUALS (type))
24088 result = build_qualified_type (result, TYPE_QUALS (type));
24090 *no_add_attrs = true; /* No need to hang on to the attribute. */
24092 if (result)
24093 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24095 return NULL_TREE;
24098 /* AltiVec defines four built-in scalar types that serve as vector
24099 elements; we must teach the compiler how to mangle them. */
24101 static const char *
24102 rs6000_mangle_type (const_tree type)
24104 type = TYPE_MAIN_VARIANT (type);
24106 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24107 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24108 return NULL;
24110 if (type == bool_char_type_node) return "U6__boolc";
24111 if (type == bool_short_type_node) return "U6__bools";
24112 if (type == pixel_type_node) return "u7__pixel";
24113 if (type == bool_int_type_node) return "U6__booli";
24114 if (type == bool_long_type_node) return "U6__booll";
24116 /* Mangle IBM extended float long double as `g' (__float128) on
24117 powerpc*-linux where long-double-64 previously was the default. */
24118 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24119 && TARGET_ELF
24120 && TARGET_LONG_DOUBLE_128
24121 && !TARGET_IEEEQUAD)
24122 return "g";
24124 /* For all other types, use normal C++ mangling. */
24125 return NULL;
24128 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24129 struct attribute_spec.handler. */
24131 static tree
24132 rs6000_handle_longcall_attribute (tree *node, tree name,
24133 tree args ATTRIBUTE_UNUSED,
24134 int flags ATTRIBUTE_UNUSED,
24135 bool *no_add_attrs)
24137 if (TREE_CODE (*node) != FUNCTION_TYPE
24138 && TREE_CODE (*node) != FIELD_DECL
24139 && TREE_CODE (*node) != TYPE_DECL)
24141 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24142 name);
24143 *no_add_attrs = true;
24146 return NULL_TREE;
24149 /* Set longcall attributes on all functions declared when
24150 rs6000_default_long_calls is true. */
24151 static void
24152 rs6000_set_default_type_attributes (tree type)
24154 if (rs6000_default_long_calls
24155 && (TREE_CODE (type) == FUNCTION_TYPE
24156 || TREE_CODE (type) == METHOD_TYPE))
24157 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24158 NULL_TREE,
24159 TYPE_ATTRIBUTES (type));
24161 #if TARGET_MACHO
24162 darwin_set_default_type_attributes (type);
24163 #endif
24166 /* Return a reference suitable for calling a function with the
24167 longcall attribute. */
24170 rs6000_longcall_ref (rtx call_ref)
24172 const char *call_name;
24173 tree node;
24175 if (GET_CODE (call_ref) != SYMBOL_REF)
24176 return call_ref;
24178 /* System V adds '.' to the internal name, so skip them. */
24179 call_name = XSTR (call_ref, 0);
24180 if (*call_name == '.')
24182 while (*call_name == '.')
24183 call_name++;
24185 node = get_identifier (call_name);
24186 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24189 return force_reg (Pmode, call_ref);
24192 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24193 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24194 #endif
24196 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24197 struct attribute_spec.handler. */
24198 static tree
24199 rs6000_handle_struct_attribute (tree *node, tree name,
24200 tree args ATTRIBUTE_UNUSED,
24201 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24203 tree *type = NULL;
24204 if (DECL_P (*node))
24206 if (TREE_CODE (*node) == TYPE_DECL)
24207 type = &TREE_TYPE (*node);
24209 else
24210 type = node;
24212 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24213 || TREE_CODE (*type) == UNION_TYPE)))
24215 warning (OPT_Wattributes, "%qE attribute ignored", name);
24216 *no_add_attrs = true;
24219 else if ((is_attribute_p ("ms_struct", name)
24220 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24221 || ((is_attribute_p ("gcc_struct", name)
24222 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24224 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24225 name);
24226 *no_add_attrs = true;
24229 return NULL_TREE;
24232 static bool
24233 rs6000_ms_bitfield_layout_p (const_tree record_type)
24235 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24236 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24237 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24240 #ifdef USING_ELFOS_H
24242 /* A get_unnamed_section callback, used for switching to toc_section. */
24244 static void
24245 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24247 if (DEFAULT_ABI == ABI_AIX
24248 && TARGET_MINIMAL_TOC
24249 && !TARGET_RELOCATABLE)
24251 if (!toc_initialized)
24253 toc_initialized = 1;
24254 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24255 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24256 fprintf (asm_out_file, "\t.tc ");
24257 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24258 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24259 fprintf (asm_out_file, "\n");
24261 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24262 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24263 fprintf (asm_out_file, " = .+32768\n");
24265 else
24266 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24268 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24269 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24270 else
24272 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24273 if (!toc_initialized)
24275 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24276 fprintf (asm_out_file, " = .+32768\n");
24277 toc_initialized = 1;
24282 /* Implement TARGET_ASM_INIT_SECTIONS. */
24284 static void
24285 rs6000_elf_asm_init_sections (void)
24287 toc_section
24288 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24290 sdata2_section
24291 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24292 SDATA2_SECTION_ASM_OP);
24295 /* Implement TARGET_SELECT_RTX_SECTION. */
24297 static section *
24298 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24299 unsigned HOST_WIDE_INT align)
24301 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24302 return toc_section;
24303 else
24304 return default_elf_select_rtx_section (mode, x, align);
24307 /* For a SYMBOL_REF, set generic flags and then perform some
24308 target-specific processing.
24310 When the AIX ABI is requested on a non-AIX system, replace the
24311 function name with the real name (with a leading .) rather than the
24312 function descriptor name. This saves a lot of overriding code to
24313 read the prefixes. */
24315 static void
24316 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24318 default_encode_section_info (decl, rtl, first);
24320 if (first
24321 && TREE_CODE (decl) == FUNCTION_DECL
24322 && !TARGET_AIX
24323 && DEFAULT_ABI == ABI_AIX)
24325 rtx sym_ref = XEXP (rtl, 0);
24326 size_t len = strlen (XSTR (sym_ref, 0));
24327 char *str = XALLOCAVEC (char, len + 2);
24328 str[0] = '.';
24329 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24330 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24334 static inline bool
24335 compare_section_name (const char *section, const char *templ)
24337 int len;
24339 len = strlen (templ);
24340 return (strncmp (section, templ, len) == 0
24341 && (section[len] == 0 || section[len] == '.'));
24344 bool
24345 rs6000_elf_in_small_data_p (const_tree decl)
24347 if (rs6000_sdata == SDATA_NONE)
24348 return false;
24350 /* We want to merge strings, so we never consider them small data. */
24351 if (TREE_CODE (decl) == STRING_CST)
24352 return false;
24354 /* Functions are never in the small data area. */
24355 if (TREE_CODE (decl) == FUNCTION_DECL)
24356 return false;
24358 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24360 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24361 if (compare_section_name (section, ".sdata")
24362 || compare_section_name (section, ".sdata2")
24363 || compare_section_name (section, ".gnu.linkonce.s")
24364 || compare_section_name (section, ".sbss")
24365 || compare_section_name (section, ".sbss2")
24366 || compare_section_name (section, ".gnu.linkonce.sb")
24367 || strcmp (section, ".PPC.EMB.sdata0") == 0
24368 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24369 return true;
24371 else
24373 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24375 if (size > 0
24376 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24377 /* If it's not public, and we're not going to reference it there,
24378 there's no need to put it in the small data section. */
24379 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24380 return true;
24383 return false;
24386 #endif /* USING_ELFOS_H */
24388 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24390 static bool
24391 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24393 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24396 /* Return a REG that occurs in ADDR with coefficient 1.
24397 ADDR can be effectively incremented by incrementing REG.
24399 r0 is special and we must not select it as an address
24400 register by this routine since our caller will try to
24401 increment the returned register via an "la" instruction. */
24404 find_addr_reg (rtx addr)
24406 while (GET_CODE (addr) == PLUS)
24408 if (GET_CODE (XEXP (addr, 0)) == REG
24409 && REGNO (XEXP (addr, 0)) != 0)
24410 addr = XEXP (addr, 0);
24411 else if (GET_CODE (XEXP (addr, 1)) == REG
24412 && REGNO (XEXP (addr, 1)) != 0)
24413 addr = XEXP (addr, 1);
24414 else if (CONSTANT_P (XEXP (addr, 0)))
24415 addr = XEXP (addr, 1);
24416 else if (CONSTANT_P (XEXP (addr, 1)))
24417 addr = XEXP (addr, 0);
24418 else
24419 gcc_unreachable ();
24421 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24422 return addr;
24425 void
24426 rs6000_fatal_bad_address (rtx op)
24428 fatal_insn ("bad address", op);
24431 #if TARGET_MACHO
24433 static tree branch_island_list = 0;
24435 /* Remember to generate a branch island for far calls to the given
24436 function. */
24438 static void
24439 add_compiler_branch_island (tree label_name, tree function_name,
24440 int line_number)
24442 tree branch_island = build_tree_list (function_name, label_name);
24443 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
24444 TREE_CHAIN (branch_island) = branch_island_list;
24445 branch_island_list = branch_island;
24448 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
24449 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
24450 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
24451 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
24453 /* Generate far-jump branch islands for everything on the
24454 branch_island_list. Invoked immediately after the last instruction
24455 of the epilogue has been emitted; the branch-islands must be
24456 appended to, and contiguous with, the function body. Mach-O stubs
24457 are generated in machopic_output_stub(). */
24459 static void
24460 macho_branch_islands (void)
24462 char tmp_buf[512];
24463 tree branch_island;
24465 for (branch_island = branch_island_list;
24466 branch_island;
24467 branch_island = TREE_CHAIN (branch_island))
24469 const char *label =
24470 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
24471 const char *name =
24472 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
24473 char name_buf[512];
24474 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24475 if (name[0] == '*' || name[0] == '&')
24476 strcpy (name_buf, name+1);
24477 else
24479 name_buf[0] = '_';
24480 strcpy (name_buf+1, name);
24482 strcpy (tmp_buf, "\n");
24483 strcat (tmp_buf, label);
24484 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24485 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24486 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24487 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24488 if (flag_pic)
24490 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24491 strcat (tmp_buf, label);
24492 strcat (tmp_buf, "_pic\n");
24493 strcat (tmp_buf, label);
24494 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24496 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24497 strcat (tmp_buf, name_buf);
24498 strcat (tmp_buf, " - ");
24499 strcat (tmp_buf, label);
24500 strcat (tmp_buf, "_pic)\n");
24502 strcat (tmp_buf, "\tmtlr r0\n");
24504 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24505 strcat (tmp_buf, name_buf);
24506 strcat (tmp_buf, " - ");
24507 strcat (tmp_buf, label);
24508 strcat (tmp_buf, "_pic)\n");
24510 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24512 else
24514 strcat (tmp_buf, ":\nlis r12,hi16(");
24515 strcat (tmp_buf, name_buf);
24516 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24517 strcat (tmp_buf, name_buf);
24518 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24520 output_asm_insn (tmp_buf, 0);
24521 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24522 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24523 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24524 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24527 branch_island_list = 0;
24530 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24531 already there or not. */
24533 static int
24534 no_previous_def (tree function_name)
24536 tree branch_island;
24537 for (branch_island = branch_island_list;
24538 branch_island;
24539 branch_island = TREE_CHAIN (branch_island))
24540 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24541 return 0;
24542 return 1;
24545 /* GET_PREV_LABEL gets the label name from the previous definition of
24546 the function. */
24548 static tree
24549 get_prev_label (tree function_name)
24551 tree branch_island;
24552 for (branch_island = branch_island_list;
24553 branch_island;
24554 branch_island = TREE_CHAIN (branch_island))
24555 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24556 return BRANCH_ISLAND_LABEL_NAME (branch_island);
24557 return 0;
24560 /* INSN is either a function call or a millicode call. It may have an
24561 unconditional jump in its delay slot.
24563 CALL_DEST is the routine we are calling. */
24565 char *
24566 output_call (rtx insn, rtx *operands, int dest_operand_number,
24567 int cookie_operand_number)
24569 static char buf[256];
24570 if (darwin_emit_branch_islands
24571 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
24572 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
24574 tree labelname;
24575 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
24577 if (no_previous_def (funname))
24579 rtx label_rtx = gen_label_rtx ();
24580 char *label_buf, temp_buf[256];
24581 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
24582 CODE_LABEL_NUMBER (label_rtx));
24583 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
24584 labelname = get_identifier (label_buf);
24585 add_compiler_branch_island (labelname, funname, insn_line (insn));
24587 else
24588 labelname = get_prev_label (funname);
24590 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
24591 instruction will reach 'foo', otherwise link as 'bl L42'".
24592 "L42" should be a 'branch island', that will do a far jump to
24593 'foo'. Branch islands are generated in
24594 macho_branch_islands(). */
24595 sprintf (buf, "jbsr %%z%d,%.246s",
24596 dest_operand_number, IDENTIFIER_POINTER (labelname));
24598 else
24599 sprintf (buf, "bl %%z%d", dest_operand_number);
24600 return buf;
24603 /* Generate PIC and indirect symbol stubs. */
24605 void
24606 machopic_output_stub (FILE *file, const char *symb, const char *stub)
24608 unsigned int length;
24609 char *symbol_name, *lazy_ptr_name;
24610 char *local_label_0;
24611 static int label = 0;
24613 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
24614 symb = (*targetm.strip_name_encoding) (symb);
24617 length = strlen (symb);
24618 symbol_name = XALLOCAVEC (char, length + 32);
24619 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
24621 lazy_ptr_name = XALLOCAVEC (char, length + 32);
24622 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
24624 if (flag_pic == 2)
24625 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
24626 else
24627 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
24629 if (flag_pic == 2)
24631 fprintf (file, "\t.align 5\n");
24633 fprintf (file, "%s:\n", stub);
24634 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24636 label++;
24637 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
24638 sprintf (local_label_0, "\"L%011d$spb\"", label);
24640 fprintf (file, "\tmflr r0\n");
24641 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
24642 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24643 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24644 lazy_ptr_name, local_label_0);
24645 fprintf (file, "\tmtlr r0\n");
24646 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24647 (TARGET_64BIT ? "ldu" : "lwzu"),
24648 lazy_ptr_name, local_label_0);
24649 fprintf (file, "\tmtctr r12\n");
24650 fprintf (file, "\tbctr\n");
24652 else
24654 fprintf (file, "\t.align 4\n");
24656 fprintf (file, "%s:\n", stub);
24657 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24659 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24660 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24661 (TARGET_64BIT ? "ldu" : "lwzu"),
24662 lazy_ptr_name);
24663 fprintf (file, "\tmtctr r12\n");
24664 fprintf (file, "\tbctr\n");
24667 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24668 fprintf (file, "%s:\n", lazy_ptr_name);
24669 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24670 fprintf (file, "%sdyld_stub_binding_helper\n",
24671 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24674 /* Legitimize PIC addresses. If the address is already
24675 position-independent, we return ORIG. Newly generated
24676 position-independent addresses go into a reg. This is REG if non
24677 zero, otherwise we allocate register(s) as necessary. */
24679 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24682 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24683 rtx reg)
24685 rtx base, offset;
24687 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24688 reg = gen_reg_rtx (Pmode);
24690 if (GET_CODE (orig) == CONST)
24692 rtx reg_temp;
24694 if (GET_CODE (XEXP (orig, 0)) == PLUS
24695 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24696 return orig;
24698 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24700 /* Use a different reg for the intermediate value, as
24701 it will be marked UNCHANGING. */
24702 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24703 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24704 Pmode, reg_temp);
24705 offset =
24706 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24707 Pmode, reg);
24709 if (GET_CODE (offset) == CONST_INT)
24711 if (SMALL_INT (offset))
24712 return plus_constant (base, INTVAL (offset));
24713 else if (! reload_in_progress && ! reload_completed)
24714 offset = force_reg (Pmode, offset);
24715 else
24717 rtx mem = force_const_mem (Pmode, orig);
24718 return machopic_legitimize_pic_address (mem, Pmode, reg);
24721 return gen_rtx_PLUS (Pmode, base, offset);
24724 /* Fall back on generic machopic code. */
24725 return machopic_legitimize_pic_address (orig, mode, reg);
24728 /* Output a .machine directive for the Darwin assembler, and call
24729 the generic start_file routine. */
24731 static void
24732 rs6000_darwin_file_start (void)
24734 static const struct
24736 const char *arg;
24737 const char *name;
24738 int if_set;
24739 } mapping[] = {
24740 { "ppc64", "ppc64", MASK_64BIT },
24741 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24742 { "power4", "ppc970", 0 },
24743 { "G5", "ppc970", 0 },
24744 { "7450", "ppc7450", 0 },
24745 { "7400", "ppc7400", MASK_ALTIVEC },
24746 { "G4", "ppc7400", 0 },
24747 { "750", "ppc750", 0 },
24748 { "740", "ppc750", 0 },
24749 { "G3", "ppc750", 0 },
24750 { "604e", "ppc604e", 0 },
24751 { "604", "ppc604", 0 },
24752 { "603e", "ppc603", 0 },
24753 { "603", "ppc603", 0 },
24754 { "601", "ppc601", 0 },
24755 { NULL, "ppc", 0 } };
24756 const char *cpu_id = "";
24757 size_t i;
24759 rs6000_file_start ();
24760 darwin_file_start ();
24762 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24763 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24764 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24765 && rs6000_select[i].string[0] != '\0')
24766 cpu_id = rs6000_select[i].string;
24768 /* Look through the mapping array. Pick the first name that either
24769 matches the argument, has a bit set in IF_SET that is also set
24770 in the target flags, or has a NULL name. */
24772 i = 0;
24773 while (mapping[i].arg != NULL
24774 && strcmp (mapping[i].arg, cpu_id) != 0
24775 && (mapping[i].if_set & target_flags) == 0)
24776 i++;
24778 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24781 #endif /* TARGET_MACHO */
24783 #if TARGET_ELF
24784 static int
24785 rs6000_elf_reloc_rw_mask (void)
24787 if (flag_pic)
24788 return 3;
24789 else if (DEFAULT_ABI == ABI_AIX)
24790 return 2;
24791 else
24792 return 0;
24795 /* Record an element in the table of global constructors. SYMBOL is
24796 a SYMBOL_REF of the function to be called; PRIORITY is a number
24797 between 0 and MAX_INIT_PRIORITY.
24799 This differs from default_named_section_asm_out_constructor in
24800 that we have special handling for -mrelocatable. */
24802 static void
24803 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24805 const char *section = ".ctors";
24806 char buf[16];
24808 if (priority != DEFAULT_INIT_PRIORITY)
24810 sprintf (buf, ".ctors.%.5u",
24811 /* Invert the numbering so the linker puts us in the proper
24812 order; constructors are run from right to left, and the
24813 linker sorts in increasing order. */
24814 MAX_INIT_PRIORITY - priority);
24815 section = buf;
24818 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24819 assemble_align (POINTER_SIZE);
24821 if (TARGET_RELOCATABLE)
24823 fputs ("\t.long (", asm_out_file);
24824 output_addr_const (asm_out_file, symbol);
24825 fputs (")@fixup\n", asm_out_file);
24827 else
24828 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24831 static void
24832 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24834 const char *section = ".dtors";
24835 char buf[16];
24837 if (priority != DEFAULT_INIT_PRIORITY)
24839 sprintf (buf, ".dtors.%.5u",
24840 /* Invert the numbering so the linker puts us in the proper
24841 order; constructors are run from right to left, and the
24842 linker sorts in increasing order. */
24843 MAX_INIT_PRIORITY - priority);
24844 section = buf;
24847 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24848 assemble_align (POINTER_SIZE);
24850 if (TARGET_RELOCATABLE)
24852 fputs ("\t.long (", asm_out_file);
24853 output_addr_const (asm_out_file, symbol);
24854 fputs (")@fixup\n", asm_out_file);
24856 else
24857 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24860 void
24861 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24863 if (TARGET_64BIT)
24865 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24866 ASM_OUTPUT_LABEL (file, name);
24867 fputs (DOUBLE_INT_ASM_OP, file);
24868 rs6000_output_function_entry (file, name);
24869 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24870 if (DOT_SYMBOLS)
24872 fputs ("\t.size\t", file);
24873 assemble_name (file, name);
24874 fputs (",24\n\t.type\t.", file);
24875 assemble_name (file, name);
24876 fputs (",@function\n", file);
24877 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24879 fputs ("\t.globl\t.", file);
24880 assemble_name (file, name);
24881 putc ('\n', file);
24884 else
24885 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24886 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24887 rs6000_output_function_entry (file, name);
24888 fputs (":\n", file);
24889 return;
24892 if (TARGET_RELOCATABLE
24893 && !TARGET_SECURE_PLT
24894 && (get_pool_size () != 0 || crtl->profile)
24895 && uses_TOC ())
24897 char buf[256];
24899 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24901 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24902 fprintf (file, "\t.long ");
24903 assemble_name (file, buf);
24904 putc ('-', file);
24905 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24906 assemble_name (file, buf);
24907 putc ('\n', file);
24910 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24911 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24913 if (DEFAULT_ABI == ABI_AIX)
24915 const char *desc_name, *orig_name;
24917 orig_name = (*targetm.strip_name_encoding) (name);
24918 desc_name = orig_name;
24919 while (*desc_name == '.')
24920 desc_name++;
24922 if (TREE_PUBLIC (decl))
24923 fprintf (file, "\t.globl %s\n", desc_name);
24925 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24926 fprintf (file, "%s:\n", desc_name);
24927 fprintf (file, "\t.long %s\n", orig_name);
24928 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24929 if (DEFAULT_ABI == ABI_AIX)
24930 fputs ("\t.long 0\n", file);
24931 fprintf (file, "\t.previous\n");
24933 ASM_OUTPUT_LABEL (file, name);
24936 static void
24937 rs6000_elf_end_indicate_exec_stack (void)
24939 if (TARGET_32BIT)
24940 file_end_indicate_exec_stack ();
24942 #endif
24944 #if TARGET_XCOFF
24945 static void
24946 rs6000_xcoff_asm_output_anchor (rtx symbol)
24948 char buffer[100];
24950 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24951 SYMBOL_REF_BLOCK_OFFSET (symbol));
24952 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24955 static void
24956 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24958 fputs (GLOBAL_ASM_OP, stream);
24959 RS6000_OUTPUT_BASENAME (stream, name);
24960 putc ('\n', stream);
24963 /* A get_unnamed_decl callback, used for read-only sections. PTR
24964 points to the section string variable. */
24966 static void
24967 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24969 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24970 *(const char *const *) directive,
24971 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24974 /* Likewise for read-write sections. */
24976 static void
24977 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24979 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24980 *(const char *const *) directive,
24981 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24984 /* A get_unnamed_section callback, used for switching to toc_section. */
24986 static void
24987 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24989 if (TARGET_MINIMAL_TOC)
24991 /* toc_section is always selected at least once from
24992 rs6000_xcoff_file_start, so this is guaranteed to
24993 always be defined once and only once in each file. */
24994 if (!toc_initialized)
24996 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24997 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24998 toc_initialized = 1;
25000 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25001 (TARGET_32BIT ? "" : ",3"));
25003 else
25004 fputs ("\t.toc\n", asm_out_file);
25007 /* Implement TARGET_ASM_INIT_SECTIONS. */
25009 static void
25010 rs6000_xcoff_asm_init_sections (void)
25012 read_only_data_section
25013 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25014 &xcoff_read_only_section_name);
25016 private_data_section
25017 = get_unnamed_section (SECTION_WRITE,
25018 rs6000_xcoff_output_readwrite_section_asm_op,
25019 &xcoff_private_data_section_name);
25021 read_only_private_data_section
25022 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25023 &xcoff_private_data_section_name);
25025 toc_section
25026 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25028 readonly_data_section = read_only_data_section;
25029 exception_section = data_section;
25032 static int
25033 rs6000_xcoff_reloc_rw_mask (void)
25035 return 3;
25038 static void
25039 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25040 tree decl ATTRIBUTE_UNUSED)
25042 int smclass;
25043 static const char * const suffix[3] = { "PR", "RO", "RW" };
25045 if (flags & SECTION_CODE)
25046 smclass = 0;
25047 else if (flags & SECTION_WRITE)
25048 smclass = 2;
25049 else
25050 smclass = 1;
25052 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25053 (flags & SECTION_CODE) ? "." : "",
25054 name, suffix[smclass], flags & SECTION_ENTSIZE);
25057 static section *
25058 rs6000_xcoff_select_section (tree decl, int reloc,
25059 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25061 if (decl_readonly_section (decl, reloc))
25063 if (TREE_PUBLIC (decl))
25064 return read_only_data_section;
25065 else
25066 return read_only_private_data_section;
25068 else
25070 if (TREE_PUBLIC (decl))
25071 return data_section;
25072 else
25073 return private_data_section;
25077 static void
25078 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25080 const char *name;
25082 /* Use select_section for private and uninitialized data. */
25083 if (!TREE_PUBLIC (decl)
25084 || DECL_COMMON (decl)
25085 || DECL_INITIAL (decl) == NULL_TREE
25086 || DECL_INITIAL (decl) == error_mark_node
25087 || (flag_zero_initialized_in_bss
25088 && initializer_zerop (DECL_INITIAL (decl))))
25089 return;
25091 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25092 name = (*targetm.strip_name_encoding) (name);
25093 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25096 /* Select section for constant in constant pool.
25098 On RS/6000, all constants are in the private read-only data area.
25099 However, if this is being placed in the TOC it must be output as a
25100 toc entry. */
25102 static section *
25103 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25104 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25106 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25107 return toc_section;
25108 else
25109 return read_only_private_data_section;
25112 /* Remove any trailing [DS] or the like from the symbol name. */
25114 static const char *
25115 rs6000_xcoff_strip_name_encoding (const char *name)
25117 size_t len;
25118 if (*name == '*')
25119 name++;
25120 len = strlen (name);
25121 if (name[len - 1] == ']')
25122 return ggc_alloc_string (name, len - 4);
25123 else
25124 return name;
25127 /* Section attributes. AIX is always PIC. */
25129 static unsigned int
25130 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25132 unsigned int align;
25133 unsigned int flags = default_section_type_flags (decl, name, reloc);
25135 /* Align to at least UNIT size. */
25136 if (flags & SECTION_CODE)
25137 align = MIN_UNITS_PER_WORD;
25138 else
25139 /* Increase alignment of large objects if not already stricter. */
25140 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25141 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25142 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25144 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25147 /* Output at beginning of assembler file.
25149 Initialize the section names for the RS/6000 at this point.
25151 Specify filename, including full path, to assembler.
25153 We want to go into the TOC section so at least one .toc will be emitted.
25154 Also, in order to output proper .bs/.es pairs, we need at least one static
25155 [RW] section emitted.
25157 Finally, declare mcount when profiling to make the assembler happy. */
25159 static void
25160 rs6000_xcoff_file_start (void)
25162 rs6000_gen_section_name (&xcoff_bss_section_name,
25163 main_input_filename, ".bss_");
25164 rs6000_gen_section_name (&xcoff_private_data_section_name,
25165 main_input_filename, ".rw_");
25166 rs6000_gen_section_name (&xcoff_read_only_section_name,
25167 main_input_filename, ".ro_");
25169 fputs ("\t.file\t", asm_out_file);
25170 output_quoted_string (asm_out_file, main_input_filename);
25171 fputc ('\n', asm_out_file);
25172 if (write_symbols != NO_DEBUG)
25173 switch_to_section (private_data_section);
25174 switch_to_section (text_section);
25175 if (profile_flag)
25176 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25177 rs6000_file_start ();
25180 /* Output at end of assembler file.
25181 On the RS/6000, referencing data should automatically pull in text. */
25183 static void
25184 rs6000_xcoff_file_end (void)
25186 switch_to_section (text_section);
25187 fputs ("_section_.text:\n", asm_out_file);
25188 switch_to_section (data_section);
25189 fputs (TARGET_32BIT
25190 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25191 asm_out_file);
25193 #endif /* TARGET_XCOFF */
25195 /* Compute a (partial) cost for rtx X. Return true if the complete
25196 cost has been computed, and false if subexpressions should be
25197 scanned. In either case, *TOTAL contains the cost result. */
25199 static bool
25200 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25201 bool speed)
25203 enum machine_mode mode = GET_MODE (x);
25205 switch (code)
25207 /* On the RS/6000, if it is valid in the insn, it is free. */
25208 case CONST_INT:
25209 if (((outer_code == SET
25210 || outer_code == PLUS
25211 || outer_code == MINUS)
25212 && (satisfies_constraint_I (x)
25213 || satisfies_constraint_L (x)))
25214 || (outer_code == AND
25215 && (satisfies_constraint_K (x)
25216 || (mode == SImode
25217 ? satisfies_constraint_L (x)
25218 : satisfies_constraint_J (x))
25219 || mask_operand (x, mode)
25220 || (mode == DImode
25221 && mask64_operand (x, DImode))))
25222 || ((outer_code == IOR || outer_code == XOR)
25223 && (satisfies_constraint_K (x)
25224 || (mode == SImode
25225 ? satisfies_constraint_L (x)
25226 : satisfies_constraint_J (x))))
25227 || outer_code == ASHIFT
25228 || outer_code == ASHIFTRT
25229 || outer_code == LSHIFTRT
25230 || outer_code == ROTATE
25231 || outer_code == ROTATERT
25232 || outer_code == ZERO_EXTRACT
25233 || (outer_code == MULT
25234 && satisfies_constraint_I (x))
25235 || ((outer_code == DIV || outer_code == UDIV
25236 || outer_code == MOD || outer_code == UMOD)
25237 && exact_log2 (INTVAL (x)) >= 0)
25238 || (outer_code == COMPARE
25239 && (satisfies_constraint_I (x)
25240 || satisfies_constraint_K (x)))
25241 || (outer_code == EQ
25242 && (satisfies_constraint_I (x)
25243 || satisfies_constraint_K (x)
25244 || (mode == SImode
25245 ? satisfies_constraint_L (x)
25246 : satisfies_constraint_J (x))))
25247 || (outer_code == GTU
25248 && satisfies_constraint_I (x))
25249 || (outer_code == LTU
25250 && satisfies_constraint_P (x)))
25252 *total = 0;
25253 return true;
25255 else if ((outer_code == PLUS
25256 && reg_or_add_cint_operand (x, VOIDmode))
25257 || (outer_code == MINUS
25258 && reg_or_sub_cint_operand (x, VOIDmode))
25259 || ((outer_code == SET
25260 || outer_code == IOR
25261 || outer_code == XOR)
25262 && (INTVAL (x)
25263 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25265 *total = COSTS_N_INSNS (1);
25266 return true;
25268 /* FALLTHRU */
25270 case CONST_DOUBLE:
25271 if (mode == DImode && code == CONST_DOUBLE)
25273 if ((outer_code == IOR || outer_code == XOR)
25274 && CONST_DOUBLE_HIGH (x) == 0
25275 && (CONST_DOUBLE_LOW (x)
25276 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25278 *total = 0;
25279 return true;
25281 else if ((outer_code == AND && and64_2_operand (x, DImode))
25282 || ((outer_code == SET
25283 || outer_code == IOR
25284 || outer_code == XOR)
25285 && CONST_DOUBLE_HIGH (x) == 0))
25287 *total = COSTS_N_INSNS (1);
25288 return true;
25291 /* FALLTHRU */
25293 case CONST:
25294 case HIGH:
25295 case SYMBOL_REF:
25296 case MEM:
25297 /* When optimizing for size, MEM should be slightly more expensive
25298 than generating address, e.g., (plus (reg) (const)).
25299 L1 cache latency is about two instructions. */
25300 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25301 return true;
25303 case LABEL_REF:
25304 *total = 0;
25305 return true;
25307 case PLUS:
25308 if (mode == DFmode)
25310 if (GET_CODE (XEXP (x, 0)) == MULT)
25312 /* FNMA accounted in outer NEG. */
25313 if (outer_code == NEG)
25314 *total = rs6000_cost->dmul - rs6000_cost->fp;
25315 else
25316 *total = rs6000_cost->dmul;
25318 else
25319 *total = rs6000_cost->fp;
25321 else if (mode == SFmode)
25323 /* FNMA accounted in outer NEG. */
25324 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25325 *total = 0;
25326 else
25327 *total = rs6000_cost->fp;
25329 else
25330 *total = COSTS_N_INSNS (1);
25331 return false;
25333 case MINUS:
25334 if (mode == DFmode)
25336 if (GET_CODE (XEXP (x, 0)) == MULT
25337 || GET_CODE (XEXP (x, 1)) == MULT)
25339 /* FNMA accounted in outer NEG. */
25340 if (outer_code == NEG)
25341 *total = rs6000_cost->dmul - rs6000_cost->fp;
25342 else
25343 *total = rs6000_cost->dmul;
25345 else
25346 *total = rs6000_cost->fp;
25348 else if (mode == SFmode)
25350 /* FNMA accounted in outer NEG. */
25351 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25352 *total = 0;
25353 else
25354 *total = rs6000_cost->fp;
25356 else
25357 *total = COSTS_N_INSNS (1);
25358 return false;
25360 case MULT:
25361 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25362 && satisfies_constraint_I (XEXP (x, 1)))
25364 if (INTVAL (XEXP (x, 1)) >= -256
25365 && INTVAL (XEXP (x, 1)) <= 255)
25366 *total = rs6000_cost->mulsi_const9;
25367 else
25368 *total = rs6000_cost->mulsi_const;
25370 /* FMA accounted in outer PLUS/MINUS. */
25371 else if ((mode == DFmode || mode == SFmode)
25372 && (outer_code == PLUS || outer_code == MINUS))
25373 *total = 0;
25374 else if (mode == DFmode)
25375 *total = rs6000_cost->dmul;
25376 else if (mode == SFmode)
25377 *total = rs6000_cost->fp;
25378 else if (mode == DImode)
25379 *total = rs6000_cost->muldi;
25380 else
25381 *total = rs6000_cost->mulsi;
25382 return false;
25384 case DIV:
25385 case MOD:
25386 if (FLOAT_MODE_P (mode))
25388 *total = mode == DFmode ? rs6000_cost->ddiv
25389 : rs6000_cost->sdiv;
25390 return false;
25392 /* FALLTHRU */
25394 case UDIV:
25395 case UMOD:
25396 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25397 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25399 if (code == DIV || code == MOD)
25400 /* Shift, addze */
25401 *total = COSTS_N_INSNS (2);
25402 else
25403 /* Shift */
25404 *total = COSTS_N_INSNS (1);
25406 else
25408 if (GET_MODE (XEXP (x, 1)) == DImode)
25409 *total = rs6000_cost->divdi;
25410 else
25411 *total = rs6000_cost->divsi;
25413 /* Add in shift and subtract for MOD. */
25414 if (code == MOD || code == UMOD)
25415 *total += COSTS_N_INSNS (2);
25416 return false;
25418 case CTZ:
25419 case FFS:
25420 *total = COSTS_N_INSNS (4);
25421 return false;
25423 case POPCOUNT:
25424 *total = COSTS_N_INSNS (6);
25425 return false;
25427 case NOT:
25428 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25430 *total = 0;
25431 return false;
25433 /* FALLTHRU */
25435 case AND:
25436 case CLZ:
25437 case IOR:
25438 case XOR:
25439 case ZERO_EXTRACT:
25440 *total = COSTS_N_INSNS (1);
25441 return false;
25443 case ASHIFT:
25444 case ASHIFTRT:
25445 case LSHIFTRT:
25446 case ROTATE:
25447 case ROTATERT:
25448 /* Handle mul_highpart. */
25449 if (outer_code == TRUNCATE
25450 && GET_CODE (XEXP (x, 0)) == MULT)
25452 if (mode == DImode)
25453 *total = rs6000_cost->muldi;
25454 else
25455 *total = rs6000_cost->mulsi;
25456 return true;
25458 else if (outer_code == AND)
25459 *total = 0;
25460 else
25461 *total = COSTS_N_INSNS (1);
25462 return false;
25464 case SIGN_EXTEND:
25465 case ZERO_EXTEND:
25466 if (GET_CODE (XEXP (x, 0)) == MEM)
25467 *total = 0;
25468 else
25469 *total = COSTS_N_INSNS (1);
25470 return false;
25472 case COMPARE:
25473 case NEG:
25474 case ABS:
25475 if (!FLOAT_MODE_P (mode))
25477 *total = COSTS_N_INSNS (1);
25478 return false;
25480 /* FALLTHRU */
25482 case FLOAT:
25483 case UNSIGNED_FLOAT:
25484 case FIX:
25485 case UNSIGNED_FIX:
25486 case FLOAT_TRUNCATE:
25487 *total = rs6000_cost->fp;
25488 return false;
25490 case FLOAT_EXTEND:
25491 if (mode == DFmode)
25492 *total = 0;
25493 else
25494 *total = rs6000_cost->fp;
25495 return false;
25497 case UNSPEC:
25498 switch (XINT (x, 1))
25500 case UNSPEC_FRSP:
25501 *total = rs6000_cost->fp;
25502 return true;
25504 default:
25505 break;
25507 break;
25509 case CALL:
25510 case IF_THEN_ELSE:
25511 if (!speed)
25513 *total = COSTS_N_INSNS (1);
25514 return true;
25516 else if (FLOAT_MODE_P (mode)
25517 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25519 *total = rs6000_cost->fp;
25520 return false;
25522 break;
25524 case EQ:
25525 case GTU:
25526 case LTU:
25527 /* Carry bit requires mode == Pmode.
25528 NEG or PLUS already counted so only add one. */
25529 if (mode == Pmode
25530 && (outer_code == NEG || outer_code == PLUS))
25532 *total = COSTS_N_INSNS (1);
25533 return true;
25535 if (outer_code == SET)
25537 if (XEXP (x, 1) == const0_rtx)
25539 if (TARGET_ISEL && !TARGET_MFCRF)
25540 *total = COSTS_N_INSNS (8);
25541 else
25542 *total = COSTS_N_INSNS (2);
25543 return true;
25545 else if (mode == Pmode)
25547 *total = COSTS_N_INSNS (3);
25548 return false;
25551 /* FALLTHRU */
25553 case GT:
25554 case LT:
25555 case UNORDERED:
25556 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
25558 if (TARGET_ISEL && !TARGET_MFCRF)
25559 *total = COSTS_N_INSNS (8);
25560 else
25561 *total = COSTS_N_INSNS (2);
25562 return true;
25564 /* CC COMPARE. */
25565 if (outer_code == COMPARE)
25567 *total = 0;
25568 return true;
25570 break;
25572 default:
25573 break;
25576 return false;
25579 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
25581 static bool
25582 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
25583 bool speed)
25585 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
25587 fprintf (stderr,
25588 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
25589 "total = %d, speed = %s, x:\n",
25590 ret ? "complete" : "scan inner",
25591 GET_RTX_NAME (code),
25592 GET_RTX_NAME (outer_code),
25593 *total,
25594 speed ? "true" : "false");
25596 debug_rtx (x);
25598 return ret;
25601 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
25603 static int
25604 rs6000_debug_address_cost (rtx x, bool speed)
25606 int ret = TARGET_ADDRESS_COST (x, speed);
25608 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
25609 ret, speed ? "true" : "false");
25610 debug_rtx (x);
25612 return ret;
25616 /* A C expression returning the cost of moving data from a register of class
25617 CLASS1 to one of CLASS2. */
25619 static int
25620 rs6000_register_move_cost (enum machine_mode mode,
25621 reg_class_t from, reg_class_t to)
25623 int ret;
25625 /* Moves from/to GENERAL_REGS. */
25626 if (reg_classes_intersect_p (to, GENERAL_REGS)
25627 || reg_classes_intersect_p (from, GENERAL_REGS))
25629 if (! reg_classes_intersect_p (to, GENERAL_REGS))
25630 from = to;
25632 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
25633 ret = (rs6000_memory_move_cost (mode, from, false)
25634 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
25636 /* It's more expensive to move CR_REGS than CR0_REGS because of the
25637 shift. */
25638 else if (from == CR_REGS)
25639 ret = 4;
25641 /* Power6 has slower LR/CTR moves so make them more expensive than
25642 memory in order to bias spills to memory .*/
25643 else if (rs6000_cpu == PROCESSOR_POWER6
25644 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25645 ret = 6 * hard_regno_nregs[0][mode];
25647 else
25648 /* A move will cost one instruction per GPR moved. */
25649 ret = 2 * hard_regno_nregs[0][mode];
25652 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25653 else if (VECTOR_UNIT_VSX_P (mode)
25654 && reg_classes_intersect_p (to, VSX_REGS)
25655 && reg_classes_intersect_p (from, VSX_REGS))
25656 ret = 2 * hard_regno_nregs[32][mode];
25658 /* Moving between two similar registers is just one instruction. */
25659 else if (reg_classes_intersect_p (to, from))
25660 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25662 /* Everything else has to go through GENERAL_REGS. */
25663 else
25664 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25665 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25667 if (TARGET_DEBUG_COST)
25668 fprintf (stderr,
25669 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25670 ret, GET_MODE_NAME (mode), reg_class_names[from],
25671 reg_class_names[to]);
25673 return ret;
25676 /* A C expressions returning the cost of moving data of MODE from a register to
25677 or from memory. */
25679 static int
25680 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
25681 bool in ATTRIBUTE_UNUSED)
25683 int ret;
25685 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25686 ret = 4 * hard_regno_nregs[0][mode];
25687 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25688 ret = 4 * hard_regno_nregs[32][mode];
25689 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25690 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25691 else
25692 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25694 if (TARGET_DEBUG_COST)
25695 fprintf (stderr,
25696 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25697 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25699 return ret;
25702 /* Returns a code for a target-specific builtin that implements
25703 reciprocal of the function, or NULL_TREE if not available. */
25705 static tree
25706 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25707 bool sqrt ATTRIBUTE_UNUSED)
25709 if (optimize_insn_for_size_p ())
25710 return NULL_TREE;
25712 if (md_fn)
25713 switch (fn)
25715 case VSX_BUILTIN_XVSQRTDP:
25716 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
25717 return NULL_TREE;
25719 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
25721 case VSX_BUILTIN_XVSQRTSP:
25722 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
25723 return NULL_TREE;
25725 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
25727 default:
25728 return NULL_TREE;
25731 else
25732 switch (fn)
25734 case BUILT_IN_SQRT:
25735 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
25736 return NULL_TREE;
25738 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
25740 case BUILT_IN_SQRTF:
25741 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
25742 return NULL_TREE;
25744 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25746 default:
25747 return NULL_TREE;
25751 /* Load up a constant. If the mode is a vector mode, splat the value across
25752 all of the vector elements. */
25754 static rtx
25755 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
25757 rtx reg;
25759 if (mode == SFmode || mode == DFmode)
25761 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
25762 reg = force_reg (mode, d);
25764 else if (mode == V4SFmode)
25766 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
25767 rtvec v = gen_rtvec (4, d, d, d, d);
25768 reg = gen_reg_rtx (mode);
25769 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25771 else if (mode == V2DFmode)
25773 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
25774 rtvec v = gen_rtvec (2, d, d);
25775 reg = gen_reg_rtx (mode);
25776 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25778 else
25779 gcc_unreachable ();
25781 return reg;
25784 /* Generate a FMADD instruction:
25785 dst = (m1 * m2) + a
25787 generating different RTL based on the fused multiply/add switch. */
25789 static void
25790 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
25792 enum machine_mode mode = GET_MODE (dst);
25794 if (!TARGET_FUSED_MADD)
25796 /* For the simple ops, use the generator function, rather than assuming
25797 that the RTL is standard. */
25798 enum insn_code mcode = optab_handler (smul_optab, mode);
25799 enum insn_code acode = optab_handler (add_optab, mode);
25800 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25801 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
25802 rtx mreg = gen_reg_rtx (mode);
25804 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
25805 emit_insn (gen_mul (mreg, m1, m2));
25806 emit_insn (gen_add (dst, mreg, a));
25809 else
25810 emit_insn (gen_rtx_SET (VOIDmode, dst,
25811 gen_rtx_PLUS (mode,
25812 gen_rtx_MULT (mode, m1, m2),
25813 a)));
25816 /* Generate a FMSUB instruction:
25817 dst = (m1 * m2) - a
25819 generating different RTL based on the fused multiply/add switch. */
25821 static void
25822 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
25824 enum machine_mode mode = GET_MODE (dst);
25826 if (!TARGET_FUSED_MADD
25827 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
25829 /* For the simple ops, use the generator function, rather than assuming
25830 that the RTL is standard. */
25831 enum insn_code mcode = optab_handler (smul_optab, mode);
25832 enum insn_code scode = optab_handler (add_optab, mode);
25833 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25834 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25835 rtx mreg = gen_reg_rtx (mode);
25837 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25838 emit_insn (gen_mul (mreg, m1, m2));
25839 emit_insn (gen_sub (dst, mreg, a));
25842 else
25843 emit_insn (gen_rtx_SET (VOIDmode, dst,
25844 gen_rtx_MINUS (mode,
25845 gen_rtx_MULT (mode, m1, m2),
25846 a)));
25849 /* Generate a FNMSUB instruction:
25850 dst = - ((m1 * m2) - a)
25852 Which is equivalent to (except in the prescence of -0.0):
25853 dst = a - (m1 * m2)
25855 generating different RTL based on the fast-math and fused multiply/add
25856 switches. */
25858 static void
25859 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
25861 enum machine_mode mode = GET_MODE (dst);
25863 if (!TARGET_FUSED_MADD)
25865 /* For the simple ops, use the generator function, rather than assuming
25866 that the RTL is standard. */
25867 enum insn_code mcode = optab_handler (smul_optab, mode);
25868 enum insn_code scode = optab_handler (sub_optab, mode);
25869 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25870 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25871 rtx mreg = gen_reg_rtx (mode);
25873 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25874 emit_insn (gen_mul (mreg, m1, m2));
25875 emit_insn (gen_sub (dst, a, mreg));
25878 else
25880 rtx m = gen_rtx_MULT (mode, m1, m2);
25882 if (!HONOR_SIGNED_ZEROS (mode))
25883 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
25885 else
25886 emit_insn (gen_rtx_SET (VOIDmode, dst,
25887 gen_rtx_NEG (mode,
25888 gen_rtx_MINUS (mode, m, a))));
25892 /* Newton-Raphson approximation of floating point divide with just 2 passes
25893 (either single precision floating point, or newer machines with higher
25894 accuracy estimates). Support both scalar and vector divide. Assumes no
25895 trapping math and finite arguments. */
25897 static void
25898 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
25900 enum machine_mode mode = GET_MODE (dst);
25901 rtx x0, e0, e1, y1, u0, v0;
25902 enum insn_code code = optab_handler (smul_optab, mode);
25903 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25904 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
25906 gcc_assert (code != CODE_FOR_nothing);
25908 /* x0 = 1./d estimate */
25909 x0 = gen_reg_rtx (mode);
25910 emit_insn (gen_rtx_SET (VOIDmode, x0,
25911 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25912 UNSPEC_FRES)));
25914 e0 = gen_reg_rtx (mode);
25915 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
25917 e1 = gen_reg_rtx (mode);
25918 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
25920 y1 = gen_reg_rtx (mode);
25921 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
25923 u0 = gen_reg_rtx (mode);
25924 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
25926 v0 = gen_reg_rtx (mode);
25927 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
25929 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
25932 /* Newton-Raphson approximation of floating point divide that has a low
25933 precision estimate. Assumes no trapping math and finite arguments. */
25935 static void
25936 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
25938 enum machine_mode mode = GET_MODE (dst);
25939 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25940 enum insn_code code = optab_handler (smul_optab, mode);
25941 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25943 gcc_assert (code != CODE_FOR_nothing);
25945 one = rs6000_load_constant_and_splat (mode, dconst1);
25947 /* x0 = 1./d estimate */
25948 x0 = gen_reg_rtx (mode);
25949 emit_insn (gen_rtx_SET (VOIDmode, x0,
25950 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25951 UNSPEC_FRES)));
25953 e0 = gen_reg_rtx (mode);
25954 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
25956 y1 = gen_reg_rtx (mode);
25957 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
25959 e1 = gen_reg_rtx (mode);
25960 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
25962 y2 = gen_reg_rtx (mode);
25963 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
25965 e2 = gen_reg_rtx (mode);
25966 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
25968 y3 = gen_reg_rtx (mode);
25969 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
25971 u0 = gen_reg_rtx (mode);
25972 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
25974 v0 = gen_reg_rtx (mode);
25975 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
25977 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
25980 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
25981 add a reg_note saying that this was a division. Support both scalar and
25982 vector divide. Assumes no trapping math and finite arguments. */
25984 void
25985 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
25987 enum machine_mode mode = GET_MODE (dst);
25989 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
25990 rs6000_emit_swdiv_high_precision (dst, n, d);
25991 else
25992 rs6000_emit_swdiv_low_precision (dst, n, d);
25994 if (note_p)
25995 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
25998 /* Newton-Raphson approximation of single/double-precision floating point
25999 rsqrt. Assumes no trapping math and finite arguments. */
26001 void
26002 rs6000_emit_swrsqrt (rtx dst, rtx src)
26004 enum machine_mode mode = GET_MODE (src);
26005 rtx x0 = gen_reg_rtx (mode);
26006 rtx y = gen_reg_rtx (mode);
26007 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26008 REAL_VALUE_TYPE dconst3_2;
26009 int i;
26010 rtx halfthree;
26011 enum insn_code code = optab_handler (smul_optab, mode);
26012 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26014 gcc_assert (code != CODE_FOR_nothing);
26016 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26017 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26018 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26020 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26022 /* x0 = rsqrt estimate */
26023 emit_insn (gen_rtx_SET (VOIDmode, x0,
26024 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26025 UNSPEC_RSQRT)));
26027 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26028 rs6000_emit_msub (y, src, halfthree, src);
26030 for (i = 0; i < passes; i++)
26032 rtx x1 = gen_reg_rtx (mode);
26033 rtx u = gen_reg_rtx (mode);
26034 rtx v = gen_reg_rtx (mode);
26036 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26037 emit_insn (gen_mul (u, x0, x0));
26038 rs6000_emit_nmsub (v, y, u, halfthree);
26039 emit_insn (gen_mul (x1, x0, v));
26040 x0 = x1;
26043 emit_move_insn (dst, x0);
26044 return;
26047 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26048 (Power7) targets. DST is the target, and SRC is the argument operand. */
26050 void
26051 rs6000_emit_popcount (rtx dst, rtx src)
26053 enum machine_mode mode = GET_MODE (dst);
26054 rtx tmp1, tmp2;
26056 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26057 if (TARGET_POPCNTD)
26059 if (mode == SImode)
26060 emit_insn (gen_popcntwsi2 (dst, src));
26061 else
26062 emit_insn (gen_popcntddi2 (dst, src));
26063 return;
26066 tmp1 = gen_reg_rtx (mode);
26068 if (mode == SImode)
26070 emit_insn (gen_popcntbsi2 (tmp1, src));
26071 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26072 NULL_RTX, 0);
26073 tmp2 = force_reg (SImode, tmp2);
26074 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26076 else
26078 emit_insn (gen_popcntbdi2 (tmp1, src));
26079 tmp2 = expand_mult (DImode, tmp1,
26080 GEN_INT ((HOST_WIDE_INT)
26081 0x01010101 << 32 | 0x01010101),
26082 NULL_RTX, 0);
26083 tmp2 = force_reg (DImode, tmp2);
26084 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26089 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26090 target, and SRC is the argument operand. */
26092 void
26093 rs6000_emit_parity (rtx dst, rtx src)
26095 enum machine_mode mode = GET_MODE (dst);
26096 rtx tmp;
26098 tmp = gen_reg_rtx (mode);
26099 if (mode == SImode)
26101 /* Is mult+shift >= shift+xor+shift+xor? */
26102 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26104 rtx tmp1, tmp2, tmp3, tmp4;
26106 tmp1 = gen_reg_rtx (SImode);
26107 emit_insn (gen_popcntbsi2 (tmp1, src));
26109 tmp2 = gen_reg_rtx (SImode);
26110 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26111 tmp3 = gen_reg_rtx (SImode);
26112 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26114 tmp4 = gen_reg_rtx (SImode);
26115 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26116 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26118 else
26119 rs6000_emit_popcount (tmp, src);
26120 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26122 else
26124 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26125 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26127 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26129 tmp1 = gen_reg_rtx (DImode);
26130 emit_insn (gen_popcntbdi2 (tmp1, src));
26132 tmp2 = gen_reg_rtx (DImode);
26133 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26134 tmp3 = gen_reg_rtx (DImode);
26135 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26137 tmp4 = gen_reg_rtx (DImode);
26138 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26139 tmp5 = gen_reg_rtx (DImode);
26140 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26142 tmp6 = gen_reg_rtx (DImode);
26143 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26144 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26146 else
26147 rs6000_emit_popcount (tmp, src);
26148 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26152 /* Return an RTX representing where to find the function value of a
26153 function returning MODE. */
26154 static rtx
26155 rs6000_complex_function_value (enum machine_mode mode)
26157 unsigned int regno;
26158 rtx r1, r2;
26159 enum machine_mode inner = GET_MODE_INNER (mode);
26160 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26162 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26163 regno = FP_ARG_RETURN;
26164 else
26166 regno = GP_ARG_RETURN;
26168 /* 32-bit is OK since it'll go in r3/r4. */
26169 if (TARGET_32BIT && inner_bytes >= 4)
26170 return gen_rtx_REG (mode, regno);
26173 if (inner_bytes >= 8)
26174 return gen_rtx_REG (mode, regno);
26176 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26177 const0_rtx);
26178 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26179 GEN_INT (inner_bytes));
26180 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26183 /* Target hook for TARGET_FUNCTION_VALUE.
26185 On the SPE, both FPs and vectors are returned in r3.
26187 On RS/6000 an integer value is in r3 and a floating-point value is in
26188 fp1, unless -msoft-float. */
26191 rs6000_function_value (const_tree valtype,
26192 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26193 bool outgoing ATTRIBUTE_UNUSED)
26195 enum machine_mode mode;
26196 unsigned int regno;
26198 /* Special handling for structs in darwin64. */
26199 if (rs6000_darwin64_abi
26200 && TYPE_MODE (valtype) == BLKmode
26201 && TREE_CODE (valtype) == RECORD_TYPE
26202 && int_size_in_bytes (valtype) > 0)
26204 CUMULATIVE_ARGS valcum;
26205 rtx valret;
26207 valcum.words = 0;
26208 valcum.fregno = FP_ARG_MIN_REG;
26209 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26210 /* Do a trial code generation as if this were going to be passed as
26211 an argument; if any part goes in memory, we return NULL. */
26212 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
26213 if (valret)
26214 return valret;
26215 /* Otherwise fall through to standard ABI rules. */
26218 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26220 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26221 return gen_rtx_PARALLEL (DImode,
26222 gen_rtvec (2,
26223 gen_rtx_EXPR_LIST (VOIDmode,
26224 gen_rtx_REG (SImode, GP_ARG_RETURN),
26225 const0_rtx),
26226 gen_rtx_EXPR_LIST (VOIDmode,
26227 gen_rtx_REG (SImode,
26228 GP_ARG_RETURN + 1),
26229 GEN_INT (4))));
26231 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26233 return gen_rtx_PARALLEL (DCmode,
26234 gen_rtvec (4,
26235 gen_rtx_EXPR_LIST (VOIDmode,
26236 gen_rtx_REG (SImode, GP_ARG_RETURN),
26237 const0_rtx),
26238 gen_rtx_EXPR_LIST (VOIDmode,
26239 gen_rtx_REG (SImode,
26240 GP_ARG_RETURN + 1),
26241 GEN_INT (4)),
26242 gen_rtx_EXPR_LIST (VOIDmode,
26243 gen_rtx_REG (SImode,
26244 GP_ARG_RETURN + 2),
26245 GEN_INT (8)),
26246 gen_rtx_EXPR_LIST (VOIDmode,
26247 gen_rtx_REG (SImode,
26248 GP_ARG_RETURN + 3),
26249 GEN_INT (12))));
26252 mode = TYPE_MODE (valtype);
26253 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26254 || POINTER_TYPE_P (valtype))
26255 mode = TARGET_32BIT ? SImode : DImode;
26257 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26258 /* _Decimal128 must use an even/odd register pair. */
26259 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26260 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26261 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26262 regno = FP_ARG_RETURN;
26263 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26264 && targetm.calls.split_complex_arg)
26265 return rs6000_complex_function_value (mode);
26266 else if (TREE_CODE (valtype) == VECTOR_TYPE
26267 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26268 && ALTIVEC_VECTOR_MODE (mode))
26269 regno = ALTIVEC_ARG_RETURN;
26270 else if (TREE_CODE (valtype) == VECTOR_TYPE
26271 && TARGET_VSX && TARGET_ALTIVEC_ABI
26272 && VSX_VECTOR_MODE (mode))
26273 regno = ALTIVEC_ARG_RETURN;
26274 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26275 && (mode == DFmode || mode == DCmode
26276 || mode == TFmode || mode == TCmode))
26277 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26278 else
26279 regno = GP_ARG_RETURN;
26281 return gen_rtx_REG (mode, regno);
26284 /* Define how to find the value returned by a library function
26285 assuming the value has mode MODE. */
26287 rs6000_libcall_value (enum machine_mode mode)
26289 unsigned int regno;
26291 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26293 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26294 return gen_rtx_PARALLEL (DImode,
26295 gen_rtvec (2,
26296 gen_rtx_EXPR_LIST (VOIDmode,
26297 gen_rtx_REG (SImode, GP_ARG_RETURN),
26298 const0_rtx),
26299 gen_rtx_EXPR_LIST (VOIDmode,
26300 gen_rtx_REG (SImode,
26301 GP_ARG_RETURN + 1),
26302 GEN_INT (4))));
26305 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26306 /* _Decimal128 must use an even/odd register pair. */
26307 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26308 else if (SCALAR_FLOAT_MODE_P (mode)
26309 && TARGET_HARD_FLOAT && TARGET_FPRS
26310 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26311 regno = FP_ARG_RETURN;
26312 else if (ALTIVEC_VECTOR_MODE (mode)
26313 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26314 regno = ALTIVEC_ARG_RETURN;
26315 else if (VSX_VECTOR_MODE (mode)
26316 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26317 regno = ALTIVEC_ARG_RETURN;
26318 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26319 return rs6000_complex_function_value (mode);
26320 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26321 && (mode == DFmode || mode == DCmode
26322 || mode == TFmode || mode == TCmode))
26323 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26324 else
26325 regno = GP_ARG_RETURN;
26327 return gen_rtx_REG (mode, regno);
26331 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26332 Frame pointer elimination is automatically handled.
26334 For the RS/6000, if frame pointer elimination is being done, we would like
26335 to convert ap into fp, not sp.
26337 We need r30 if -mminimal-toc was specified, and there are constant pool
26338 references. */
26340 bool
26341 rs6000_can_eliminate (const int from, const int to)
26343 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26344 ? ! frame_pointer_needed
26345 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26346 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26347 : true);
26350 /* Define the offset between two registers, FROM to be eliminated and its
26351 replacement TO, at the start of a routine. */
26352 HOST_WIDE_INT
26353 rs6000_initial_elimination_offset (int from, int to)
26355 rs6000_stack_t *info = rs6000_stack_info ();
26356 HOST_WIDE_INT offset;
26358 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26359 offset = info->push_p ? 0 : -info->total_size;
26360 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26362 offset = info->push_p ? 0 : -info->total_size;
26363 if (FRAME_GROWS_DOWNWARD)
26364 offset += info->fixed_size + info->vars_size + info->parm_size;
26366 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26367 offset = FRAME_GROWS_DOWNWARD
26368 ? info->fixed_size + info->vars_size + info->parm_size
26369 : 0;
26370 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26371 offset = info->total_size;
26372 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26373 offset = info->push_p ? info->total_size : 0;
26374 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26375 offset = 0;
26376 else
26377 gcc_unreachable ();
26379 return offset;
26382 static rtx
26383 rs6000_dwarf_register_span (rtx reg)
26385 rtx parts[8];
26386 int i, words;
26387 unsigned regno = REGNO (reg);
26388 enum machine_mode mode = GET_MODE (reg);
26390 if (TARGET_SPE
26391 && regno < 32
26392 && (SPE_VECTOR_MODE (GET_MODE (reg))
26393 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26394 && mode != SFmode && mode != SDmode && mode != SCmode)))
26396 else
26397 return NULL_RTX;
26399 regno = REGNO (reg);
26401 /* The duality of the SPE register size wreaks all kinds of havoc.
26402 This is a way of distinguishing r0 in 32-bits from r0 in
26403 64-bits. */
26404 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26405 gcc_assert (words <= 4);
26406 for (i = 0; i < words; i++, regno++)
26408 if (BYTES_BIG_ENDIAN)
26410 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26411 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26413 else
26415 parts[2 * i] = gen_rtx_REG (SImode, regno);
26416 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26420 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26423 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26425 static void
26426 rs6000_init_dwarf_reg_sizes_extra (tree address)
26428 if (TARGET_SPE)
26430 int i;
26431 enum machine_mode mode = TYPE_MODE (char_type_node);
26432 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26433 rtx mem = gen_rtx_MEM (BLKmode, addr);
26434 rtx value = gen_int_mode (4, mode);
26436 for (i = 1201; i < 1232; i++)
26438 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26439 HOST_WIDE_INT offset
26440 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26442 emit_move_insn (adjust_address (mem, mode, offset), value);
26447 /* Map internal gcc register numbers to DWARF2 register numbers. */
26449 unsigned int
26450 rs6000_dbx_register_number (unsigned int regno)
26452 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26453 return regno;
26454 if (regno == MQ_REGNO)
26455 return 100;
26456 if (regno == LR_REGNO)
26457 return 108;
26458 if (regno == CTR_REGNO)
26459 return 109;
26460 if (CR_REGNO_P (regno))
26461 return regno - CR0_REGNO + 86;
26462 if (regno == CA_REGNO)
26463 return 101; /* XER */
26464 if (ALTIVEC_REGNO_P (regno))
26465 return regno - FIRST_ALTIVEC_REGNO + 1124;
26466 if (regno == VRSAVE_REGNO)
26467 return 356;
26468 if (regno == VSCR_REGNO)
26469 return 67;
26470 if (regno == SPE_ACC_REGNO)
26471 return 99;
26472 if (regno == SPEFSCR_REGNO)
26473 return 612;
26474 /* SPE high reg number. We get these values of regno from
26475 rs6000_dwarf_register_span. */
26476 gcc_assert (regno >= 1200 && regno < 1232);
26477 return regno;
26480 /* target hook eh_return_filter_mode */
26481 static enum machine_mode
26482 rs6000_eh_return_filter_mode (void)
26484 return TARGET_32BIT ? SImode : word_mode;
26487 /* Target hook for scalar_mode_supported_p. */
26488 static bool
26489 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26491 if (DECIMAL_FLOAT_MODE_P (mode))
26492 return default_decimal_float_supported_p ();
26493 else
26494 return default_scalar_mode_supported_p (mode);
26497 /* Target hook for vector_mode_supported_p. */
26498 static bool
26499 rs6000_vector_mode_supported_p (enum machine_mode mode)
26502 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26503 return true;
26505 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26506 return true;
26508 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26509 return true;
26511 else
26512 return false;
26515 /* Target hook for invalid_arg_for_unprototyped_fn. */
26516 static const char *
26517 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26519 return (!rs6000_darwin64_abi
26520 && typelist == 0
26521 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26522 && (funcdecl == NULL_TREE
26523 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26524 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
26525 ? N_("AltiVec argument passed to unprototyped function")
26526 : NULL;
26529 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26530 setup by using __stack_chk_fail_local hidden function instead of
26531 calling __stack_chk_fail directly. Otherwise it is better to call
26532 __stack_chk_fail directly. */
26534 static tree
26535 rs6000_stack_protect_fail (void)
26537 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
26538 ? default_hidden_stack_protect_fail ()
26539 : default_external_stack_protect_fail ();
26542 void
26543 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
26544 int num_operands ATTRIBUTE_UNUSED)
26546 if (rs6000_warn_cell_microcode)
26548 const char *temp;
26549 int insn_code_number = recog_memoized (insn);
26550 location_t location = locator_location (INSN_LOCATOR (insn));
26552 /* Punt on insns we cannot recognize. */
26553 if (insn_code_number < 0)
26554 return;
26556 temp = get_insn_template (insn_code_number, insn);
26558 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
26559 warning_at (location, OPT_mwarn_cell_microcode,
26560 "emitting microcode insn %s\t[%s] #%d",
26561 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26562 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
26563 warning_at (location, OPT_mwarn_cell_microcode,
26564 "emitting conditional microcode insn %s\t[%s] #%d",
26565 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26569 #include "gt-rs6000.h"