* doc/invoke.texi: Add cpu_type's 464 and 464fp.
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blobe90772b03efcffa2cd672dcc20276b251f070b00
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
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 "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "recog.h"
36 #include "obstack.h"
37 #include "tree.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "except.h"
41 #include "function.h"
42 #include "output.h"
43 #include "basic-block.h"
44 #include "integrate.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 "tree-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 machine_function GTY(())
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (0) was used. */
125 int ra_need_lr;
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot;
133 } machine_function;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu;
138 struct rs6000_cpu_select rs6000_select[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 static GTY(()) bool rs6000_cell_dont_microcode;
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 to use isel instructions. */
184 int rs6000_isel;
186 /* Nonzero if floating point operations are done in the GPRs. */
187 int rs6000_float_gprs = 0;
189 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
190 int rs6000_darwin64_abi;
192 /* Set to nonzero once AIX common-mode calls have been defined. */
193 static GTY(()) int common_mode_defined;
195 /* Save information from a "cmpxx" operation until the branch or scc is
196 emitted. */
197 rtx rs6000_compare_op0, rs6000_compare_op1;
198 int rs6000_compare_fp_p;
200 /* Label number of label created for -mrelocatable, to call to so we can
201 get the address of the GOT section */
202 int rs6000_pic_labelno;
204 #ifdef USING_ELFOS_H
205 /* Which abi to adhere to */
206 const char *rs6000_abi_name;
208 /* Semantics of the small data area */
209 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
211 /* Which small data model to use */
212 const char *rs6000_sdata_name = (char *)0;
214 /* Counter for labels which are to be placed in .fixup. */
215 int fixuplabelno = 0;
216 #endif
218 /* Bit size of immediate TLS offsets and string from which it is decoded. */
219 int rs6000_tls_size = 32;
220 const char *rs6000_tls_size_string;
222 /* ABI enumeration available for subtarget to use. */
223 enum rs6000_abi rs6000_current_abi;
225 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
226 int dot_symbols;
228 /* Debug flags */
229 const char *rs6000_debug_name;
230 int rs6000_debug_stack; /* debug stack applications */
231 int rs6000_debug_arg; /* debug argument handling */
233 /* Value is TRUE if register/mode pair is acceptable. */
234 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
236 /* Built in types. */
238 tree rs6000_builtin_types[RS6000_BTI_MAX];
239 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
241 const char *rs6000_traceback_name;
242 static enum {
243 traceback_default = 0,
244 traceback_none,
245 traceback_part,
246 traceback_full
247 } rs6000_traceback;
249 /* Flag to say the TOC is initialized */
250 int toc_initialized;
251 char toc_label_name[10];
253 /* Cached value of rs6000_variable_issue. This is cached in
254 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
255 static short cached_can_issue_more;
257 static GTY(()) section *read_only_data_section;
258 static GTY(()) section *private_data_section;
259 static GTY(()) section *read_only_private_data_section;
260 static GTY(()) section *sdata2_section;
261 static GTY(()) section *toc_section;
263 /* Control alignment for fields within structures. */
264 /* String from -malign-XXXXX. */
265 int rs6000_alignment_flags;
267 /* True for any options that were explicitly set. */
268 struct {
269 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
270 bool alignment; /* True if -malign- was used. */
271 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
272 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
273 bool spe; /* True if -mspe= was used. */
274 bool float_gprs; /* True if -mfloat-gprs= was used. */
275 bool isel; /* True if -misel was used. */
276 bool long_double; /* True if -mlong-double- was used. */
277 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
278 bool vrsave; /* True if -mvrsave was used. */
279 } rs6000_explicit_options;
281 struct builtin_description
283 /* mask is not const because we're going to alter it below. This
284 nonsense will go away when we rewrite the -march infrastructure
285 to give us more target flag bits. */
286 unsigned int mask;
287 const enum insn_code icode;
288 const char *const name;
289 const enum rs6000_builtins code;
292 /* Target cpu costs. */
294 struct processor_costs {
295 const int mulsi; /* cost of SImode multiplication. */
296 const int mulsi_const; /* cost of SImode multiplication by constant. */
297 const int mulsi_const9; /* cost of SImode mult by short constant. */
298 const int muldi; /* cost of DImode multiplication. */
299 const int divsi; /* cost of SImode division. */
300 const int divdi; /* cost of DImode division. */
301 const int fp; /* cost of simple SFmode and DFmode insns. */
302 const int dmul; /* cost of DFmode multiplication (and fmadd). */
303 const int sdiv; /* cost of SFmode division (fdivs). */
304 const int ddiv; /* cost of DFmode division (fdiv). */
305 const int cache_line_size; /* cache line size in bytes. */
306 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
307 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
308 const int simultaneous_prefetches; /* number of parallel prefetch
309 operations. */
312 const struct processor_costs *rs6000_cost;
314 /* Processor costs (relative to an add) */
316 /* Instruction size costs on 32bit processors. */
317 static const
318 struct processor_costs size32_cost = {
319 COSTS_N_INSNS (1), /* mulsi */
320 COSTS_N_INSNS (1), /* mulsi_const */
321 COSTS_N_INSNS (1), /* mulsi_const9 */
322 COSTS_N_INSNS (1), /* muldi */
323 COSTS_N_INSNS (1), /* divsi */
324 COSTS_N_INSNS (1), /* divdi */
325 COSTS_N_INSNS (1), /* fp */
326 COSTS_N_INSNS (1), /* dmul */
327 COSTS_N_INSNS (1), /* sdiv */
328 COSTS_N_INSNS (1), /* ddiv */
335 /* Instruction size costs on 64bit processors. */
336 static const
337 struct processor_costs size64_cost = {
338 COSTS_N_INSNS (1), /* mulsi */
339 COSTS_N_INSNS (1), /* mulsi_const */
340 COSTS_N_INSNS (1), /* mulsi_const9 */
341 COSTS_N_INSNS (1), /* muldi */
342 COSTS_N_INSNS (1), /* divsi */
343 COSTS_N_INSNS (1), /* divdi */
344 COSTS_N_INSNS (1), /* fp */
345 COSTS_N_INSNS (1), /* dmul */
346 COSTS_N_INSNS (1), /* sdiv */
347 COSTS_N_INSNS (1), /* ddiv */
348 128,
354 /* Instruction costs on RIOS1 processors. */
355 static const
356 struct processor_costs rios1_cost = {
357 COSTS_N_INSNS (5), /* mulsi */
358 COSTS_N_INSNS (4), /* mulsi_const */
359 COSTS_N_INSNS (3), /* mulsi_const9 */
360 COSTS_N_INSNS (5), /* muldi */
361 COSTS_N_INSNS (19), /* divsi */
362 COSTS_N_INSNS (19), /* divdi */
363 COSTS_N_INSNS (2), /* fp */
364 COSTS_N_INSNS (2), /* dmul */
365 COSTS_N_INSNS (19), /* sdiv */
366 COSTS_N_INSNS (19), /* ddiv */
367 128, /* cache line size */
368 64, /* l1 cache */
369 512, /* l2 cache */
370 0, /* streams */
373 /* Instruction costs on RIOS2 processors. */
374 static const
375 struct processor_costs rios2_cost = {
376 COSTS_N_INSNS (2), /* mulsi */
377 COSTS_N_INSNS (2), /* mulsi_const */
378 COSTS_N_INSNS (2), /* mulsi_const9 */
379 COSTS_N_INSNS (2), /* muldi */
380 COSTS_N_INSNS (13), /* divsi */
381 COSTS_N_INSNS (13), /* divdi */
382 COSTS_N_INSNS (2), /* fp */
383 COSTS_N_INSNS (2), /* dmul */
384 COSTS_N_INSNS (17), /* sdiv */
385 COSTS_N_INSNS (17), /* ddiv */
386 256, /* cache line size */
387 256, /* l1 cache */
388 1024, /* l2 cache */
389 0, /* streams */
392 /* Instruction costs on RS64A processors. */
393 static const
394 struct processor_costs rs64a_cost = {
395 COSTS_N_INSNS (20), /* mulsi */
396 COSTS_N_INSNS (12), /* mulsi_const */
397 COSTS_N_INSNS (8), /* mulsi_const9 */
398 COSTS_N_INSNS (34), /* muldi */
399 COSTS_N_INSNS (65), /* divsi */
400 COSTS_N_INSNS (67), /* divdi */
401 COSTS_N_INSNS (4), /* fp */
402 COSTS_N_INSNS (4), /* dmul */
403 COSTS_N_INSNS (31), /* sdiv */
404 COSTS_N_INSNS (31), /* ddiv */
405 128, /* cache line size */
406 128, /* l1 cache */
407 2048, /* l2 cache */
408 1, /* streams */
411 /* Instruction costs on MPCCORE processors. */
412 static const
413 struct processor_costs mpccore_cost = {
414 COSTS_N_INSNS (2), /* mulsi */
415 COSTS_N_INSNS (2), /* mulsi_const */
416 COSTS_N_INSNS (2), /* mulsi_const9 */
417 COSTS_N_INSNS (2), /* muldi */
418 COSTS_N_INSNS (6), /* divsi */
419 COSTS_N_INSNS (6), /* divdi */
420 COSTS_N_INSNS (4), /* fp */
421 COSTS_N_INSNS (5), /* dmul */
422 COSTS_N_INSNS (10), /* sdiv */
423 COSTS_N_INSNS (17), /* ddiv */
424 32, /* cache line size */
425 4, /* l1 cache */
426 16, /* l2 cache */
427 1, /* streams */
430 /* Instruction costs on PPC403 processors. */
431 static const
432 struct processor_costs ppc403_cost = {
433 COSTS_N_INSNS (4), /* mulsi */
434 COSTS_N_INSNS (4), /* mulsi_const */
435 COSTS_N_INSNS (4), /* mulsi_const9 */
436 COSTS_N_INSNS (4), /* muldi */
437 COSTS_N_INSNS (33), /* divsi */
438 COSTS_N_INSNS (33), /* divdi */
439 COSTS_N_INSNS (11), /* fp */
440 COSTS_N_INSNS (11), /* dmul */
441 COSTS_N_INSNS (11), /* sdiv */
442 COSTS_N_INSNS (11), /* ddiv */
443 32, /* cache line size */
444 4, /* l1 cache */
445 16, /* l2 cache */
446 1, /* streams */
449 /* Instruction costs on PPC405 processors. */
450 static const
451 struct processor_costs ppc405_cost = {
452 COSTS_N_INSNS (5), /* mulsi */
453 COSTS_N_INSNS (4), /* mulsi_const */
454 COSTS_N_INSNS (3), /* mulsi_const9 */
455 COSTS_N_INSNS (5), /* muldi */
456 COSTS_N_INSNS (35), /* divsi */
457 COSTS_N_INSNS (35), /* divdi */
458 COSTS_N_INSNS (11), /* fp */
459 COSTS_N_INSNS (11), /* dmul */
460 COSTS_N_INSNS (11), /* sdiv */
461 COSTS_N_INSNS (11), /* ddiv */
462 32, /* cache line size */
463 16, /* l1 cache */
464 128, /* l2 cache */
465 1, /* streams */
468 /* Instruction costs on PPC440 processors. */
469 static const
470 struct processor_costs ppc440_cost = {
471 COSTS_N_INSNS (3), /* mulsi */
472 COSTS_N_INSNS (2), /* mulsi_const */
473 COSTS_N_INSNS (2), /* mulsi_const9 */
474 COSTS_N_INSNS (3), /* muldi */
475 COSTS_N_INSNS (34), /* divsi */
476 COSTS_N_INSNS (34), /* divdi */
477 COSTS_N_INSNS (5), /* fp */
478 COSTS_N_INSNS (5), /* dmul */
479 COSTS_N_INSNS (19), /* sdiv */
480 COSTS_N_INSNS (33), /* ddiv */
481 32, /* cache line size */
482 32, /* l1 cache */
483 256, /* l2 cache */
484 1, /* streams */
487 /* Instruction costs on PPC601 processors. */
488 static const
489 struct processor_costs ppc601_cost = {
490 COSTS_N_INSNS (5), /* mulsi */
491 COSTS_N_INSNS (5), /* mulsi_const */
492 COSTS_N_INSNS (5), /* mulsi_const9 */
493 COSTS_N_INSNS (5), /* muldi */
494 COSTS_N_INSNS (36), /* divsi */
495 COSTS_N_INSNS (36), /* divdi */
496 COSTS_N_INSNS (4), /* fp */
497 COSTS_N_INSNS (5), /* dmul */
498 COSTS_N_INSNS (17), /* sdiv */
499 COSTS_N_INSNS (31), /* ddiv */
500 32, /* cache line size */
501 32, /* l1 cache */
502 256, /* l2 cache */
503 1, /* streams */
506 /* Instruction costs on PPC603 processors. */
507 static const
508 struct processor_costs ppc603_cost = {
509 COSTS_N_INSNS (5), /* mulsi */
510 COSTS_N_INSNS (3), /* mulsi_const */
511 COSTS_N_INSNS (2), /* mulsi_const9 */
512 COSTS_N_INSNS (5), /* muldi */
513 COSTS_N_INSNS (37), /* divsi */
514 COSTS_N_INSNS (37), /* divdi */
515 COSTS_N_INSNS (3), /* fp */
516 COSTS_N_INSNS (4), /* dmul */
517 COSTS_N_INSNS (18), /* sdiv */
518 COSTS_N_INSNS (33), /* ddiv */
519 32, /* cache line size */
520 8, /* l1 cache */
521 64, /* l2 cache */
522 1, /* streams */
525 /* Instruction costs on PPC604 processors. */
526 static const
527 struct processor_costs ppc604_cost = {
528 COSTS_N_INSNS (4), /* mulsi */
529 COSTS_N_INSNS (4), /* mulsi_const */
530 COSTS_N_INSNS (4), /* mulsi_const9 */
531 COSTS_N_INSNS (4), /* muldi */
532 COSTS_N_INSNS (20), /* divsi */
533 COSTS_N_INSNS (20), /* divdi */
534 COSTS_N_INSNS (3), /* fp */
535 COSTS_N_INSNS (3), /* dmul */
536 COSTS_N_INSNS (18), /* sdiv */
537 COSTS_N_INSNS (32), /* ddiv */
538 32, /* cache line size */
539 16, /* l1 cache */
540 512, /* l2 cache */
541 1, /* streams */
544 /* Instruction costs on PPC604e processors. */
545 static const
546 struct processor_costs ppc604e_cost = {
547 COSTS_N_INSNS (2), /* mulsi */
548 COSTS_N_INSNS (2), /* mulsi_const */
549 COSTS_N_INSNS (2), /* mulsi_const9 */
550 COSTS_N_INSNS (2), /* muldi */
551 COSTS_N_INSNS (20), /* divsi */
552 COSTS_N_INSNS (20), /* divdi */
553 COSTS_N_INSNS (3), /* fp */
554 COSTS_N_INSNS (3), /* dmul */
555 COSTS_N_INSNS (18), /* sdiv */
556 COSTS_N_INSNS (32), /* ddiv */
557 32, /* cache line size */
558 32, /* l1 cache */
559 1024, /* l2 cache */
560 1, /* streams */
563 /* Instruction costs on PPC620 processors. */
564 static const
565 struct processor_costs ppc620_cost = {
566 COSTS_N_INSNS (5), /* mulsi */
567 COSTS_N_INSNS (4), /* mulsi_const */
568 COSTS_N_INSNS (3), /* mulsi_const9 */
569 COSTS_N_INSNS (7), /* muldi */
570 COSTS_N_INSNS (21), /* divsi */
571 COSTS_N_INSNS (37), /* divdi */
572 COSTS_N_INSNS (3), /* fp */
573 COSTS_N_INSNS (3), /* dmul */
574 COSTS_N_INSNS (18), /* sdiv */
575 COSTS_N_INSNS (32), /* ddiv */
576 128, /* cache line size */
577 32, /* l1 cache */
578 1024, /* l2 cache */
579 1, /* streams */
582 /* Instruction costs on PPC630 processors. */
583 static const
584 struct processor_costs ppc630_cost = {
585 COSTS_N_INSNS (5), /* mulsi */
586 COSTS_N_INSNS (4), /* mulsi_const */
587 COSTS_N_INSNS (3), /* mulsi_const9 */
588 COSTS_N_INSNS (7), /* muldi */
589 COSTS_N_INSNS (21), /* divsi */
590 COSTS_N_INSNS (37), /* divdi */
591 COSTS_N_INSNS (3), /* fp */
592 COSTS_N_INSNS (3), /* dmul */
593 COSTS_N_INSNS (17), /* sdiv */
594 COSTS_N_INSNS (21), /* ddiv */
595 128, /* cache line size */
596 64, /* l1 cache */
597 1024, /* l2 cache */
598 1, /* streams */
601 /* Instruction costs on Cell processor. */
602 /* COSTS_N_INSNS (1) ~ one add. */
603 static const
604 struct processor_costs ppccell_cost = {
605 COSTS_N_INSNS (9/2)+2, /* mulsi */
606 COSTS_N_INSNS (6/2), /* mulsi_const */
607 COSTS_N_INSNS (6/2), /* mulsi_const9 */
608 COSTS_N_INSNS (15/2)+2, /* muldi */
609 COSTS_N_INSNS (38/2), /* divsi */
610 COSTS_N_INSNS (70/2), /* divdi */
611 COSTS_N_INSNS (10/2), /* fp */
612 COSTS_N_INSNS (10/2), /* dmul */
613 COSTS_N_INSNS (74/2), /* sdiv */
614 COSTS_N_INSNS (74/2), /* ddiv */
615 128, /* cache line size */
616 32, /* l1 cache */
617 512, /* l2 cache */
618 6, /* streams */
621 /* Instruction costs on PPC750 and PPC7400 processors. */
622 static const
623 struct processor_costs ppc750_cost = {
624 COSTS_N_INSNS (5), /* mulsi */
625 COSTS_N_INSNS (3), /* mulsi_const */
626 COSTS_N_INSNS (2), /* mulsi_const9 */
627 COSTS_N_INSNS (5), /* muldi */
628 COSTS_N_INSNS (17), /* divsi */
629 COSTS_N_INSNS (17), /* divdi */
630 COSTS_N_INSNS (3), /* fp */
631 COSTS_N_INSNS (3), /* dmul */
632 COSTS_N_INSNS (17), /* sdiv */
633 COSTS_N_INSNS (31), /* ddiv */
634 32, /* cache line size */
635 32, /* l1 cache */
636 512, /* l2 cache */
637 1, /* streams */
640 /* Instruction costs on PPC7450 processors. */
641 static const
642 struct processor_costs ppc7450_cost = {
643 COSTS_N_INSNS (4), /* mulsi */
644 COSTS_N_INSNS (3), /* mulsi_const */
645 COSTS_N_INSNS (3), /* mulsi_const9 */
646 COSTS_N_INSNS (4), /* muldi */
647 COSTS_N_INSNS (23), /* divsi */
648 COSTS_N_INSNS (23), /* divdi */
649 COSTS_N_INSNS (5), /* fp */
650 COSTS_N_INSNS (5), /* dmul */
651 COSTS_N_INSNS (21), /* sdiv */
652 COSTS_N_INSNS (35), /* ddiv */
653 32, /* cache line size */
654 32, /* l1 cache */
655 1024, /* l2 cache */
656 1, /* streams */
659 /* Instruction costs on PPC8540 processors. */
660 static const
661 struct processor_costs ppc8540_cost = {
662 COSTS_N_INSNS (4), /* mulsi */
663 COSTS_N_INSNS (4), /* mulsi_const */
664 COSTS_N_INSNS (4), /* mulsi_const9 */
665 COSTS_N_INSNS (4), /* muldi */
666 COSTS_N_INSNS (19), /* divsi */
667 COSTS_N_INSNS (19), /* divdi */
668 COSTS_N_INSNS (4), /* fp */
669 COSTS_N_INSNS (4), /* dmul */
670 COSTS_N_INSNS (29), /* sdiv */
671 COSTS_N_INSNS (29), /* ddiv */
672 32, /* cache line size */
673 32, /* l1 cache */
674 256, /* l2 cache */
675 1, /* prefetch streams /*/
678 /* Instruction costs on E300C2 and E300C3 cores. */
679 static const
680 struct processor_costs ppce300c2c3_cost = {
681 COSTS_N_INSNS (4), /* mulsi */
682 COSTS_N_INSNS (4), /* mulsi_const */
683 COSTS_N_INSNS (4), /* mulsi_const9 */
684 COSTS_N_INSNS (4), /* muldi */
685 COSTS_N_INSNS (19), /* divsi */
686 COSTS_N_INSNS (19), /* divdi */
687 COSTS_N_INSNS (3), /* fp */
688 COSTS_N_INSNS (4), /* dmul */
689 COSTS_N_INSNS (18), /* sdiv */
690 COSTS_N_INSNS (33), /* ddiv */
692 16, /* l1 cache */
693 16, /* l2 cache */
694 1, /* prefetch streams /*/
697 /* Instruction costs on POWER4 and POWER5 processors. */
698 static const
699 struct processor_costs power4_cost = {
700 COSTS_N_INSNS (3), /* mulsi */
701 COSTS_N_INSNS (2), /* mulsi_const */
702 COSTS_N_INSNS (2), /* mulsi_const9 */
703 COSTS_N_INSNS (4), /* muldi */
704 COSTS_N_INSNS (18), /* divsi */
705 COSTS_N_INSNS (34), /* divdi */
706 COSTS_N_INSNS (3), /* fp */
707 COSTS_N_INSNS (3), /* dmul */
708 COSTS_N_INSNS (17), /* sdiv */
709 COSTS_N_INSNS (17), /* ddiv */
710 128, /* cache line size */
711 32, /* l1 cache */
712 1024, /* l2 cache */
713 8, /* prefetch streams /*/
716 /* Instruction costs on POWER6 processors. */
717 static const
718 struct processor_costs power6_cost = {
719 COSTS_N_INSNS (8), /* mulsi */
720 COSTS_N_INSNS (8), /* mulsi_const */
721 COSTS_N_INSNS (8), /* mulsi_const9 */
722 COSTS_N_INSNS (8), /* muldi */
723 COSTS_N_INSNS (22), /* divsi */
724 COSTS_N_INSNS (28), /* divdi */
725 COSTS_N_INSNS (3), /* fp */
726 COSTS_N_INSNS (3), /* dmul */
727 COSTS_N_INSNS (13), /* sdiv */
728 COSTS_N_INSNS (16), /* ddiv */
729 128, /* cache line size */
730 64, /* l1 cache */
731 2048, /* l2 cache */
732 16, /* prefetch streams */
736 static bool rs6000_function_ok_for_sibcall (tree, tree);
737 static const char *rs6000_invalid_within_doloop (const_rtx);
738 static rtx rs6000_generate_compare (enum rtx_code);
739 static void rs6000_emit_stack_tie (void);
740 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
741 static bool spe_func_has_64bit_regs_p (void);
742 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
743 int, HOST_WIDE_INT);
744 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
745 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
746 static unsigned rs6000_hash_constant (rtx);
747 static unsigned toc_hash_function (const void *);
748 static int toc_hash_eq (const void *, const void *);
749 static int constant_pool_expr_1 (rtx, int *, int *);
750 static bool constant_pool_expr_p (rtx);
751 static bool legitimate_small_data_p (enum machine_mode, rtx);
752 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
753 static struct machine_function * rs6000_init_machine_status (void);
754 static bool rs6000_assemble_integer (rtx, unsigned int, int);
755 static bool no_global_regs_above (int);
756 #ifdef HAVE_GAS_HIDDEN
757 static void rs6000_assemble_visibility (tree, int);
758 #endif
759 static int rs6000_ra_ever_killed (void);
760 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
761 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
762 static bool rs6000_ms_bitfield_layout_p (const_tree);
763 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
764 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
765 static const char *rs6000_mangle_type (const_tree);
766 extern const struct attribute_spec rs6000_attribute_table[];
767 static void rs6000_set_default_type_attributes (tree);
768 static bool rs6000_reg_live_or_pic_offset_p (int);
769 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
770 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
771 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
772 tree);
773 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
774 static bool rs6000_return_in_memory (const_tree, const_tree);
775 static void rs6000_file_start (void);
776 #if TARGET_ELF
777 static int rs6000_elf_reloc_rw_mask (void);
778 static void rs6000_elf_asm_out_constructor (rtx, int);
779 static void rs6000_elf_asm_out_destructor (rtx, int);
780 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
781 static void rs6000_elf_asm_init_sections (void);
782 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
783 unsigned HOST_WIDE_INT);
784 static void rs6000_elf_encode_section_info (tree, rtx, int)
785 ATTRIBUTE_UNUSED;
786 #endif
787 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
788 static void rs6000_alloc_sdmode_stack_slot (void);
789 static void rs6000_instantiate_decls (void);
790 #if TARGET_XCOFF
791 static void rs6000_xcoff_asm_output_anchor (rtx);
792 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
793 static void rs6000_xcoff_asm_init_sections (void);
794 static int rs6000_xcoff_reloc_rw_mask (void);
795 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
796 static section *rs6000_xcoff_select_section (tree, int,
797 unsigned HOST_WIDE_INT);
798 static void rs6000_xcoff_unique_section (tree, int);
799 static section *rs6000_xcoff_select_rtx_section
800 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
801 static const char * rs6000_xcoff_strip_name_encoding (const char *);
802 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
803 static void rs6000_xcoff_file_start (void);
804 static void rs6000_xcoff_file_end (void);
805 #endif
806 static int rs6000_variable_issue (FILE *, int, rtx, int);
807 static bool rs6000_rtx_costs (rtx, int, int, int *);
808 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
809 static void rs6000_sched_init (FILE *, int, int);
810 static bool is_microcoded_insn (rtx);
811 static bool is_nonpipeline_insn (rtx);
812 static bool is_cracked_insn (rtx);
813 static bool is_branch_slot_insn (rtx);
814 static bool is_load_insn (rtx);
815 static rtx get_store_dest (rtx pat);
816 static bool is_store_insn (rtx);
817 static bool set_to_load_agen (rtx,rtx);
818 static bool adjacent_mem_locations (rtx,rtx);
819 static int rs6000_adjust_priority (rtx, int);
820 static int rs6000_issue_rate (void);
821 static bool rs6000_is_costly_dependence (dep_t, int, int);
822 static rtx get_next_active_insn (rtx, rtx);
823 static bool insn_terminates_group_p (rtx , enum group_termination);
824 static bool insn_must_be_first_in_group (rtx);
825 static bool insn_must_be_last_in_group (rtx);
826 static bool is_costly_group (rtx *, rtx);
827 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
828 static int redefine_groups (FILE *, int, rtx, rtx);
829 static int pad_groups (FILE *, int, rtx, rtx);
830 static void rs6000_sched_finish (FILE *, int);
831 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
832 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
833 static int rs6000_use_sched_lookahead (void);
834 static int rs6000_use_sched_lookahead_guard (rtx);
835 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
836 static tree rs6000_builtin_mask_for_load (void);
837 static tree rs6000_builtin_mul_widen_even (tree);
838 static tree rs6000_builtin_mul_widen_odd (tree);
839 static tree rs6000_builtin_conversion (enum tree_code, tree);
841 static void def_builtin (int, const char *, tree, int);
842 static bool rs6000_vector_alignment_reachable (const_tree, bool);
843 static void rs6000_init_builtins (void);
844 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
845 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
846 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
847 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
848 static void altivec_init_builtins (void);
849 static void rs6000_common_init_builtins (void);
850 static void rs6000_init_libfuncs (void);
852 static void paired_init_builtins (void);
853 static rtx paired_expand_builtin (tree, rtx, bool *);
854 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
855 static rtx paired_expand_stv_builtin (enum insn_code, tree);
856 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
858 static void enable_mask_for_builtins (struct builtin_description *, int,
859 enum rs6000_builtins,
860 enum rs6000_builtins);
861 static tree build_opaque_vector_type (tree, int);
862 static void spe_init_builtins (void);
863 static rtx spe_expand_builtin (tree, rtx, bool *);
864 static rtx spe_expand_stv_builtin (enum insn_code, tree);
865 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
866 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
867 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
868 static rs6000_stack_t *rs6000_stack_info (void);
869 static void debug_stack_info (rs6000_stack_t *);
871 static rtx altivec_expand_builtin (tree, rtx, bool *);
872 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
873 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
874 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
875 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
876 static rtx altivec_expand_predicate_builtin (enum insn_code,
877 const char *, tree, rtx);
878 static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
879 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
880 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
881 static rtx altivec_expand_vec_set_builtin (tree);
882 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
883 static int get_element_number (tree, tree);
884 static bool rs6000_handle_option (size_t, const char *, int);
885 static void rs6000_parse_tls_size_option (void);
886 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
887 static int first_altivec_reg_to_save (void);
888 static unsigned int compute_vrsave_mask (void);
889 static void compute_save_world_info (rs6000_stack_t *info_ptr);
890 static void is_altivec_return_reg (rtx, void *);
891 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
892 int easy_vector_constant (rtx, enum machine_mode);
893 static bool rs6000_is_opaque_type (const_tree);
894 static rtx rs6000_dwarf_register_span (rtx);
895 static void rs6000_init_dwarf_reg_sizes_extra (tree);
896 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
897 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
898 static rtx rs6000_tls_get_addr (void);
899 static rtx rs6000_got_sym (void);
900 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
901 static const char *rs6000_get_some_local_dynamic_name (void);
902 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
903 static rtx rs6000_complex_function_value (enum machine_mode);
904 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
905 enum machine_mode, tree);
906 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
907 HOST_WIDE_INT);
908 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
909 tree, HOST_WIDE_INT);
910 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
911 HOST_WIDE_INT,
912 rtx[], int *);
913 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
914 const_tree, HOST_WIDE_INT,
915 rtx[], int *);
916 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
917 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
918 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
919 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
920 enum machine_mode, tree,
921 int *, int);
922 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
923 const_tree, bool);
924 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
925 tree, bool);
926 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
927 #if TARGET_MACHO
928 static void macho_branch_islands (void);
929 static int no_previous_def (tree function_name);
930 static tree get_prev_label (tree function_name);
931 static void rs6000_darwin_file_start (void);
932 #endif
934 static tree rs6000_build_builtin_va_list (void);
935 static void rs6000_va_start (tree, rtx);
936 static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
937 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
938 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
939 static bool rs6000_vector_mode_supported_p (enum machine_mode);
940 static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
941 enum machine_mode);
942 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
943 enum machine_mode);
944 static int get_vsel_insn (enum machine_mode);
945 static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
946 static tree rs6000_stack_protect_fail (void);
948 const int INSN_NOT_AVAILABLE = -1;
949 static enum machine_mode rs6000_eh_return_filter_mode (void);
951 /* Hash table stuff for keeping track of TOC entries. */
953 struct toc_hash_struct GTY(())
955 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
956 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
957 rtx key;
958 enum machine_mode key_mode;
959 int labelno;
962 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
964 /* Default register names. */
965 char rs6000_reg_names[][8] =
967 "0", "1", "2", "3", "4", "5", "6", "7",
968 "8", "9", "10", "11", "12", "13", "14", "15",
969 "16", "17", "18", "19", "20", "21", "22", "23",
970 "24", "25", "26", "27", "28", "29", "30", "31",
971 "0", "1", "2", "3", "4", "5", "6", "7",
972 "8", "9", "10", "11", "12", "13", "14", "15",
973 "16", "17", "18", "19", "20", "21", "22", "23",
974 "24", "25", "26", "27", "28", "29", "30", "31",
975 "mq", "lr", "ctr","ap",
976 "0", "1", "2", "3", "4", "5", "6", "7",
977 "xer",
978 /* AltiVec registers. */
979 "0", "1", "2", "3", "4", "5", "6", "7",
980 "8", "9", "10", "11", "12", "13", "14", "15",
981 "16", "17", "18", "19", "20", "21", "22", "23",
982 "24", "25", "26", "27", "28", "29", "30", "31",
983 "vrsave", "vscr",
984 /* SPE registers. */
985 "spe_acc", "spefscr",
986 /* Soft frame pointer. */
987 "sfp"
990 #ifdef TARGET_REGNAMES
991 static const char alt_reg_names[][8] =
993 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
994 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
995 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
996 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
997 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
998 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
999 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1000 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1001 "mq", "lr", "ctr", "ap",
1002 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1003 "xer",
1004 /* AltiVec registers. */
1005 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1006 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1007 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1008 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1009 "vrsave", "vscr",
1010 /* SPE registers. */
1011 "spe_acc", "spefscr",
1012 /* Soft frame pointer. */
1013 "sfp"
1015 #endif
1017 #ifndef MASK_STRICT_ALIGN
1018 #define MASK_STRICT_ALIGN 0
1019 #endif
1020 #ifndef TARGET_PROFILE_KERNEL
1021 #define TARGET_PROFILE_KERNEL 0
1022 #endif
1024 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1025 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1027 /* Initialize the GCC target structure. */
1028 #undef TARGET_ATTRIBUTE_TABLE
1029 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1030 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1031 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1033 #undef TARGET_ASM_ALIGNED_DI_OP
1034 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1036 /* Default unaligned ops are only provided for ELF. Find the ops needed
1037 for non-ELF systems. */
1038 #ifndef OBJECT_FORMAT_ELF
1039 #if TARGET_XCOFF
1040 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1041 64-bit targets. */
1042 #undef TARGET_ASM_UNALIGNED_HI_OP
1043 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1044 #undef TARGET_ASM_UNALIGNED_SI_OP
1045 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1046 #undef TARGET_ASM_UNALIGNED_DI_OP
1047 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1048 #else
1049 /* For Darwin. */
1050 #undef TARGET_ASM_UNALIGNED_HI_OP
1051 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1052 #undef TARGET_ASM_UNALIGNED_SI_OP
1053 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1054 #undef TARGET_ASM_UNALIGNED_DI_OP
1055 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1056 #undef TARGET_ASM_ALIGNED_DI_OP
1057 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1058 #endif
1059 #endif
1061 /* This hook deals with fixups for relocatable code and DI-mode objects
1062 in 64-bit code. */
1063 #undef TARGET_ASM_INTEGER
1064 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1066 #ifdef HAVE_GAS_HIDDEN
1067 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1068 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1069 #endif
1071 #undef TARGET_HAVE_TLS
1072 #define TARGET_HAVE_TLS HAVE_AS_TLS
1074 #undef TARGET_CANNOT_FORCE_CONST_MEM
1075 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1077 #undef TARGET_ASM_FUNCTION_PROLOGUE
1078 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1079 #undef TARGET_ASM_FUNCTION_EPILOGUE
1080 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1082 #undef TARGET_SCHED_VARIABLE_ISSUE
1083 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1085 #undef TARGET_SCHED_ISSUE_RATE
1086 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1087 #undef TARGET_SCHED_ADJUST_COST
1088 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1089 #undef TARGET_SCHED_ADJUST_PRIORITY
1090 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1091 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1092 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1093 #undef TARGET_SCHED_INIT
1094 #define TARGET_SCHED_INIT rs6000_sched_init
1095 #undef TARGET_SCHED_FINISH
1096 #define TARGET_SCHED_FINISH rs6000_sched_finish
1097 #undef TARGET_SCHED_REORDER
1098 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1099 #undef TARGET_SCHED_REORDER2
1100 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1102 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1103 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1105 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1106 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1108 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1109 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1110 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1111 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1112 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1113 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1114 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1115 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1117 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1118 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1120 #undef TARGET_INIT_BUILTINS
1121 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1123 #undef TARGET_EXPAND_BUILTIN
1124 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1126 #undef TARGET_MANGLE_TYPE
1127 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1129 #undef TARGET_INIT_LIBFUNCS
1130 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1132 #if TARGET_MACHO
1133 #undef TARGET_BINDS_LOCAL_P
1134 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1135 #endif
1137 #undef TARGET_MS_BITFIELD_LAYOUT_P
1138 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1140 #undef TARGET_ASM_OUTPUT_MI_THUNK
1141 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1143 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1144 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1146 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1147 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1149 #undef TARGET_INVALID_WITHIN_DOLOOP
1150 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1152 #undef TARGET_RTX_COSTS
1153 #define TARGET_RTX_COSTS rs6000_rtx_costs
1154 #undef TARGET_ADDRESS_COST
1155 #define TARGET_ADDRESS_COST hook_int_rtx_0
1157 #undef TARGET_VECTOR_OPAQUE_P
1158 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
1160 #undef TARGET_DWARF_REGISTER_SPAN
1161 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1163 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1164 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1166 /* On rs6000, function arguments are promoted, as are function return
1167 values. */
1168 #undef TARGET_PROMOTE_FUNCTION_ARGS
1169 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
1170 #undef TARGET_PROMOTE_FUNCTION_RETURN
1171 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
1173 #undef TARGET_RETURN_IN_MEMORY
1174 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1176 #undef TARGET_SETUP_INCOMING_VARARGS
1177 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1179 /* Always strict argument naming on rs6000. */
1180 #undef TARGET_STRICT_ARGUMENT_NAMING
1181 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1182 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1183 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1184 #undef TARGET_SPLIT_COMPLEX_ARG
1185 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1186 #undef TARGET_MUST_PASS_IN_STACK
1187 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1188 #undef TARGET_PASS_BY_REFERENCE
1189 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1190 #undef TARGET_ARG_PARTIAL_BYTES
1191 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1193 #undef TARGET_BUILD_BUILTIN_VA_LIST
1194 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1196 #undef TARGET_EXPAND_BUILTIN_VA_START
1197 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1199 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1200 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1202 #undef TARGET_EH_RETURN_FILTER_MODE
1203 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1205 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1206 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1208 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1209 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1211 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1212 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1214 #undef TARGET_HANDLE_OPTION
1215 #define TARGET_HANDLE_OPTION rs6000_handle_option
1217 #undef TARGET_DEFAULT_TARGET_FLAGS
1218 #define TARGET_DEFAULT_TARGET_FLAGS \
1219 (TARGET_DEFAULT)
1221 #undef TARGET_STACK_PROTECT_FAIL
1222 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1224 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1225 The PowerPC architecture requires only weak consistency among
1226 processors--that is, memory accesses between processors need not be
1227 sequentially consistent and memory accesses among processors can occur
1228 in any order. The ability to order memory accesses weakly provides
1229 opportunities for more efficient use of the system bus. Unless a
1230 dependency exists, the 604e allows read operations to precede store
1231 operations. */
1232 #undef TARGET_RELAXED_ORDERING
1233 #define TARGET_RELAXED_ORDERING true
1235 #ifdef HAVE_AS_TLS
1236 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1237 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1238 #endif
1240 /* Use a 32-bit anchor range. This leads to sequences like:
1242 addis tmp,anchor,high
1243 add dest,tmp,low
1245 where tmp itself acts as an anchor, and can be shared between
1246 accesses to the same 64k page. */
1247 #undef TARGET_MIN_ANCHOR_OFFSET
1248 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1249 #undef TARGET_MAX_ANCHOR_OFFSET
1250 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1251 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1252 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1254 #undef TARGET_BUILTIN_RECIPROCAL
1255 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1257 #undef TARGET_EXPAND_TO_RTL_HOOK
1258 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1260 #undef TARGET_INSTANTIATE_DECLS
1261 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1263 struct gcc_target targetm = TARGET_INITIALIZER;
1266 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1267 MODE. */
1268 static int
1269 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1271 /* The GPRs can hold any mode, but values bigger than one register
1272 cannot go past R31. */
1273 if (INT_REGNO_P (regno))
1274 return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
1276 /* The float registers can only hold floating modes and DImode.
1277 This excludes the 32-bit decimal float mode for now. */
1278 if (FP_REGNO_P (regno))
1279 return
1280 ((SCALAR_FLOAT_MODE_P (mode)
1281 && (mode != TDmode || (regno % 2) == 0)
1282 && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
1283 || (GET_MODE_CLASS (mode) == MODE_INT
1284 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1285 || (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1286 && PAIRED_VECTOR_MODE (mode)));
1288 /* The CR register can only hold CC modes. */
1289 if (CR_REGNO_P (regno))
1290 return GET_MODE_CLASS (mode) == MODE_CC;
1292 if (XER_REGNO_P (regno))
1293 return mode == PSImode;
1295 /* AltiVec only in AldyVec registers. */
1296 if (ALTIVEC_REGNO_P (regno))
1297 return ALTIVEC_VECTOR_MODE (mode);
1299 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1300 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1301 return 1;
1303 /* We cannot put TImode anywhere except general register and it must be
1304 able to fit within the register set. */
1306 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1309 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1310 static void
1311 rs6000_init_hard_regno_mode_ok (void)
1313 int r, m;
1315 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1316 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1317 if (rs6000_hard_regno_mode_ok (r, m))
1318 rs6000_hard_regno_mode_ok_p[m][r] = true;
1321 #if TARGET_MACHO
1322 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
1324 static void
1325 darwin_rs6000_override_options (void)
1327 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
1328 off. */
1329 rs6000_altivec_abi = 1;
1330 TARGET_ALTIVEC_VRSAVE = 1;
1331 if (DEFAULT_ABI == ABI_DARWIN)
1333 if (MACHO_DYNAMIC_NO_PIC_P)
1335 if (flag_pic)
1336 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
1337 flag_pic = 0;
1339 else if (flag_pic == 1)
1341 flag_pic = 2;
1344 if (TARGET_64BIT && ! TARGET_POWERPC64)
1346 target_flags |= MASK_POWERPC64;
1347 warning (0, "-m64 requires PowerPC64 architecture, enabling");
1349 if (flag_mkernel)
1351 rs6000_default_long_calls = 1;
1352 target_flags |= MASK_SOFT_FLOAT;
1355 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
1356 Altivec. */
1357 if (!flag_mkernel && !flag_apple_kext
1358 && TARGET_64BIT
1359 && ! (target_flags_explicit & MASK_ALTIVEC))
1360 target_flags |= MASK_ALTIVEC;
1362 /* Unless the user (not the configurer) has explicitly overridden
1363 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
1364 G4 unless targetting the kernel. */
1365 if (!flag_mkernel
1366 && !flag_apple_kext
1367 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
1368 && ! (target_flags_explicit & MASK_ALTIVEC)
1369 && ! rs6000_select[1].string)
1371 target_flags |= MASK_ALTIVEC;
1374 #endif
1376 /* If not otherwise specified by a target, make 'long double' equivalent to
1377 'double'. */
1379 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1380 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1381 #endif
1383 /* Override command line options. Mostly we process the processor
1384 type and sometimes adjust other TARGET_ options. */
1386 void
1387 rs6000_override_options (const char *default_cpu)
1389 size_t i, j;
1390 struct rs6000_cpu_select *ptr;
1391 int set_masks;
1393 /* Simplifications for entries below. */
1395 enum {
1396 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1397 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1400 /* This table occasionally claims that a processor does not support
1401 a particular feature even though it does, but the feature is slower
1402 than the alternative. Thus, it shouldn't be relied on as a
1403 complete description of the processor's support.
1405 Please keep this list in order, and don't forget to update the
1406 documentation in invoke.texi when adding a new processor or
1407 flag. */
1408 static struct ptt
1410 const char *const name; /* Canonical processor name. */
1411 const enum processor_type processor; /* Processor type enum value. */
1412 const int target_enable; /* Target flags to enable. */
1413 } const processor_target_table[]
1414 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1415 {"403", PROCESSOR_PPC403,
1416 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1417 {"405", PROCESSOR_PPC405,
1418 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1419 {"405fp", PROCESSOR_PPC405,
1420 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1421 {"440", PROCESSOR_PPC440,
1422 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1423 {"440fp", PROCESSOR_PPC440,
1424 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1425 {"464", PROCESSOR_PPC440,
1426 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1427 {"464fp", PROCESSOR_PPC440,
1428 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1429 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1430 {"601", PROCESSOR_PPC601,
1431 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1432 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1433 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1434 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1435 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1436 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1437 {"620", PROCESSOR_PPC620,
1438 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1439 {"630", PROCESSOR_PPC630,
1440 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1441 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1442 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1443 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1444 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1445 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1446 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1447 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1448 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
1449 /* 8548 has a dummy entry for now. */
1450 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
1451 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1452 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1453 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1454 {"970", PROCESSOR_POWER4,
1455 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1456 {"cell", PROCESSOR_CELL,
1457 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1458 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1459 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1460 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1461 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1462 {"G5", PROCESSOR_POWER4,
1463 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1464 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1465 {"power2", PROCESSOR_POWER,
1466 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1467 {"power3", PROCESSOR_PPC630,
1468 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1469 {"power4", PROCESSOR_POWER4,
1470 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
1471 {"power5", PROCESSOR_POWER5,
1472 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1473 | MASK_MFCRF | MASK_POPCNTB},
1474 {"power5+", PROCESSOR_POWER5,
1475 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1476 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1477 {"power6", PROCESSOR_POWER6,
1478 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
1479 | MASK_FPRND | MASK_CMPB | MASK_DFP },
1480 {"power6x", PROCESSOR_POWER6,
1481 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
1482 | MASK_FPRND | MASK_CMPB | MASK_MFPGPR | MASK_DFP },
1483 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1484 {"powerpc64", PROCESSOR_POWERPC64,
1485 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1486 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1487 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1488 {"rios2", PROCESSOR_RIOS2,
1489 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1490 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1491 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1492 {"rs64", PROCESSOR_RS64A,
1493 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1496 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
1498 /* Some OSs don't support saving the high part of 64-bit registers on
1499 context switch. Other OSs don't support saving Altivec registers.
1500 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1501 settings; if the user wants either, the user must explicitly specify
1502 them and we won't interfere with the user's specification. */
1504 enum {
1505 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1506 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1507 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1508 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1509 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP)
1512 rs6000_init_hard_regno_mode_ok ();
1514 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
1515 #ifdef OS_MISSING_POWERPC64
1516 if (OS_MISSING_POWERPC64)
1517 set_masks &= ~MASK_POWERPC64;
1518 #endif
1519 #ifdef OS_MISSING_ALTIVEC
1520 if (OS_MISSING_ALTIVEC)
1521 set_masks &= ~MASK_ALTIVEC;
1522 #endif
1524 /* Don't override by the processor default if given explicitly. */
1525 set_masks &= ~target_flags_explicit;
1527 /* Identify the processor type. */
1528 rs6000_select[0].string = default_cpu;
1529 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
1531 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
1533 ptr = &rs6000_select[i];
1534 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
1536 for (j = 0; j < ptt_size; j++)
1537 if (! strcmp (ptr->string, processor_target_table[j].name))
1539 if (ptr->set_tune_p)
1540 rs6000_cpu = processor_target_table[j].processor;
1542 if (ptr->set_arch_p)
1544 target_flags &= ~set_masks;
1545 target_flags |= (processor_target_table[j].target_enable
1546 & set_masks);
1548 break;
1551 if (j == ptt_size)
1552 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
1556 if (TARGET_E500)
1557 rs6000_isel = 1;
1559 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3)
1561 if (TARGET_ALTIVEC)
1562 error ("AltiVec not supported in this target");
1563 if (TARGET_SPE)
1564 error ("Spe not supported in this target");
1567 /* If we are optimizing big endian systems for space, use the load/store
1568 multiple and string instructions. */
1569 if (BYTES_BIG_ENDIAN && optimize_size)
1570 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
1572 /* Don't allow -mmultiple or -mstring on little endian systems
1573 unless the cpu is a 750, because the hardware doesn't support the
1574 instructions used in little endian mode, and causes an alignment
1575 trap. The 750 does not cause an alignment trap (except when the
1576 target is unaligned). */
1578 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
1580 if (TARGET_MULTIPLE)
1582 target_flags &= ~MASK_MULTIPLE;
1583 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
1584 warning (0, "-mmultiple is not supported on little endian systems");
1587 if (TARGET_STRING)
1589 target_flags &= ~MASK_STRING;
1590 if ((target_flags_explicit & MASK_STRING) != 0)
1591 warning (0, "-mstring is not supported on little endian systems");
1595 /* Set debug flags */
1596 if (rs6000_debug_name)
1598 if (! strcmp (rs6000_debug_name, "all"))
1599 rs6000_debug_stack = rs6000_debug_arg = 1;
1600 else if (! strcmp (rs6000_debug_name, "stack"))
1601 rs6000_debug_stack = 1;
1602 else if (! strcmp (rs6000_debug_name, "arg"))
1603 rs6000_debug_arg = 1;
1604 else
1605 error ("unknown -mdebug-%s switch", rs6000_debug_name);
1608 if (rs6000_traceback_name)
1610 if (! strncmp (rs6000_traceback_name, "full", 4))
1611 rs6000_traceback = traceback_full;
1612 else if (! strncmp (rs6000_traceback_name, "part", 4))
1613 rs6000_traceback = traceback_part;
1614 else if (! strncmp (rs6000_traceback_name, "no", 2))
1615 rs6000_traceback = traceback_none;
1616 else
1617 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1618 rs6000_traceback_name);
1621 if (!rs6000_explicit_options.long_double)
1622 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1624 #ifndef POWERPC_LINUX
1625 if (!rs6000_explicit_options.ieee)
1626 rs6000_ieeequad = 1;
1627 #endif
1629 /* Enable Altivec ABI for AIX -maltivec. */
1630 if (TARGET_XCOFF && TARGET_ALTIVEC)
1631 rs6000_altivec_abi = 1;
1633 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
1634 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
1635 be explicitly overridden in either case. */
1636 if (TARGET_ELF)
1638 if (!rs6000_explicit_options.altivec_abi
1639 && (TARGET_64BIT || TARGET_ALTIVEC))
1640 rs6000_altivec_abi = 1;
1642 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
1643 if (!rs6000_explicit_options.vrsave)
1644 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
1647 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1648 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1650 rs6000_darwin64_abi = 1;
1651 #if TARGET_MACHO
1652 darwin_one_byte_bool = 1;
1653 #endif
1654 /* Default to natural alignment, for better performance. */
1655 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
1658 /* Place FP constants in the constant pool instead of TOC
1659 if section anchors enabled. */
1660 if (flag_section_anchors)
1661 TARGET_NO_FP_IN_TOC = 1;
1663 /* Handle -mtls-size option. */
1664 rs6000_parse_tls_size_option ();
1666 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1667 SUBTARGET_OVERRIDE_OPTIONS;
1668 #endif
1669 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1670 SUBSUBTARGET_OVERRIDE_OPTIONS;
1671 #endif
1672 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1673 SUB3TARGET_OVERRIDE_OPTIONS;
1674 #endif
1676 if (TARGET_E500)
1678 /* The e500 does not have string instructions, and we set
1679 MASK_STRING above when optimizing for size. */
1680 if ((target_flags & MASK_STRING) != 0)
1681 target_flags = target_flags & ~MASK_STRING;
1683 else if (rs6000_select[1].string != NULL)
1685 /* For the powerpc-eabispe configuration, we set all these by
1686 default, so let's unset them if we manually set another
1687 CPU that is not the E500. */
1688 if (!rs6000_explicit_options.spe_abi)
1689 rs6000_spe_abi = 0;
1690 if (!rs6000_explicit_options.spe)
1691 rs6000_spe = 0;
1692 if (!rs6000_explicit_options.float_gprs)
1693 rs6000_float_gprs = 0;
1694 if (!rs6000_explicit_options.isel)
1695 rs6000_isel = 0;
1698 /* Detect invalid option combinations with E500. */
1699 CHECK_E500_OPTIONS;
1701 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
1702 && rs6000_cpu != PROCESSOR_POWER5
1703 && rs6000_cpu != PROCESSOR_POWER6
1704 && rs6000_cpu != PROCESSOR_CELL);
1705 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
1706 || rs6000_cpu == PROCESSOR_POWER5);
1707 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
1708 || rs6000_cpu == PROCESSOR_POWER5
1709 || rs6000_cpu == PROCESSOR_POWER6);
1711 rs6000_sched_restricted_insns_priority
1712 = (rs6000_sched_groups ? 1 : 0);
1714 /* Handle -msched-costly-dep option. */
1715 rs6000_sched_costly_dep
1716 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
1718 if (rs6000_sched_costly_dep_str)
1720 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
1721 rs6000_sched_costly_dep = no_dep_costly;
1722 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
1723 rs6000_sched_costly_dep = all_deps_costly;
1724 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
1725 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
1726 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
1727 rs6000_sched_costly_dep = store_to_load_dep_costly;
1728 else
1729 rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
1732 /* Handle -minsert-sched-nops option. */
1733 rs6000_sched_insert_nops
1734 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
1736 if (rs6000_sched_insert_nops_str)
1738 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
1739 rs6000_sched_insert_nops = sched_finish_none;
1740 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
1741 rs6000_sched_insert_nops = sched_finish_pad_groups;
1742 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
1743 rs6000_sched_insert_nops = sched_finish_regroup_exact;
1744 else
1745 rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
1748 #ifdef TARGET_REGNAMES
1749 /* If the user desires alternate register names, copy in the
1750 alternate names now. */
1751 if (TARGET_REGNAMES)
1752 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
1753 #endif
1755 /* Set aix_struct_return last, after the ABI is determined.
1756 If -maix-struct-return or -msvr4-struct-return was explicitly
1757 used, don't override with the ABI default. */
1758 if (!rs6000_explicit_options.aix_struct_ret)
1759 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
1761 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
1762 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
1764 if (TARGET_TOC)
1765 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
1767 /* We can only guarantee the availability of DI pseudo-ops when
1768 assembling for 64-bit targets. */
1769 if (!TARGET_64BIT)
1771 targetm.asm_out.aligned_op.di = NULL;
1772 targetm.asm_out.unaligned_op.di = NULL;
1775 /* Set branch target alignment, if not optimizing for size. */
1776 if (!optimize_size)
1778 /* Cell wants to be aligned 8byte for dual issue. */
1779 if (rs6000_cpu == PROCESSOR_CELL)
1781 if (align_functions <= 0)
1782 align_functions = 8;
1783 if (align_jumps <= 0)
1784 align_jumps = 8;
1785 if (align_loops <= 0)
1786 align_loops = 8;
1788 if (rs6000_align_branch_targets)
1790 if (align_functions <= 0)
1791 align_functions = 16;
1792 if (align_jumps <= 0)
1793 align_jumps = 16;
1794 if (align_loops <= 0)
1795 align_loops = 16;
1797 if (align_jumps_max_skip <= 0)
1798 align_jumps_max_skip = 15;
1799 if (align_loops_max_skip <= 0)
1800 align_loops_max_skip = 15;
1803 /* Arrange to save and restore machine status around nested functions. */
1804 init_machine_status = rs6000_init_machine_status;
1806 /* We should always be splitting complex arguments, but we can't break
1807 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1808 if (DEFAULT_ABI != ABI_AIX)
1809 targetm.calls.split_complex_arg = NULL;
1811 /* Initialize rs6000_cost with the appropriate target costs. */
1812 if (optimize_size)
1813 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
1814 else
1815 switch (rs6000_cpu)
1817 case PROCESSOR_RIOS1:
1818 rs6000_cost = &rios1_cost;
1819 break;
1821 case PROCESSOR_RIOS2:
1822 rs6000_cost = &rios2_cost;
1823 break;
1825 case PROCESSOR_RS64A:
1826 rs6000_cost = &rs64a_cost;
1827 break;
1829 case PROCESSOR_MPCCORE:
1830 rs6000_cost = &mpccore_cost;
1831 break;
1833 case PROCESSOR_PPC403:
1834 rs6000_cost = &ppc403_cost;
1835 break;
1837 case PROCESSOR_PPC405:
1838 rs6000_cost = &ppc405_cost;
1839 break;
1841 case PROCESSOR_PPC440:
1842 rs6000_cost = &ppc440_cost;
1843 break;
1845 case PROCESSOR_PPC601:
1846 rs6000_cost = &ppc601_cost;
1847 break;
1849 case PROCESSOR_PPC603:
1850 rs6000_cost = &ppc603_cost;
1851 break;
1853 case PROCESSOR_PPC604:
1854 rs6000_cost = &ppc604_cost;
1855 break;
1857 case PROCESSOR_PPC604e:
1858 rs6000_cost = &ppc604e_cost;
1859 break;
1861 case PROCESSOR_PPC620:
1862 rs6000_cost = &ppc620_cost;
1863 break;
1865 case PROCESSOR_PPC630:
1866 rs6000_cost = &ppc630_cost;
1867 break;
1869 case PROCESSOR_CELL:
1870 rs6000_cost = &ppccell_cost;
1871 break;
1873 case PROCESSOR_PPC750:
1874 case PROCESSOR_PPC7400:
1875 rs6000_cost = &ppc750_cost;
1876 break;
1878 case PROCESSOR_PPC7450:
1879 rs6000_cost = &ppc7450_cost;
1880 break;
1882 case PROCESSOR_PPC8540:
1883 rs6000_cost = &ppc8540_cost;
1884 break;
1886 case PROCESSOR_PPCE300C2:
1887 case PROCESSOR_PPCE300C3:
1888 rs6000_cost = &ppce300c2c3_cost;
1889 break;
1891 case PROCESSOR_POWER4:
1892 case PROCESSOR_POWER5:
1893 rs6000_cost = &power4_cost;
1894 break;
1896 case PROCESSOR_POWER6:
1897 rs6000_cost = &power6_cost;
1898 break;
1900 default:
1901 gcc_unreachable ();
1904 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
1905 set_param_value ("simultaneous-prefetches",
1906 rs6000_cost->simultaneous_prefetches);
1907 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
1908 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
1909 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
1910 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
1911 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
1912 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
1914 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
1915 can be optimized to ap = __builtin_next_arg (0). */
1916 if (DEFAULT_ABI != ABI_V4)
1917 targetm.expand_builtin_va_start = NULL;
1920 /* Implement targetm.vectorize.builtin_mask_for_load. */
1921 static tree
1922 rs6000_builtin_mask_for_load (void)
1924 if (TARGET_ALTIVEC)
1925 return altivec_builtin_mask_for_load;
1926 else
1927 return 0;
1930 /* Implement targetm.vectorize.builtin_conversion. */
1931 static tree
1932 rs6000_builtin_conversion (enum tree_code code, tree type)
1934 if (!TARGET_ALTIVEC)
1935 return NULL_TREE;
1937 switch (code)
1939 case FLOAT_EXPR:
1940 switch (TYPE_MODE (type))
1942 case V4SImode:
1943 return TYPE_UNSIGNED (type) ?
1944 rs6000_builtin_decls[ALTIVEC_BUILTIN_VCFUX] :
1945 rs6000_builtin_decls[ALTIVEC_BUILTIN_VCFSX];
1946 default:
1947 return NULL_TREE;
1949 default:
1950 return NULL_TREE;
1954 /* Implement targetm.vectorize.builtin_mul_widen_even. */
1955 static tree
1956 rs6000_builtin_mul_widen_even (tree type)
1958 if (!TARGET_ALTIVEC)
1959 return NULL_TREE;
1961 switch (TYPE_MODE (type))
1963 case V8HImode:
1964 return TYPE_UNSIGNED (type) ?
1965 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH] :
1966 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
1968 case V16QImode:
1969 return TYPE_UNSIGNED (type) ?
1970 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB] :
1971 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
1972 default:
1973 return NULL_TREE;
1977 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
1978 static tree
1979 rs6000_builtin_mul_widen_odd (tree type)
1981 if (!TARGET_ALTIVEC)
1982 return NULL_TREE;
1984 switch (TYPE_MODE (type))
1986 case V8HImode:
1987 return TYPE_UNSIGNED (type) ?
1988 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH] :
1989 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
1991 case V16QImode:
1992 return TYPE_UNSIGNED (type) ?
1993 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB] :
1994 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
1995 default:
1996 return NULL_TREE;
2001 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2002 after applying N number of iterations. This routine does not determine
2003 how may iterations are required to reach desired alignment. */
2005 static bool
2006 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
2008 if (is_packed)
2009 return false;
2011 if (TARGET_32BIT)
2013 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
2014 return true;
2016 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
2017 return true;
2019 return false;
2021 else
2023 if (TARGET_MACHO)
2024 return false;
2026 /* Assuming that all other types are naturally aligned. CHECKME! */
2027 return true;
2031 /* Handle generic options of the form -mfoo=yes/no.
2032 NAME is the option name.
2033 VALUE is the option value.
2034 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2035 whether the option value is 'yes' or 'no' respectively. */
2036 static void
2037 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
2039 if (value == 0)
2040 return;
2041 else if (!strcmp (value, "yes"))
2042 *flag = 1;
2043 else if (!strcmp (value, "no"))
2044 *flag = 0;
2045 else
2046 error ("unknown -m%s= option specified: '%s'", name, value);
2049 /* Validate and record the size specified with the -mtls-size option. */
2051 static void
2052 rs6000_parse_tls_size_option (void)
2054 if (rs6000_tls_size_string == 0)
2055 return;
2056 else if (strcmp (rs6000_tls_size_string, "16") == 0)
2057 rs6000_tls_size = 16;
2058 else if (strcmp (rs6000_tls_size_string, "32") == 0)
2059 rs6000_tls_size = 32;
2060 else if (strcmp (rs6000_tls_size_string, "64") == 0)
2061 rs6000_tls_size = 64;
2062 else
2063 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
2066 void
2067 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
2069 if (DEFAULT_ABI == ABI_DARWIN)
2070 /* The Darwin libraries never set errno, so we might as well
2071 avoid calling them when that's the only reason we would. */
2072 flag_errno_math = 0;
2074 /* Double growth factor to counter reduced min jump length. */
2075 set_param_value ("max-grow-copy-bb-insns", 16);
2077 /* Enable section anchors by default.
2078 Skip section anchors for Objective C and Objective C++
2079 until front-ends fixed. */
2080 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
2081 flag_section_anchors = 1;
2084 /* Implement TARGET_HANDLE_OPTION. */
2086 static bool
2087 rs6000_handle_option (size_t code, const char *arg, int value)
2089 switch (code)
2091 case OPT_mno_power:
2092 target_flags &= ~(MASK_POWER | MASK_POWER2
2093 | MASK_MULTIPLE | MASK_STRING);
2094 target_flags_explicit |= (MASK_POWER | MASK_POWER2
2095 | MASK_MULTIPLE | MASK_STRING);
2096 break;
2097 case OPT_mno_powerpc:
2098 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
2099 | MASK_PPC_GFXOPT | MASK_POWERPC64);
2100 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
2101 | MASK_PPC_GFXOPT | MASK_POWERPC64);
2102 break;
2103 case OPT_mfull_toc:
2104 target_flags &= ~MASK_MINIMAL_TOC;
2105 TARGET_NO_FP_IN_TOC = 0;
2106 TARGET_NO_SUM_IN_TOC = 0;
2107 target_flags_explicit |= MASK_MINIMAL_TOC;
2108 #ifdef TARGET_USES_SYSV4_OPT
2109 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
2110 just the same as -mminimal-toc. */
2111 target_flags |= MASK_MINIMAL_TOC;
2112 target_flags_explicit |= MASK_MINIMAL_TOC;
2113 #endif
2114 break;
2116 #ifdef TARGET_USES_SYSV4_OPT
2117 case OPT_mtoc:
2118 /* Make -mtoc behave like -mminimal-toc. */
2119 target_flags |= MASK_MINIMAL_TOC;
2120 target_flags_explicit |= MASK_MINIMAL_TOC;
2121 break;
2122 #endif
2124 #ifdef TARGET_USES_AIX64_OPT
2125 case OPT_maix64:
2126 #else
2127 case OPT_m64:
2128 #endif
2129 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
2130 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
2131 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
2132 break;
2134 #ifdef TARGET_USES_AIX64_OPT
2135 case OPT_maix32:
2136 #else
2137 case OPT_m32:
2138 #endif
2139 target_flags &= ~MASK_POWERPC64;
2140 target_flags_explicit |= MASK_POWERPC64;
2141 break;
2143 case OPT_minsert_sched_nops_:
2144 rs6000_sched_insert_nops_str = arg;
2145 break;
2147 case OPT_mminimal_toc:
2148 if (value == 1)
2150 TARGET_NO_FP_IN_TOC = 0;
2151 TARGET_NO_SUM_IN_TOC = 0;
2153 break;
2155 case OPT_mpower:
2156 if (value == 1)
2158 target_flags |= (MASK_MULTIPLE | MASK_STRING);
2159 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
2161 break;
2163 case OPT_mpower2:
2164 if (value == 1)
2166 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
2167 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
2169 break;
2171 case OPT_mpowerpc_gpopt:
2172 case OPT_mpowerpc_gfxopt:
2173 if (value == 1)
2175 target_flags |= MASK_POWERPC;
2176 target_flags_explicit |= MASK_POWERPC;
2178 break;
2180 case OPT_maix_struct_return:
2181 case OPT_msvr4_struct_return:
2182 rs6000_explicit_options.aix_struct_ret = true;
2183 break;
2185 case OPT_mvrsave_:
2186 rs6000_explicit_options.vrsave = true;
2187 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
2188 break;
2190 case OPT_misel:
2191 rs6000_explicit_options.isel = true;
2192 rs6000_isel = value;
2193 break;
2195 case OPT_misel_:
2196 rs6000_explicit_options.isel = true;
2197 rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
2198 break;
2200 case OPT_mspe:
2201 rs6000_explicit_options.spe = true;
2202 rs6000_spe = value;
2203 break;
2205 case OPT_mspe_:
2206 rs6000_explicit_options.spe = true;
2207 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
2208 break;
2210 case OPT_mdebug_:
2211 rs6000_debug_name = arg;
2212 break;
2214 #ifdef TARGET_USES_SYSV4_OPT
2215 case OPT_mcall_:
2216 rs6000_abi_name = arg;
2217 break;
2219 case OPT_msdata_:
2220 rs6000_sdata_name = arg;
2221 break;
2223 case OPT_mtls_size_:
2224 rs6000_tls_size_string = arg;
2225 break;
2227 case OPT_mrelocatable:
2228 if (value == 1)
2230 target_flags |= MASK_MINIMAL_TOC;
2231 target_flags_explicit |= MASK_MINIMAL_TOC;
2232 TARGET_NO_FP_IN_TOC = 1;
2234 break;
2236 case OPT_mrelocatable_lib:
2237 if (value == 1)
2239 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
2240 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
2241 TARGET_NO_FP_IN_TOC = 1;
2243 else
2245 target_flags &= ~MASK_RELOCATABLE;
2246 target_flags_explicit |= MASK_RELOCATABLE;
2248 break;
2249 #endif
2251 case OPT_mabi_:
2252 if (!strcmp (arg, "altivec"))
2254 rs6000_explicit_options.altivec_abi = true;
2255 rs6000_altivec_abi = 1;
2257 /* Enabling the AltiVec ABI turns off the SPE ABI. */
2258 rs6000_spe_abi = 0;
2260 else if (! strcmp (arg, "no-altivec"))
2262 rs6000_explicit_options.altivec_abi = true;
2263 rs6000_altivec_abi = 0;
2265 else if (! strcmp (arg, "spe"))
2267 rs6000_explicit_options.spe_abi = true;
2268 rs6000_spe_abi = 1;
2269 rs6000_altivec_abi = 0;
2270 if (!TARGET_SPE_ABI)
2271 error ("not configured for ABI: '%s'", arg);
2273 else if (! strcmp (arg, "no-spe"))
2275 rs6000_explicit_options.spe_abi = true;
2276 rs6000_spe_abi = 0;
2279 /* These are here for testing during development only, do not
2280 document in the manual please. */
2281 else if (! strcmp (arg, "d64"))
2283 rs6000_darwin64_abi = 1;
2284 warning (0, "Using darwin64 ABI");
2286 else if (! strcmp (arg, "d32"))
2288 rs6000_darwin64_abi = 0;
2289 warning (0, "Using old darwin ABI");
2292 else if (! strcmp (arg, "ibmlongdouble"))
2294 rs6000_explicit_options.ieee = true;
2295 rs6000_ieeequad = 0;
2296 warning (0, "Using IBM extended precision long double");
2298 else if (! strcmp (arg, "ieeelongdouble"))
2300 rs6000_explicit_options.ieee = true;
2301 rs6000_ieeequad = 1;
2302 warning (0, "Using IEEE extended precision long double");
2305 else
2307 error ("unknown ABI specified: '%s'", arg);
2308 return false;
2310 break;
2312 case OPT_mcpu_:
2313 rs6000_select[1].string = arg;
2314 break;
2316 case OPT_mtune_:
2317 rs6000_select[2].string = arg;
2318 break;
2320 case OPT_mtraceback_:
2321 rs6000_traceback_name = arg;
2322 break;
2324 case OPT_mfloat_gprs_:
2325 rs6000_explicit_options.float_gprs = true;
2326 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
2327 rs6000_float_gprs = 1;
2328 else if (! strcmp (arg, "double"))
2329 rs6000_float_gprs = 2;
2330 else if (! strcmp (arg, "no"))
2331 rs6000_float_gprs = 0;
2332 else
2334 error ("invalid option for -mfloat-gprs: '%s'", arg);
2335 return false;
2337 break;
2339 case OPT_mlong_double_:
2340 rs6000_explicit_options.long_double = true;
2341 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2342 if (value != 64 && value != 128)
2344 error ("Unknown switch -mlong-double-%s", arg);
2345 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2346 return false;
2348 else
2349 rs6000_long_double_type_size = value;
2350 break;
2352 case OPT_msched_costly_dep_:
2353 rs6000_sched_costly_dep_str = arg;
2354 break;
2356 case OPT_malign_:
2357 rs6000_explicit_options.alignment = true;
2358 if (! strcmp (arg, "power"))
2360 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2361 some C library functions, so warn about it. The flag may be
2362 useful for performance studies from time to time though, so
2363 don't disable it entirely. */
2364 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2365 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2366 " it is incompatible with the installed C and C++ libraries");
2367 rs6000_alignment_flags = MASK_ALIGN_POWER;
2369 else if (! strcmp (arg, "natural"))
2370 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2371 else
2373 error ("unknown -malign-XXXXX option specified: '%s'", arg);
2374 return false;
2376 break;
2378 return true;
2381 /* Do anything needed at the start of the asm file. */
2383 static void
2384 rs6000_file_start (void)
2386 size_t i;
2387 char buffer[80];
2388 const char *start = buffer;
2389 struct rs6000_cpu_select *ptr;
2390 const char *default_cpu = TARGET_CPU_DEFAULT;
2391 FILE *file = asm_out_file;
2393 default_file_start ();
2395 #ifdef TARGET_BI_ARCH
2396 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
2397 default_cpu = 0;
2398 #endif
2400 if (flag_verbose_asm)
2402 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
2403 rs6000_select[0].string = default_cpu;
2405 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2407 ptr = &rs6000_select[i];
2408 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2410 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
2411 start = "";
2415 if (PPC405_ERRATUM77)
2417 fprintf (file, "%s PPC405CR_ERRATUM77", start);
2418 start = "";
2421 #ifdef USING_ELFOS_H
2422 switch (rs6000_sdata)
2424 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
2425 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
2426 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
2427 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
2430 if (rs6000_sdata && g_switch_value)
2432 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
2433 g_switch_value);
2434 start = "";
2436 #endif
2438 if (*start == '\0')
2439 putc ('\n', file);
2442 #ifdef HAVE_AS_GNU_ATTRIBUTE
2443 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
2445 fprintf (file, "\t.gnu_attribute 4, %d\n",
2446 (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
2447 fprintf (file, "\t.gnu_attribute 8, %d\n",
2448 (TARGET_ALTIVEC_ABI ? 2
2449 : TARGET_SPE_ABI ? 3
2450 : 1));
2452 #endif
2454 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
2456 switch_to_section (toc_section);
2457 switch_to_section (text_section);
2462 /* Return nonzero if this function is known to have a null epilogue. */
2465 direct_return (void)
2467 if (reload_completed)
2469 rs6000_stack_t *info = rs6000_stack_info ();
2471 if (info->first_gp_reg_save == 32
2472 && info->first_fp_reg_save == 64
2473 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
2474 && ! info->lr_save_p
2475 && ! info->cr_save_p
2476 && info->vrsave_mask == 0
2477 && ! info->push_p)
2478 return 1;
2481 return 0;
2484 /* Return the number of instructions it takes to form a constant in an
2485 integer register. */
2488 num_insns_constant_wide (HOST_WIDE_INT value)
2490 /* signed constant loadable with {cal|addi} */
2491 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
2492 return 1;
2494 /* constant loadable with {cau|addis} */
2495 else if ((value & 0xffff) == 0
2496 && (value >> 31 == -1 || value >> 31 == 0))
2497 return 1;
2499 #if HOST_BITS_PER_WIDE_INT == 64
2500 else if (TARGET_POWERPC64)
2502 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
2503 HOST_WIDE_INT high = value >> 31;
2505 if (high == 0 || high == -1)
2506 return 2;
2508 high >>= 1;
2510 if (low == 0)
2511 return num_insns_constant_wide (high) + 1;
2512 else
2513 return (num_insns_constant_wide (high)
2514 + num_insns_constant_wide (low) + 1);
2516 #endif
2518 else
2519 return 2;
2523 num_insns_constant (rtx op, enum machine_mode mode)
2525 HOST_WIDE_INT low, high;
2527 switch (GET_CODE (op))
2529 case CONST_INT:
2530 #if HOST_BITS_PER_WIDE_INT == 64
2531 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
2532 && mask64_operand (op, mode))
2533 return 2;
2534 else
2535 #endif
2536 return num_insns_constant_wide (INTVAL (op));
2538 case CONST_DOUBLE:
2539 if (mode == SFmode || mode == SDmode)
2541 long l;
2542 REAL_VALUE_TYPE rv;
2544 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2545 if (DECIMAL_FLOAT_MODE_P (mode))
2546 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
2547 else
2548 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
2549 return num_insns_constant_wide ((HOST_WIDE_INT) l);
2552 if (mode == VOIDmode || mode == DImode)
2554 high = CONST_DOUBLE_HIGH (op);
2555 low = CONST_DOUBLE_LOW (op);
2557 else
2559 long l[2];
2560 REAL_VALUE_TYPE rv;
2562 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2563 if (DECIMAL_FLOAT_MODE_P (mode))
2564 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
2565 else
2566 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
2567 high = l[WORDS_BIG_ENDIAN == 0];
2568 low = l[WORDS_BIG_ENDIAN != 0];
2571 if (TARGET_32BIT)
2572 return (num_insns_constant_wide (low)
2573 + num_insns_constant_wide (high));
2574 else
2576 if ((high == 0 && low >= 0)
2577 || (high == -1 && low < 0))
2578 return num_insns_constant_wide (low);
2580 else if (mask64_operand (op, mode))
2581 return 2;
2583 else if (low == 0)
2584 return num_insns_constant_wide (high) + 1;
2586 else
2587 return (num_insns_constant_wide (high)
2588 + num_insns_constant_wide (low) + 1);
2591 default:
2592 gcc_unreachable ();
2596 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2597 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2598 corresponding element of the vector, but for V4SFmode and V2SFmode,
2599 the corresponding "float" is interpreted as an SImode integer. */
2601 static HOST_WIDE_INT
2602 const_vector_elt_as_int (rtx op, unsigned int elt)
2604 rtx tmp = CONST_VECTOR_ELT (op, elt);
2605 if (GET_MODE (op) == V4SFmode
2606 || GET_MODE (op) == V2SFmode)
2607 tmp = gen_lowpart (SImode, tmp);
2608 return INTVAL (tmp);
2611 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2612 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2613 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2614 all items are set to the same value and contain COPIES replicas of the
2615 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2616 operand and the others are set to the value of the operand's msb. */
2618 static bool
2619 vspltis_constant (rtx op, unsigned step, unsigned copies)
2621 enum machine_mode mode = GET_MODE (op);
2622 enum machine_mode inner = GET_MODE_INNER (mode);
2624 unsigned i;
2625 unsigned nunits = GET_MODE_NUNITS (mode);
2626 unsigned bitsize = GET_MODE_BITSIZE (inner);
2627 unsigned mask = GET_MODE_MASK (inner);
2629 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
2630 HOST_WIDE_INT splat_val = val;
2631 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
2633 /* Construct the value to be splatted, if possible. If not, return 0. */
2634 for (i = 2; i <= copies; i *= 2)
2636 HOST_WIDE_INT small_val;
2637 bitsize /= 2;
2638 small_val = splat_val >> bitsize;
2639 mask >>= bitsize;
2640 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
2641 return false;
2642 splat_val = small_val;
2645 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2646 if (EASY_VECTOR_15 (splat_val))
2649 /* Also check if we can splat, and then add the result to itself. Do so if
2650 the value is positive, of if the splat instruction is using OP's mode;
2651 for splat_val < 0, the splat and the add should use the same mode. */
2652 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
2653 && (splat_val >= 0 || (step == 1 && copies == 1)))
2656 else
2657 return false;
2659 /* Check if VAL is present in every STEP-th element, and the
2660 other elements are filled with its most significant bit. */
2661 for (i = 0; i < nunits - 1; ++i)
2663 HOST_WIDE_INT desired_val;
2664 if (((i + 1) & (step - 1)) == 0)
2665 desired_val = val;
2666 else
2667 desired_val = msb_val;
2669 if (desired_val != const_vector_elt_as_int (op, i))
2670 return false;
2673 return true;
2677 /* Return true if OP is of the given MODE and can be synthesized
2678 with a vspltisb, vspltish or vspltisw. */
2680 bool
2681 easy_altivec_constant (rtx op, enum machine_mode mode)
2683 unsigned step, copies;
2685 if (mode == VOIDmode)
2686 mode = GET_MODE (op);
2687 else if (mode != GET_MODE (op))
2688 return false;
2690 /* Start with a vspltisw. */
2691 step = GET_MODE_NUNITS (mode) / 4;
2692 copies = 1;
2694 if (vspltis_constant (op, step, copies))
2695 return true;
2697 /* Then try with a vspltish. */
2698 if (step == 1)
2699 copies <<= 1;
2700 else
2701 step >>= 1;
2703 if (vspltis_constant (op, step, copies))
2704 return true;
2706 /* And finally a vspltisb. */
2707 if (step == 1)
2708 copies <<= 1;
2709 else
2710 step >>= 1;
2712 if (vspltis_constant (op, step, copies))
2713 return true;
2715 return false;
2718 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2719 result is OP. Abort if it is not possible. */
2722 gen_easy_altivec_constant (rtx op)
2724 enum machine_mode mode = GET_MODE (op);
2725 int nunits = GET_MODE_NUNITS (mode);
2726 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
2727 unsigned step = nunits / 4;
2728 unsigned copies = 1;
2730 /* Start with a vspltisw. */
2731 if (vspltis_constant (op, step, copies))
2732 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
2734 /* Then try with a vspltish. */
2735 if (step == 1)
2736 copies <<= 1;
2737 else
2738 step >>= 1;
2740 if (vspltis_constant (op, step, copies))
2741 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
2743 /* And finally a vspltisb. */
2744 if (step == 1)
2745 copies <<= 1;
2746 else
2747 step >>= 1;
2749 if (vspltis_constant (op, step, copies))
2750 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
2752 gcc_unreachable ();
2755 const char *
2756 output_vec_const_move (rtx *operands)
2758 int cst, cst2;
2759 enum machine_mode mode;
2760 rtx dest, vec;
2762 dest = operands[0];
2763 vec = operands[1];
2764 mode = GET_MODE (dest);
2766 if (TARGET_ALTIVEC)
2768 rtx splat_vec;
2769 if (zero_constant (vec, mode))
2770 return "vxor %0,%0,%0";
2772 splat_vec = gen_easy_altivec_constant (vec);
2773 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
2774 operands[1] = XEXP (splat_vec, 0);
2775 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
2776 return "#";
2778 switch (GET_MODE (splat_vec))
2780 case V4SImode:
2781 return "vspltisw %0,%1";
2783 case V8HImode:
2784 return "vspltish %0,%1";
2786 case V16QImode:
2787 return "vspltisb %0,%1";
2789 default:
2790 gcc_unreachable ();
2794 gcc_assert (TARGET_SPE);
2796 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2797 pattern of V1DI, V4HI, and V2SF.
2799 FIXME: We should probably return # and add post reload
2800 splitters for these, but this way is so easy ;-). */
2801 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
2802 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
2803 operands[1] = CONST_VECTOR_ELT (vec, 0);
2804 operands[2] = CONST_VECTOR_ELT (vec, 1);
2805 if (cst == cst2)
2806 return "li %0,%1\n\tevmergelo %0,%0,%0";
2807 else
2808 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2811 /* Initialize TARGET of vector PAIRED to VALS. */
2813 void
2814 paired_expand_vector_init (rtx target, rtx vals)
2816 enum machine_mode mode = GET_MODE (target);
2817 int n_elts = GET_MODE_NUNITS (mode);
2818 int n_var = 0;
2819 rtx x, new, tmp, constant_op, op1, op2;
2820 int i;
2822 for (i = 0; i < n_elts; ++i)
2824 x = XVECEXP (vals, 0, i);
2825 if (!CONSTANT_P (x))
2826 ++n_var;
2828 if (n_var == 0)
2830 /* Load from constant pool. */
2831 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
2832 return;
2835 if (n_var == 2)
2837 /* The vector is initialized only with non-constants. */
2838 new = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
2839 XVECEXP (vals, 0, 1));
2841 emit_move_insn (target, new);
2842 return;
2845 /* One field is non-constant and the other one is a constant. Load the
2846 constant from the constant pool and use ps_merge instruction to
2847 construct the whole vector. */
2848 op1 = XVECEXP (vals, 0, 0);
2849 op2 = XVECEXP (vals, 0, 1);
2851 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
2853 tmp = gen_reg_rtx (GET_MODE (constant_op));
2854 emit_move_insn (tmp, constant_op);
2856 if (CONSTANT_P (op1))
2857 new = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
2858 else
2859 new = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
2861 emit_move_insn (target, new);
2864 void
2865 paired_expand_vector_move (rtx operands[])
2867 rtx op0 = operands[0], op1 = operands[1];
2869 emit_move_insn (op0, op1);
2872 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
2873 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
2874 operands for the relation operation COND. This is a recursive
2875 function. */
2877 static void
2878 paired_emit_vector_compare (enum rtx_code rcode,
2879 rtx dest, rtx op0, rtx op1,
2880 rtx cc_op0, rtx cc_op1)
2882 rtx tmp = gen_reg_rtx (V2SFmode);
2883 rtx tmp1, max, min, equal_zero;
2885 gcc_assert (TARGET_PAIRED_FLOAT);
2886 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
2888 switch (rcode)
2890 case LT:
2891 case LTU:
2892 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
2893 return;
2894 case GE:
2895 case GEU:
2896 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
2897 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
2898 return;
2899 case LE:
2900 case LEU:
2901 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
2902 return;
2903 case GT:
2904 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
2905 return;
2906 case EQ:
2907 tmp1 = gen_reg_rtx (V2SFmode);
2908 max = gen_reg_rtx (V2SFmode);
2909 min = gen_reg_rtx (V2SFmode);
2910 equal_zero = gen_reg_rtx (V2SFmode);
2912 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
2913 emit_insn (gen_selv2sf4
2914 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
2915 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
2916 emit_insn (gen_selv2sf4
2917 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
2918 emit_insn (gen_subv2sf3 (tmp1, min, max));
2919 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
2920 return;
2921 case NE:
2922 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
2923 return;
2924 case UNLE:
2925 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
2926 return;
2927 case UNLT:
2928 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
2929 return;
2930 case UNGE:
2931 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
2932 return;
2933 case UNGT:
2934 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
2935 return;
2936 default:
2937 gcc_unreachable ();
2940 return;
2943 /* Emit vector conditional expression.
2944 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
2945 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
2948 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
2949 rtx cond, rtx cc_op0, rtx cc_op1)
2951 enum rtx_code rcode = GET_CODE (cond);
2953 if (!TARGET_PAIRED_FLOAT)
2954 return 0;
2956 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
2958 return 1;
2961 /* Initialize vector TARGET to VALS. */
2963 void
2964 rs6000_expand_vector_init (rtx target, rtx vals)
2966 enum machine_mode mode = GET_MODE (target);
2967 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2968 int n_elts = GET_MODE_NUNITS (mode);
2969 int n_var = 0, one_var = -1;
2970 bool all_same = true, all_const_zero = true;
2971 rtx x, mem;
2972 int i;
2974 for (i = 0; i < n_elts; ++i)
2976 x = XVECEXP (vals, 0, i);
2977 if (!CONSTANT_P (x))
2978 ++n_var, one_var = i;
2979 else if (x != CONST0_RTX (inner_mode))
2980 all_const_zero = false;
2982 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
2983 all_same = false;
2986 if (n_var == 0)
2988 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
2989 if (mode != V4SFmode && all_const_zero)
2991 /* Zero register. */
2992 emit_insn (gen_rtx_SET (VOIDmode, target,
2993 gen_rtx_XOR (mode, target, target)));
2994 return;
2996 else if (mode != V4SFmode && easy_vector_constant (const_vec, mode))
2998 /* Splat immediate. */
2999 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
3000 return;
3002 else if (all_same)
3003 ; /* Splat vector element. */
3004 else
3006 /* Load from constant pool. */
3007 emit_move_insn (target, const_vec);
3008 return;
3012 /* Store value to stack temp. Load vector element. Splat. */
3013 if (all_same)
3015 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
3016 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
3017 XVECEXP (vals, 0, 0));
3018 x = gen_rtx_UNSPEC (VOIDmode,
3019 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
3020 emit_insn (gen_rtx_PARALLEL (VOIDmode,
3021 gen_rtvec (2,
3022 gen_rtx_SET (VOIDmode,
3023 target, mem),
3024 x)));
3025 x = gen_rtx_VEC_SELECT (inner_mode, target,
3026 gen_rtx_PARALLEL (VOIDmode,
3027 gen_rtvec (1, const0_rtx)));
3028 emit_insn (gen_rtx_SET (VOIDmode, target,
3029 gen_rtx_VEC_DUPLICATE (mode, x)));
3030 return;
3033 /* One field is non-constant. Load constant then overwrite
3034 varying field. */
3035 if (n_var == 1)
3037 rtx copy = copy_rtx (vals);
3039 /* Load constant part of vector, substitute neighboring value for
3040 varying element. */
3041 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
3042 rs6000_expand_vector_init (target, copy);
3044 /* Insert variable. */
3045 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
3046 return;
3049 /* Construct the vector in memory one field at a time
3050 and load the whole vector. */
3051 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
3052 for (i = 0; i < n_elts; i++)
3053 emit_move_insn (adjust_address_nv (mem, inner_mode,
3054 i * GET_MODE_SIZE (inner_mode)),
3055 XVECEXP (vals, 0, i));
3056 emit_move_insn (target, mem);
3059 /* Set field ELT of TARGET to VAL. */
3061 void
3062 rs6000_expand_vector_set (rtx target, rtx val, int elt)
3064 enum machine_mode mode = GET_MODE (target);
3065 enum machine_mode inner_mode = GET_MODE_INNER (mode);
3066 rtx reg = gen_reg_rtx (mode);
3067 rtx mask, mem, x;
3068 int width = GET_MODE_SIZE (inner_mode);
3069 int i;
3071 /* Load single variable value. */
3072 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
3073 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
3074 x = gen_rtx_UNSPEC (VOIDmode,
3075 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
3076 emit_insn (gen_rtx_PARALLEL (VOIDmode,
3077 gen_rtvec (2,
3078 gen_rtx_SET (VOIDmode,
3079 reg, mem),
3080 x)));
3082 /* Linear sequence. */
3083 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
3084 for (i = 0; i < 16; ++i)
3085 XVECEXP (mask, 0, i) = GEN_INT (i);
3087 /* Set permute mask to insert element into target. */
3088 for (i = 0; i < width; ++i)
3089 XVECEXP (mask, 0, elt*width + i)
3090 = GEN_INT (i + 0x10);
3091 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
3092 x = gen_rtx_UNSPEC (mode,
3093 gen_rtvec (3, target, reg,
3094 force_reg (V16QImode, x)),
3095 UNSPEC_VPERM);
3096 emit_insn (gen_rtx_SET (VOIDmode, target, x));
3099 /* Extract field ELT from VEC into TARGET. */
3101 void
3102 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
3104 enum machine_mode mode = GET_MODE (vec);
3105 enum machine_mode inner_mode = GET_MODE_INNER (mode);
3106 rtx mem, x;
3108 /* Allocate mode-sized buffer. */
3109 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
3111 /* Add offset to field within buffer matching vector element. */
3112 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
3114 /* Store single field into mode-sized buffer. */
3115 x = gen_rtx_UNSPEC (VOIDmode,
3116 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
3117 emit_insn (gen_rtx_PARALLEL (VOIDmode,
3118 gen_rtvec (2,
3119 gen_rtx_SET (VOIDmode,
3120 mem, vec),
3121 x)));
3122 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
3125 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
3126 implement ANDing by the mask IN. */
3127 void
3128 build_mask64_2_operands (rtx in, rtx *out)
3130 #if HOST_BITS_PER_WIDE_INT >= 64
3131 unsigned HOST_WIDE_INT c, lsb, m1, m2;
3132 int shift;
3134 gcc_assert (GET_CODE (in) == CONST_INT);
3136 c = INTVAL (in);
3137 if (c & 1)
3139 /* Assume c initially something like 0x00fff000000fffff. The idea
3140 is to rotate the word so that the middle ^^^^^^ group of zeros
3141 is at the MS end and can be cleared with an rldicl mask. We then
3142 rotate back and clear off the MS ^^ group of zeros with a
3143 second rldicl. */
3144 c = ~c; /* c == 0xff000ffffff00000 */
3145 lsb = c & -c; /* lsb == 0x0000000000100000 */
3146 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
3147 c = ~c; /* c == 0x00fff000000fffff */
3148 c &= -lsb; /* c == 0x00fff00000000000 */
3149 lsb = c & -c; /* lsb == 0x0000100000000000 */
3150 c = ~c; /* c == 0xff000fffffffffff */
3151 c &= -lsb; /* c == 0xff00000000000000 */
3152 shift = 0;
3153 while ((lsb >>= 1) != 0)
3154 shift++; /* shift == 44 on exit from loop */
3155 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
3156 m1 = ~m1; /* m1 == 0x000000ffffffffff */
3157 m2 = ~c; /* m2 == 0x00ffffffffffffff */
3159 else
3161 /* Assume c initially something like 0xff000f0000000000. The idea
3162 is to rotate the word so that the ^^^ middle group of zeros
3163 is at the LS end and can be cleared with an rldicr mask. We then
3164 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
3165 a second rldicr. */
3166 lsb = c & -c; /* lsb == 0x0000010000000000 */
3167 m2 = -lsb; /* m2 == 0xffffff0000000000 */
3168 c = ~c; /* c == 0x00fff0ffffffffff */
3169 c &= -lsb; /* c == 0x00fff00000000000 */
3170 lsb = c & -c; /* lsb == 0x0000100000000000 */
3171 c = ~c; /* c == 0xff000fffffffffff */
3172 c &= -lsb; /* c == 0xff00000000000000 */
3173 shift = 0;
3174 while ((lsb >>= 1) != 0)
3175 shift++; /* shift == 44 on exit from loop */
3176 m1 = ~c; /* m1 == 0x00ffffffffffffff */
3177 m1 >>= shift; /* m1 == 0x0000000000000fff */
3178 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
3181 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
3182 masks will be all 1's. We are guaranteed more than one transition. */
3183 out[0] = GEN_INT (64 - shift);
3184 out[1] = GEN_INT (m1);
3185 out[2] = GEN_INT (shift);
3186 out[3] = GEN_INT (m2);
3187 #else
3188 (void)in;
3189 (void)out;
3190 gcc_unreachable ();
3191 #endif
3194 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
3196 bool
3197 invalid_e500_subreg (rtx op, enum machine_mode mode)
3199 if (TARGET_E500_DOUBLE)
3201 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
3202 subreg:TI and reg:TF. */
3203 if (GET_CODE (op) == SUBREG
3204 && (mode == SImode || mode == DImode || mode == TImode)
3205 && REG_P (SUBREG_REG (op))
3206 && (GET_MODE (SUBREG_REG (op)) == DFmode
3207 || GET_MODE (SUBREG_REG (op)) == TFmode
3208 || GET_MODE (SUBREG_REG (op)) == DDmode
3209 || GET_MODE (SUBREG_REG (op)) == TDmode))
3210 return true;
3212 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
3213 reg:TI. */
3214 if (GET_CODE (op) == SUBREG
3215 && (mode == DFmode || mode == TFmode
3216 || mode == DDmode || mode == TDmode)
3217 && REG_P (SUBREG_REG (op))
3218 && (GET_MODE (SUBREG_REG (op)) == DImode
3219 || GET_MODE (SUBREG_REG (op)) == TImode))
3220 return true;
3223 if (TARGET_SPE
3224 && GET_CODE (op) == SUBREG
3225 && mode == SImode
3226 && REG_P (SUBREG_REG (op))
3227 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
3228 return true;
3230 return false;
3233 /* AIX increases natural record alignment to doubleword if the first
3234 field is an FP double while the FP fields remain word aligned. */
3236 unsigned int
3237 rs6000_special_round_type_align (tree type, unsigned int computed,
3238 unsigned int specified)
3240 unsigned int align = MAX (computed, specified);
3241 tree field = TYPE_FIELDS (type);
3243 /* Skip all non field decls */
3244 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
3245 field = TREE_CHAIN (field);
3247 if (field != NULL && field != type)
3249 type = TREE_TYPE (field);
3250 while (TREE_CODE (type) == ARRAY_TYPE)
3251 type = TREE_TYPE (type);
3253 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
3254 align = MAX (align, 64);
3257 return align;
3260 /* Darwin increases record alignment to the natural alignment of
3261 the first field. */
3263 unsigned int
3264 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
3265 unsigned int specified)
3267 unsigned int align = MAX (computed, specified);
3269 if (TYPE_PACKED (type))
3270 return align;
3272 /* Find the first field, looking down into aggregates. */
3273 do {
3274 tree field = TYPE_FIELDS (type);
3275 /* Skip all non field decls */
3276 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
3277 field = TREE_CHAIN (field);
3278 if (! field)
3279 break;
3280 type = TREE_TYPE (field);
3281 while (TREE_CODE (type) == ARRAY_TYPE)
3282 type = TREE_TYPE (type);
3283 } while (AGGREGATE_TYPE_P (type));
3285 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
3286 align = MAX (align, TYPE_ALIGN (type));
3288 return align;
3291 /* Return 1 for an operand in small memory on V.4/eabi. */
3294 small_data_operand (rtx op ATTRIBUTE_UNUSED,
3295 enum machine_mode mode ATTRIBUTE_UNUSED)
3297 #if TARGET_ELF
3298 rtx sym_ref;
3300 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
3301 return 0;
3303 if (DEFAULT_ABI != ABI_V4)
3304 return 0;
3306 /* Vector and float memory instructions have a limited offset on the
3307 SPE, so using a vector or float variable directly as an operand is
3308 not useful. */
3309 if (TARGET_SPE
3310 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
3311 return 0;
3313 if (GET_CODE (op) == SYMBOL_REF)
3314 sym_ref = op;
3316 else if (GET_CODE (op) != CONST
3317 || GET_CODE (XEXP (op, 0)) != PLUS
3318 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
3319 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
3320 return 0;
3322 else
3324 rtx sum = XEXP (op, 0);
3325 HOST_WIDE_INT summand;
3327 /* We have to be careful here, because it is the referenced address
3328 that must be 32k from _SDA_BASE_, not just the symbol. */
3329 summand = INTVAL (XEXP (sum, 1));
3330 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
3331 return 0;
3333 sym_ref = XEXP (sum, 0);
3336 return SYMBOL_REF_SMALL_P (sym_ref);
3337 #else
3338 return 0;
3339 #endif
3342 /* Return true if either operand is a general purpose register. */
3344 bool
3345 gpr_or_gpr_p (rtx op0, rtx op1)
3347 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
3348 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
3352 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
3354 static int
3355 constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
3357 switch (GET_CODE (op))
3359 case SYMBOL_REF:
3360 if (RS6000_SYMBOL_REF_TLS_P (op))
3361 return 0;
3362 else if (CONSTANT_POOL_ADDRESS_P (op))
3364 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
3366 *have_sym = 1;
3367 return 1;
3369 else
3370 return 0;
3372 else if (! strcmp (XSTR (op, 0), toc_label_name))
3374 *have_toc = 1;
3375 return 1;
3377 else
3378 return 0;
3379 case PLUS:
3380 case MINUS:
3381 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
3382 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
3383 case CONST:
3384 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
3385 case CONST_INT:
3386 return 1;
3387 default:
3388 return 0;
3392 static bool
3393 constant_pool_expr_p (rtx op)
3395 int have_sym = 0;
3396 int have_toc = 0;
3397 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
3400 bool
3401 toc_relative_expr_p (rtx op)
3403 int have_sym = 0;
3404 int have_toc = 0;
3405 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
3408 bool
3409 legitimate_constant_pool_address_p (rtx x)
3411 return (TARGET_TOC
3412 && GET_CODE (x) == PLUS
3413 && GET_CODE (XEXP (x, 0)) == REG
3414 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
3415 && constant_pool_expr_p (XEXP (x, 1)));
3418 static bool
3419 legitimate_small_data_p (enum machine_mode mode, rtx x)
3421 return (DEFAULT_ABI == ABI_V4
3422 && !flag_pic && !TARGET_TOC
3423 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
3424 && small_data_operand (x, mode));
3427 /* SPE offset addressing is limited to 5-bits worth of double words. */
3428 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
3430 bool
3431 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
3433 unsigned HOST_WIDE_INT offset, extra;
3435 if (GET_CODE (x) != PLUS)
3436 return false;
3437 if (GET_CODE (XEXP (x, 0)) != REG)
3438 return false;
3439 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
3440 return false;
3441 if (legitimate_constant_pool_address_p (x))
3442 return true;
3443 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
3444 return false;
3446 offset = INTVAL (XEXP (x, 1));
3447 extra = 0;
3448 switch (mode)
3450 case V16QImode:
3451 case V8HImode:
3452 case V4SFmode:
3453 case V4SImode:
3454 /* AltiVec vector modes. Only reg+reg addressing is valid and
3455 constant offset zero should not occur due to canonicalization. */
3456 return false;
3458 case V4HImode:
3459 case V2SImode:
3460 case V1DImode:
3461 case V2SFmode:
3462 /* Paired vector modes. Only reg+reg addressing is valid and
3463 constant offset zero should not occur due to canonicalization. */
3464 if (TARGET_PAIRED_FLOAT)
3465 return false;
3466 /* SPE vector modes. */
3467 return SPE_CONST_OFFSET_OK (offset);
3469 case DFmode:
3470 case DDmode:
3471 if (TARGET_E500_DOUBLE)
3472 return SPE_CONST_OFFSET_OK (offset);
3474 case DImode:
3475 /* On e500v2, we may have:
3477 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3479 Which gets addressed with evldd instructions. */
3480 if (TARGET_E500_DOUBLE)
3481 return SPE_CONST_OFFSET_OK (offset);
3483 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
3484 extra = 4;
3485 else if (offset & 3)
3486 return false;
3487 break;
3489 case TFmode:
3490 case TDmode:
3491 if (TARGET_E500_DOUBLE)
3492 return (SPE_CONST_OFFSET_OK (offset)
3493 && SPE_CONST_OFFSET_OK (offset + 8));
3495 case TImode:
3496 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
3497 extra = 12;
3498 else if (offset & 3)
3499 return false;
3500 else
3501 extra = 8;
3502 break;
3504 default:
3505 break;
3508 offset += 0x8000;
3509 return (offset < 0x10000) && (offset + extra < 0x10000);
3512 bool
3513 legitimate_indexed_address_p (rtx x, int strict)
3515 rtx op0, op1;
3517 if (GET_CODE (x) != PLUS)
3518 return false;
3520 op0 = XEXP (x, 0);
3521 op1 = XEXP (x, 1);
3523 /* Recognize the rtl generated by reload which we know will later be
3524 replaced with proper base and index regs. */
3525 if (!strict
3526 && reload_in_progress
3527 && (REG_P (op0) || GET_CODE (op0) == PLUS)
3528 && REG_P (op1))
3529 return true;
3531 return (REG_P (op0) && REG_P (op1)
3532 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
3533 && INT_REG_OK_FOR_INDEX_P (op1, strict))
3534 || (INT_REG_OK_FOR_BASE_P (op1, strict)
3535 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
3538 inline bool
3539 legitimate_indirect_address_p (rtx x, int strict)
3541 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
3544 bool
3545 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
3547 if (!TARGET_MACHO || !flag_pic
3548 || mode != SImode || GET_CODE (x) != MEM)
3549 return false;
3550 x = XEXP (x, 0);
3552 if (GET_CODE (x) != LO_SUM)
3553 return false;
3554 if (GET_CODE (XEXP (x, 0)) != REG)
3555 return false;
3556 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
3557 return false;
3558 x = XEXP (x, 1);
3560 return CONSTANT_P (x);
3563 static bool
3564 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
3566 if (GET_CODE (x) != LO_SUM)
3567 return false;
3568 if (GET_CODE (XEXP (x, 0)) != REG)
3569 return false;
3570 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
3571 return false;
3572 /* Restrict addressing for DI because of our SUBREG hackery. */
3573 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3574 || mode == DDmode || mode == TDmode
3575 || mode == DImode))
3576 return false;
3577 x = XEXP (x, 1);
3579 if (TARGET_ELF || TARGET_MACHO)
3581 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
3582 return false;
3583 if (TARGET_TOC)
3584 return false;
3585 if (GET_MODE_NUNITS (mode) != 1)
3586 return false;
3587 if (GET_MODE_BITSIZE (mode) > 64
3588 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
3589 && !(TARGET_HARD_FLOAT && TARGET_FPRS
3590 && (mode == DFmode || mode == DDmode))))
3591 return false;
3593 return CONSTANT_P (x);
3596 return false;
3600 /* Try machine-dependent ways of modifying an illegitimate address
3601 to be legitimate. If we find one, return the new, valid address.
3602 This is used from only one place: `memory_address' in explow.c.
3604 OLDX is the address as it was before break_out_memory_refs was
3605 called. In some cases it is useful to look at this to decide what
3606 needs to be done.
3608 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3610 It is always safe for this function to do nothing. It exists to
3611 recognize opportunities to optimize the output.
3613 On RS/6000, first check for the sum of a register with a constant
3614 integer that is out of range. If so, generate code to add the
3615 constant with the low-order 16 bits masked to the register and force
3616 this result into another register (this can be done with `cau').
3617 Then generate an address of REG+(CONST&0xffff), allowing for the
3618 possibility of bit 16 being a one.
3620 Then check for the sum of a register and something not constant, try to
3621 load the other things into a register and return the sum. */
3624 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3625 enum machine_mode mode)
3627 if (GET_CODE (x) == SYMBOL_REF)
3629 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
3630 if (model != 0)
3631 return rs6000_legitimize_tls_address (x, model);
3634 if (GET_CODE (x) == PLUS
3635 && GET_CODE (XEXP (x, 0)) == REG
3636 && GET_CODE (XEXP (x, 1)) == CONST_INT
3637 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000
3638 && !(SPE_VECTOR_MODE (mode)
3639 || ALTIVEC_VECTOR_MODE (mode)
3640 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3641 || mode == DImode))))
3643 HOST_WIDE_INT high_int, low_int;
3644 rtx sum;
3645 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3646 high_int = INTVAL (XEXP (x, 1)) - low_int;
3647 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
3648 GEN_INT (high_int)), 0);
3649 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
3651 else if (GET_CODE (x) == PLUS
3652 && GET_CODE (XEXP (x, 0)) == REG
3653 && GET_CODE (XEXP (x, 1)) != CONST_INT
3654 && GET_MODE_NUNITS (mode) == 1
3655 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3656 || TARGET_POWERPC64
3657 || ((mode != DImode && mode != DFmode && mode != DDmode)
3658 || TARGET_E500_DOUBLE))
3659 && (TARGET_POWERPC64 || mode != DImode)
3660 && mode != TImode
3661 && mode != TFmode
3662 && mode != TDmode)
3664 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
3665 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
3667 else if (ALTIVEC_VECTOR_MODE (mode))
3669 rtx reg;
3671 /* Make sure both operands are registers. */
3672 if (GET_CODE (x) == PLUS)
3673 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
3674 force_reg (Pmode, XEXP (x, 1)));
3676 reg = force_reg (Pmode, x);
3677 return reg;
3679 else if (SPE_VECTOR_MODE (mode)
3680 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3681 || mode == DDmode || mode == TDmode
3682 || mode == DImode)))
3684 if (mode == DImode)
3685 return NULL_RTX;
3686 /* We accept [reg + reg] and [reg + OFFSET]. */
3688 if (GET_CODE (x) == PLUS)
3690 rtx op1 = XEXP (x, 0);
3691 rtx op2 = XEXP (x, 1);
3692 rtx y;
3694 op1 = force_reg (Pmode, op1);
3696 if (GET_CODE (op2) != REG
3697 && (GET_CODE (op2) != CONST_INT
3698 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
3699 || (GET_MODE_SIZE (mode) > 8
3700 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
3701 op2 = force_reg (Pmode, op2);
3703 /* We can't always do [reg + reg] for these, because [reg +
3704 reg + offset] is not a legitimate addressing mode. */
3705 y = gen_rtx_PLUS (Pmode, op1, op2);
3707 if (GET_MODE_SIZE (mode) > 8 && REG_P (op2))
3708 return force_reg (Pmode, y);
3709 else
3710 return y;
3713 return force_reg (Pmode, x);
3715 else if (TARGET_ELF
3716 && TARGET_32BIT
3717 && TARGET_NO_TOC
3718 && ! flag_pic
3719 && GET_CODE (x) != CONST_INT
3720 && GET_CODE (x) != CONST_DOUBLE
3721 && CONSTANT_P (x)
3722 && GET_MODE_NUNITS (mode) == 1
3723 && (GET_MODE_BITSIZE (mode) <= 32
3724 || ((TARGET_HARD_FLOAT && TARGET_FPRS)
3725 && (mode == DFmode || mode == DDmode))))
3727 rtx reg = gen_reg_rtx (Pmode);
3728 emit_insn (gen_elf_high (reg, x));
3729 return gen_rtx_LO_SUM (Pmode, reg, x);
3731 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
3732 && ! flag_pic
3733 #if TARGET_MACHO
3734 && ! MACHO_DYNAMIC_NO_PIC_P
3735 #endif
3736 && GET_CODE (x) != CONST_INT
3737 && GET_CODE (x) != CONST_DOUBLE
3738 && CONSTANT_P (x)
3739 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3740 || (mode != DFmode && mode != DDmode))
3741 && mode != DImode
3742 && mode != TImode)
3744 rtx reg = gen_reg_rtx (Pmode);
3745 emit_insn (gen_macho_high (reg, x));
3746 return gen_rtx_LO_SUM (Pmode, reg, x);
3748 else if (TARGET_TOC
3749 && constant_pool_expr_p (x)
3750 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
3752 return create_TOC_reference (x);
3754 else
3755 return NULL_RTX;
3758 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3759 We need to emit DTP-relative relocations. */
3761 static void
3762 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
3764 switch (size)
3766 case 4:
3767 fputs ("\t.long\t", file);
3768 break;
3769 case 8:
3770 fputs (DOUBLE_INT_ASM_OP, file);
3771 break;
3772 default:
3773 gcc_unreachable ();
3775 output_addr_const (file, x);
3776 fputs ("@dtprel+0x8000", file);
3779 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3781 static GTY(()) rtx rs6000_tls_symbol;
3782 static rtx
3783 rs6000_tls_get_addr (void)
3785 if (!rs6000_tls_symbol)
3786 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
3788 return rs6000_tls_symbol;
3791 /* Construct the SYMBOL_REF for TLS GOT references. */
3793 static GTY(()) rtx rs6000_got_symbol;
3794 static rtx
3795 rs6000_got_sym (void)
3797 if (!rs6000_got_symbol)
3799 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
3800 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
3801 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
3804 return rs6000_got_symbol;
3807 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3808 this (thread-local) address. */
3810 static rtx
3811 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
3813 rtx dest, insn;
3815 dest = gen_reg_rtx (Pmode);
3816 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
3818 rtx tlsreg;
3820 if (TARGET_64BIT)
3822 tlsreg = gen_rtx_REG (Pmode, 13);
3823 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
3825 else
3827 tlsreg = gen_rtx_REG (Pmode, 2);
3828 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
3830 emit_insn (insn);
3832 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
3834 rtx tlsreg, tmp;
3836 tmp = gen_reg_rtx (Pmode);
3837 if (TARGET_64BIT)
3839 tlsreg = gen_rtx_REG (Pmode, 13);
3840 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
3842 else
3844 tlsreg = gen_rtx_REG (Pmode, 2);
3845 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
3847 emit_insn (insn);
3848 if (TARGET_64BIT)
3849 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
3850 else
3851 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
3852 emit_insn (insn);
3854 else
3856 rtx r3, got, tga, tmp1, tmp2, eqv;
3858 /* We currently use relocations like @got@tlsgd for tls, which
3859 means the linker will handle allocation of tls entries, placing
3860 them in the .got section. So use a pointer to the .got section,
3861 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3862 or to secondary GOT sections used by 32-bit -fPIC. */
3863 if (TARGET_64BIT)
3864 got = gen_rtx_REG (Pmode, 2);
3865 else
3867 if (flag_pic == 1)
3868 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
3869 else
3871 rtx gsym = rs6000_got_sym ();
3872 got = gen_reg_rtx (Pmode);
3873 if (flag_pic == 0)
3874 rs6000_emit_move (got, gsym, Pmode);
3875 else
3877 rtx tmp3, mem;
3878 rtx first, last;
3880 tmp1 = gen_reg_rtx (Pmode);
3881 tmp2 = gen_reg_rtx (Pmode);
3882 tmp3 = gen_reg_rtx (Pmode);
3883 mem = gen_const_mem (Pmode, tmp1);
3885 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
3886 emit_move_insn (tmp1,
3887 gen_rtx_REG (Pmode, LR_REGNO));
3888 emit_move_insn (tmp2, mem);
3889 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
3890 last = emit_move_insn (got, tmp3);
3891 set_unique_reg_note (last, REG_EQUAL, gsym);
3892 maybe_encapsulate_block (first, last, gsym);
3897 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
3899 r3 = gen_rtx_REG (Pmode, 3);
3900 if (TARGET_64BIT)
3901 insn = gen_tls_gd_64 (r3, got, addr);
3902 else
3903 insn = gen_tls_gd_32 (r3, got, addr);
3904 start_sequence ();
3905 emit_insn (insn);
3906 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3907 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3908 insn = emit_call_insn (insn);
3909 RTL_CONST_CALL_P (insn) = 1;
3910 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3911 insn = get_insns ();
3912 end_sequence ();
3913 emit_libcall_block (insn, dest, r3, addr);
3915 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3917 r3 = gen_rtx_REG (Pmode, 3);
3918 if (TARGET_64BIT)
3919 insn = gen_tls_ld_64 (r3, got);
3920 else
3921 insn = gen_tls_ld_32 (r3, got);
3922 start_sequence ();
3923 emit_insn (insn);
3924 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3925 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3926 insn = emit_call_insn (insn);
3927 RTL_CONST_CALL_P (insn) = 1;
3928 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3929 insn = get_insns ();
3930 end_sequence ();
3931 tmp1 = gen_reg_rtx (Pmode);
3932 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3933 UNSPEC_TLSLD);
3934 emit_libcall_block (insn, tmp1, r3, eqv);
3935 if (rs6000_tls_size == 16)
3937 if (TARGET_64BIT)
3938 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3939 else
3940 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3942 else if (rs6000_tls_size == 32)
3944 tmp2 = gen_reg_rtx (Pmode);
3945 if (TARGET_64BIT)
3946 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3947 else
3948 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3949 emit_insn (insn);
3950 if (TARGET_64BIT)
3951 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3952 else
3953 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3955 else
3957 tmp2 = gen_reg_rtx (Pmode);
3958 if (TARGET_64BIT)
3959 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3960 else
3961 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3962 emit_insn (insn);
3963 insn = gen_rtx_SET (Pmode, dest,
3964 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3966 emit_insn (insn);
3968 else
3970 /* IE, or 64-bit offset LE. */
3971 tmp2 = gen_reg_rtx (Pmode);
3972 if (TARGET_64BIT)
3973 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3974 else
3975 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3976 emit_insn (insn);
3977 if (TARGET_64BIT)
3978 insn = gen_tls_tls_64 (dest, tmp2, addr);
3979 else
3980 insn = gen_tls_tls_32 (dest, tmp2, addr);
3981 emit_insn (insn);
3985 return dest;
3988 /* Return 1 if X contains a thread-local symbol. */
3990 bool
3991 rs6000_tls_referenced_p (rtx x)
3993 if (! TARGET_HAVE_TLS)
3994 return false;
3996 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
3999 /* Return 1 if *X is a thread-local symbol. This is the same as
4000 rs6000_tls_symbol_ref except for the type of the unused argument. */
4002 static int
4003 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
4005 return RS6000_SYMBOL_REF_TLS_P (*x);
4008 /* The convention appears to be to define this wherever it is used.
4009 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
4010 is now used here. */
4011 #ifndef REG_MODE_OK_FOR_BASE_P
4012 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
4013 #endif
4015 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
4016 replace the input X, or the original X if no replacement is called for.
4017 The output parameter *WIN is 1 if the calling macro should goto WIN,
4018 0 if it should not.
4020 For RS/6000, we wish to handle large displacements off a base
4021 register by splitting the addend across an addiu/addis and the mem insn.
4022 This cuts number of extra insns needed from 3 to 1.
4024 On Darwin, we use this to generate code for floating point constants.
4025 A movsf_low is generated so we wind up with 2 instructions rather than 3.
4026 The Darwin code is inside #if TARGET_MACHO because only then is
4027 machopic_function_base_name() defined. */
4029 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
4030 int opnum, int type,
4031 int ind_levels ATTRIBUTE_UNUSED, int *win)
4033 /* We must recognize output that we have already generated ourselves. */
4034 if (GET_CODE (x) == PLUS
4035 && GET_CODE (XEXP (x, 0)) == PLUS
4036 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
4037 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4038 && GET_CODE (XEXP (x, 1)) == CONST_INT)
4040 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4041 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
4042 opnum, (enum reload_type)type);
4043 *win = 1;
4044 return x;
4047 #if TARGET_MACHO
4048 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
4049 && GET_CODE (x) == LO_SUM
4050 && GET_CODE (XEXP (x, 0)) == PLUS
4051 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
4052 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
4053 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
4054 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
4055 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
4056 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
4057 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
4059 /* Result of previous invocation of this function on Darwin
4060 floating point constant. */
4061 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4062 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
4063 opnum, (enum reload_type)type);
4064 *win = 1;
4065 return x;
4067 #endif
4069 /* Force ld/std non-word aligned offset into base register by wrapping
4070 in offset 0. */
4071 if (GET_CODE (x) == PLUS
4072 && GET_CODE (XEXP (x, 0)) == REG
4073 && REGNO (XEXP (x, 0)) < 32
4074 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
4075 && GET_CODE (XEXP (x, 1)) == CONST_INT
4076 && (INTVAL (XEXP (x, 1)) & 3) != 0
4077 && !ALTIVEC_VECTOR_MODE (mode)
4078 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
4079 && TARGET_POWERPC64)
4081 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
4082 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4083 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
4084 opnum, (enum reload_type) type);
4085 *win = 1;
4086 return x;
4089 if (GET_CODE (x) == PLUS
4090 && GET_CODE (XEXP (x, 0)) == REG
4091 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
4092 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
4093 && GET_CODE (XEXP (x, 1)) == CONST_INT
4094 && !SPE_VECTOR_MODE (mode)
4095 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4096 || mode == DDmode || mode == TDmode
4097 || mode == DImode))
4098 && !ALTIVEC_VECTOR_MODE (mode))
4100 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
4101 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
4102 HOST_WIDE_INT high
4103 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
4105 /* Check for 32-bit overflow. */
4106 if (high + low != val)
4108 *win = 0;
4109 return x;
4112 /* Reload the high part into a base reg; leave the low part
4113 in the mem directly. */
4115 x = gen_rtx_PLUS (GET_MODE (x),
4116 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
4117 GEN_INT (high)),
4118 GEN_INT (low));
4120 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4121 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
4122 opnum, (enum reload_type)type);
4123 *win = 1;
4124 return x;
4127 if (GET_CODE (x) == SYMBOL_REF
4128 && !ALTIVEC_VECTOR_MODE (mode)
4129 && !SPE_VECTOR_MODE (mode)
4130 #if TARGET_MACHO
4131 && DEFAULT_ABI == ABI_DARWIN
4132 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
4133 #else
4134 && DEFAULT_ABI == ABI_V4
4135 && !flag_pic
4136 #endif
4137 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
4138 The same goes for DImode without 64-bit gprs and DFmode and DDmode
4139 without fprs. */
4140 && mode != TFmode
4141 && mode != TDmode
4142 && (mode != DImode || TARGET_POWERPC64)
4143 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
4144 || (TARGET_FPRS && TARGET_HARD_FLOAT)))
4146 #if TARGET_MACHO
4147 if (flag_pic)
4149 rtx offset = gen_rtx_CONST (Pmode,
4150 gen_rtx_MINUS (Pmode, x,
4151 machopic_function_base_sym ()));
4152 x = gen_rtx_LO_SUM (GET_MODE (x),
4153 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
4154 gen_rtx_HIGH (Pmode, offset)), offset);
4156 else
4157 #endif
4158 x = gen_rtx_LO_SUM (GET_MODE (x),
4159 gen_rtx_HIGH (Pmode, x), x);
4161 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4162 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
4163 opnum, (enum reload_type)type);
4164 *win = 1;
4165 return x;
4168 /* Reload an offset address wrapped by an AND that represents the
4169 masking of the lower bits. Strip the outer AND and let reload
4170 convert the offset address into an indirect address. */
4171 if (TARGET_ALTIVEC
4172 && ALTIVEC_VECTOR_MODE (mode)
4173 && GET_CODE (x) == AND
4174 && GET_CODE (XEXP (x, 0)) == PLUS
4175 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
4176 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4177 && GET_CODE (XEXP (x, 1)) == CONST_INT
4178 && INTVAL (XEXP (x, 1)) == -16)
4180 x = XEXP (x, 0);
4181 *win = 1;
4182 return x;
4185 if (TARGET_TOC
4186 && constant_pool_expr_p (x)
4187 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
4189 x = create_TOC_reference (x);
4190 *win = 1;
4191 return x;
4193 *win = 0;
4194 return x;
4197 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
4198 that is a valid memory address for an instruction.
4199 The MODE argument is the machine mode for the MEM expression
4200 that wants to use this address.
4202 On the RS/6000, there are four valid address: a SYMBOL_REF that
4203 refers to a constant pool entry of an address (or the sum of it
4204 plus a constant), a short (16-bit signed) constant plus a register,
4205 the sum of two registers, or a register indirect, possibly with an
4206 auto-increment. For DFmode, DDmode and DImode with a constant plus
4207 register, we must ensure that both words are addressable or PowerPC64
4208 with offset word aligned.
4210 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
4211 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
4212 because adjacent memory cells are accessed by adding word-sized offsets
4213 during assembly output. */
4215 rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
4217 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
4218 if (TARGET_ALTIVEC
4219 && ALTIVEC_VECTOR_MODE (mode)
4220 && GET_CODE (x) == AND
4221 && GET_CODE (XEXP (x, 1)) == CONST_INT
4222 && INTVAL (XEXP (x, 1)) == -16)
4223 x = XEXP (x, 0);
4225 if (RS6000_SYMBOL_REF_TLS_P (x))
4226 return 0;
4227 if (legitimate_indirect_address_p (x, reg_ok_strict))
4228 return 1;
4229 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
4230 && !ALTIVEC_VECTOR_MODE (mode)
4231 && !SPE_VECTOR_MODE (mode)
4232 && mode != TFmode
4233 && mode != TDmode
4234 /* Restrict addressing for DI because of our SUBREG hackery. */
4235 && !(TARGET_E500_DOUBLE
4236 && (mode == DFmode || mode == DDmode || mode == DImode))
4237 && TARGET_UPDATE
4238 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
4239 return 1;
4240 if (legitimate_small_data_p (mode, x))
4241 return 1;
4242 if (legitimate_constant_pool_address_p (x))
4243 return 1;
4244 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
4245 if (! reg_ok_strict
4246 && GET_CODE (x) == PLUS
4247 && GET_CODE (XEXP (x, 0)) == REG
4248 && (XEXP (x, 0) == virtual_stack_vars_rtx
4249 || XEXP (x, 0) == arg_pointer_rtx)
4250 && GET_CODE (XEXP (x, 1)) == CONST_INT)
4251 return 1;
4252 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
4253 return 1;
4254 if (mode != TImode
4255 && mode != TFmode
4256 && mode != TDmode
4257 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
4258 || TARGET_POWERPC64
4259 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
4260 && (TARGET_POWERPC64 || mode != DImode)
4261 && legitimate_indexed_address_p (x, reg_ok_strict))
4262 return 1;
4263 if (GET_CODE (x) == PRE_MODIFY
4264 && mode != TImode
4265 && mode != TFmode
4266 && mode != TDmode
4267 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
4268 || TARGET_POWERPC64
4269 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
4270 && (TARGET_POWERPC64 || mode != DImode)
4271 && !ALTIVEC_VECTOR_MODE (mode)
4272 && !SPE_VECTOR_MODE (mode)
4273 /* Restrict addressing for DI because of our SUBREG hackery. */
4274 && !(TARGET_E500_DOUBLE
4275 && (mode == DFmode || mode == DDmode || mode == DImode))
4276 && TARGET_UPDATE
4277 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
4278 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
4279 || legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict))
4280 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
4281 return 1;
4282 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
4283 return 1;
4284 return 0;
4287 /* Go to LABEL if ADDR (a legitimate address expression)
4288 has an effect that depends on the machine mode it is used for.
4290 On the RS/6000 this is true of all integral offsets (since AltiVec
4291 modes don't allow them) or is a pre-increment or decrement.
4293 ??? Except that due to conceptual problems in offsettable_address_p
4294 we can't really report the problems of integral offsets. So leave
4295 this assuming that the adjustable offset must be valid for the
4296 sub-words of a TFmode operand, which is what we had before. */
4298 bool
4299 rs6000_mode_dependent_address (rtx addr)
4301 switch (GET_CODE (addr))
4303 case PLUS:
4304 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
4306 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
4307 return val + 12 + 0x8000 >= 0x10000;
4309 break;
4311 case LO_SUM:
4312 return true;
4314 case PRE_INC:
4315 case PRE_DEC:
4316 case PRE_MODIFY:
4317 return TARGET_UPDATE;
4319 default:
4320 break;
4323 return false;
4326 /* More elaborate version of recog's offsettable_memref_p predicate
4327 that works around the ??? note of rs6000_mode_dependent_address.
4328 In particular it accepts
4330 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
4332 in 32-bit mode, that the recog predicate rejects. */
4334 bool
4335 rs6000_offsettable_memref_p (rtx op)
4337 if (!MEM_P (op))
4338 return false;
4340 /* First mimic offsettable_memref_p. */
4341 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
4342 return true;
4344 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
4345 the latter predicate knows nothing about the mode of the memory
4346 reference and, therefore, assumes that it is the largest supported
4347 mode (TFmode). As a consequence, legitimate offsettable memory
4348 references are rejected. rs6000_legitimate_offset_address_p contains
4349 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
4350 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
4353 /* Return number of consecutive hard regs needed starting at reg REGNO
4354 to hold something of mode MODE.
4355 This is ordinarily the length in words of a value of mode MODE
4356 but can be less for certain modes in special long registers.
4358 For the SPE, GPRs are 64 bits but only 32 bits are visible in
4359 scalar instructions. The upper 32 bits are only available to the
4360 SIMD instructions.
4362 POWER and PowerPC GPRs hold 32 bits worth;
4363 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
4366 rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
4368 if (FP_REGNO_P (regno))
4369 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
4371 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
4372 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
4374 if (ALTIVEC_REGNO_P (regno))
4375 return
4376 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
4378 /* The value returned for SCmode in the E500 double case is 2 for
4379 ABI compatibility; storing an SCmode value in a single register
4380 would require function_arg and rs6000_spe_function_arg to handle
4381 SCmode so as to pass the value correctly in a pair of
4382 registers. */
4383 if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode)
4384 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
4386 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4389 /* Change register usage conditional on target flags. */
4390 void
4391 rs6000_conditional_register_usage (void)
4393 int i;
4395 /* Set MQ register fixed (already call_used) if not POWER
4396 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
4397 be allocated. */
4398 if (! TARGET_POWER)
4399 fixed_regs[64] = 1;
4401 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
4402 if (TARGET_64BIT)
4403 fixed_regs[13] = call_used_regs[13]
4404 = call_really_used_regs[13] = 1;
4406 /* Conditionally disable FPRs. */
4407 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
4408 for (i = 32; i < 64; i++)
4409 fixed_regs[i] = call_used_regs[i]
4410 = call_really_used_regs[i] = 1;
4412 /* The TOC register is not killed across calls in a way that is
4413 visible to the compiler. */
4414 if (DEFAULT_ABI == ABI_AIX)
4415 call_really_used_regs[2] = 0;
4417 if (DEFAULT_ABI == ABI_V4
4418 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
4419 && flag_pic == 2)
4420 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4422 if (DEFAULT_ABI == ABI_V4
4423 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
4424 && flag_pic == 1)
4425 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4426 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4427 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4429 if (DEFAULT_ABI == ABI_DARWIN
4430 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
4431 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4432 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4433 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4435 if (TARGET_TOC && TARGET_MINIMAL_TOC)
4436 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4437 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4439 if (TARGET_SPE)
4441 global_regs[SPEFSCR_REGNO] = 1;
4442 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
4443 registers in prologues and epilogues. We no longer use r14
4444 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
4445 pool for link-compatibility with older versions of GCC. Once
4446 "old" code has died out, we can return r14 to the allocation
4447 pool. */
4448 fixed_regs[14]
4449 = call_used_regs[14]
4450 = call_really_used_regs[14] = 1;
4453 if (!TARGET_ALTIVEC)
4455 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
4456 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
4457 call_really_used_regs[VRSAVE_REGNO] = 1;
4460 if (TARGET_ALTIVEC)
4461 global_regs[VSCR_REGNO] = 1;
4463 if (TARGET_ALTIVEC_ABI)
4465 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
4466 call_used_regs[i] = call_really_used_regs[i] = 1;
4468 /* AIX reserves VR20:31 in non-extended ABI mode. */
4469 if (TARGET_XCOFF)
4470 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
4471 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
4475 /* Try to output insns to set TARGET equal to the constant C if it can
4476 be done in less than N insns. Do all computations in MODE.
4477 Returns the place where the output has been placed if it can be
4478 done and the insns have been emitted. If it would take more than N
4479 insns, zero is returned and no insns and emitted. */
4482 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
4483 rtx source, int n ATTRIBUTE_UNUSED)
4485 rtx result, insn, set;
4486 HOST_WIDE_INT c0, c1;
4488 switch (mode)
4490 case QImode:
4491 case HImode:
4492 if (dest == NULL)
4493 dest = gen_reg_rtx (mode);
4494 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
4495 return dest;
4497 case SImode:
4498 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
4500 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
4501 GEN_INT (INTVAL (source)
4502 & (~ (HOST_WIDE_INT) 0xffff))));
4503 emit_insn (gen_rtx_SET (VOIDmode, dest,
4504 gen_rtx_IOR (SImode, copy_rtx (result),
4505 GEN_INT (INTVAL (source) & 0xffff))));
4506 result = dest;
4507 break;
4509 case DImode:
4510 switch (GET_CODE (source))
4512 case CONST_INT:
4513 c0 = INTVAL (source);
4514 c1 = -(c0 < 0);
4515 break;
4517 case CONST_DOUBLE:
4518 #if HOST_BITS_PER_WIDE_INT >= 64
4519 c0 = CONST_DOUBLE_LOW (source);
4520 c1 = -(c0 < 0);
4521 #else
4522 c0 = CONST_DOUBLE_LOW (source);
4523 c1 = CONST_DOUBLE_HIGH (source);
4524 #endif
4525 break;
4527 default:
4528 gcc_unreachable ();
4531 result = rs6000_emit_set_long_const (dest, c0, c1);
4532 break;
4534 default:
4535 gcc_unreachable ();
4538 insn = get_last_insn ();
4539 set = single_set (insn);
4540 if (! CONSTANT_P (SET_SRC (set)))
4541 set_unique_reg_note (insn, REG_EQUAL, source);
4543 return result;
4546 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4547 fall back to a straight forward decomposition. We do this to avoid
4548 exponential run times encountered when looking for longer sequences
4549 with rs6000_emit_set_const. */
4550 static rtx
4551 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
4553 if (!TARGET_POWERPC64)
4555 rtx operand1, operand2;
4557 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
4558 DImode);
4559 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
4560 DImode);
4561 emit_move_insn (operand1, GEN_INT (c1));
4562 emit_move_insn (operand2, GEN_INT (c2));
4564 else
4566 HOST_WIDE_INT ud1, ud2, ud3, ud4;
4568 ud1 = c1 & 0xffff;
4569 ud2 = (c1 & 0xffff0000) >> 16;
4570 #if HOST_BITS_PER_WIDE_INT >= 64
4571 c2 = c1 >> 32;
4572 #endif
4573 ud3 = c2 & 0xffff;
4574 ud4 = (c2 & 0xffff0000) >> 16;
4576 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
4577 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
4579 if (ud1 & 0x8000)
4580 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
4581 else
4582 emit_move_insn (dest, GEN_INT (ud1));
4585 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
4586 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
4588 if (ud2 & 0x8000)
4589 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
4590 - 0x80000000));
4591 else
4592 emit_move_insn (dest, GEN_INT (ud2 << 16));
4593 if (ud1 != 0)
4594 emit_move_insn (copy_rtx (dest),
4595 gen_rtx_IOR (DImode, copy_rtx (dest),
4596 GEN_INT (ud1)));
4598 else if ((ud4 == 0xffff && (ud3 & 0x8000))
4599 || (ud4 == 0 && ! (ud3 & 0x8000)))
4601 if (ud3 & 0x8000)
4602 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
4603 - 0x80000000));
4604 else
4605 emit_move_insn (dest, GEN_INT (ud3 << 16));
4607 if (ud2 != 0)
4608 emit_move_insn (copy_rtx (dest),
4609 gen_rtx_IOR (DImode, copy_rtx (dest),
4610 GEN_INT (ud2)));
4611 emit_move_insn (copy_rtx (dest),
4612 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4613 GEN_INT (16)));
4614 if (ud1 != 0)
4615 emit_move_insn (copy_rtx (dest),
4616 gen_rtx_IOR (DImode, copy_rtx (dest),
4617 GEN_INT (ud1)));
4619 else
4621 if (ud4 & 0x8000)
4622 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
4623 - 0x80000000));
4624 else
4625 emit_move_insn (dest, GEN_INT (ud4 << 16));
4627 if (ud3 != 0)
4628 emit_move_insn (copy_rtx (dest),
4629 gen_rtx_IOR (DImode, copy_rtx (dest),
4630 GEN_INT (ud3)));
4632 emit_move_insn (copy_rtx (dest),
4633 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4634 GEN_INT (32)));
4635 if (ud2 != 0)
4636 emit_move_insn (copy_rtx (dest),
4637 gen_rtx_IOR (DImode, copy_rtx (dest),
4638 GEN_INT (ud2 << 16)));
4639 if (ud1 != 0)
4640 emit_move_insn (copy_rtx (dest),
4641 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
4644 return dest;
4647 /* Helper for the following. Get rid of [r+r] memory refs
4648 in cases where it won't work (TImode, TFmode, TDmode). */
4650 static void
4651 rs6000_eliminate_indexed_memrefs (rtx operands[2])
4653 if (GET_CODE (operands[0]) == MEM
4654 && GET_CODE (XEXP (operands[0], 0)) != REG
4655 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
4656 && ! reload_in_progress)
4657 operands[0]
4658 = replace_equiv_address (operands[0],
4659 copy_addr_to_reg (XEXP (operands[0], 0)));
4661 if (GET_CODE (operands[1]) == MEM
4662 && GET_CODE (XEXP (operands[1], 0)) != REG
4663 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
4664 && ! reload_in_progress)
4665 operands[1]
4666 = replace_equiv_address (operands[1],
4667 copy_addr_to_reg (XEXP (operands[1], 0)));
4670 /* Emit a move from SOURCE to DEST in mode MODE. */
4671 void
4672 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
4674 rtx operands[2];
4675 operands[0] = dest;
4676 operands[1] = source;
4678 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4679 if (GET_CODE (operands[1]) == CONST_DOUBLE
4680 && ! FLOAT_MODE_P (mode)
4681 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
4683 /* FIXME. This should never happen. */
4684 /* Since it seems that it does, do the safe thing and convert
4685 to a CONST_INT. */
4686 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
4688 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
4689 || FLOAT_MODE_P (mode)
4690 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
4691 || CONST_DOUBLE_LOW (operands[1]) < 0)
4692 && (CONST_DOUBLE_HIGH (operands[1]) != -1
4693 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
4695 /* Check if GCC is setting up a block move that will end up using FP
4696 registers as temporaries. We must make sure this is acceptable. */
4697 if (GET_CODE (operands[0]) == MEM
4698 && GET_CODE (operands[1]) == MEM
4699 && mode == DImode
4700 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
4701 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
4702 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
4703 ? 32 : MEM_ALIGN (operands[0])))
4704 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
4705 ? 32
4706 : MEM_ALIGN (operands[1]))))
4707 && ! MEM_VOLATILE_P (operands [0])
4708 && ! MEM_VOLATILE_P (operands [1]))
4710 emit_move_insn (adjust_address (operands[0], SImode, 0),
4711 adjust_address (operands[1], SImode, 0));
4712 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
4713 adjust_address (copy_rtx (operands[1]), SImode, 4));
4714 return;
4717 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
4718 && !gpc_reg_operand (operands[1], mode))
4719 operands[1] = force_reg (mode, operands[1]);
4721 if (mode == SFmode && ! TARGET_POWERPC
4722 && TARGET_HARD_FLOAT && TARGET_FPRS
4723 && GET_CODE (operands[0]) == MEM)
4725 int regnum;
4727 if (reload_in_progress || reload_completed)
4728 regnum = true_regnum (operands[1]);
4729 else if (GET_CODE (operands[1]) == REG)
4730 regnum = REGNO (operands[1]);
4731 else
4732 regnum = -1;
4734 /* If operands[1] is a register, on POWER it may have
4735 double-precision data in it, so truncate it to single
4736 precision. */
4737 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
4739 rtx newreg;
4740 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
4741 : gen_reg_rtx (mode));
4742 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
4743 operands[1] = newreg;
4747 /* Recognize the case where operand[1] is a reference to thread-local
4748 data and load its address to a register. */
4749 if (rs6000_tls_referenced_p (operands[1]))
4751 enum tls_model model;
4752 rtx tmp = operands[1];
4753 rtx addend = NULL;
4755 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
4757 addend = XEXP (XEXP (tmp, 0), 1);
4758 tmp = XEXP (XEXP (tmp, 0), 0);
4761 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
4762 model = SYMBOL_REF_TLS_MODEL (tmp);
4763 gcc_assert (model != 0);
4765 tmp = rs6000_legitimize_tls_address (tmp, model);
4766 if (addend)
4768 tmp = gen_rtx_PLUS (mode, tmp, addend);
4769 tmp = force_operand (tmp, operands[0]);
4771 operands[1] = tmp;
4774 /* Handle the case where reload calls us with an invalid address. */
4775 if (reload_in_progress && mode == Pmode
4776 && (! general_operand (operands[1], mode)
4777 || ! nonimmediate_operand (operands[0], mode)))
4778 goto emit_set;
4780 /* 128-bit constant floating-point values on Darwin should really be
4781 loaded as two parts. */
4782 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
4783 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
4785 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4786 know how to get a DFmode SUBREG of a TFmode. */
4787 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
4788 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
4789 simplify_gen_subreg (imode, operands[1], mode, 0),
4790 imode);
4791 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
4792 GET_MODE_SIZE (imode)),
4793 simplify_gen_subreg (imode, operands[1], mode,
4794 GET_MODE_SIZE (imode)),
4795 imode);
4796 return;
4799 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
4800 cfun->machine->sdmode_stack_slot =
4801 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
4803 if (reload_in_progress
4804 && mode == SDmode
4805 && MEM_P (operands[0])
4806 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
4807 && REG_P (operands[1]))
4809 if (FP_REGNO_P (REGNO (operands[1])))
4811 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
4812 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
4813 emit_insn (gen_movsd_store (mem, operands[1]));
4815 else if (INT_REGNO_P (REGNO (operands[1])))
4817 rtx mem = adjust_address_nv (operands[0], mode, 4);
4818 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
4819 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
4821 else
4822 gcc_unreachable();
4823 return;
4825 if (reload_in_progress
4826 && mode == SDmode
4827 && REG_P (operands[0])
4828 && MEM_P (operands[1])
4829 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
4831 if (FP_REGNO_P (REGNO (operands[0])))
4833 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
4834 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
4835 emit_insn (gen_movsd_load (operands[0], mem));
4837 else if (INT_REGNO_P (REGNO (operands[0])))
4839 rtx mem = adjust_address_nv (operands[1], mode, 4);
4840 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
4841 emit_insn (gen_movsd_hardfloat (operands[0], mem));
4843 else
4844 gcc_unreachable();
4845 return;
4848 /* FIXME: In the long term, this switch statement should go away
4849 and be replaced by a sequence of tests based on things like
4850 mode == Pmode. */
4851 switch (mode)
4853 case HImode:
4854 case QImode:
4855 if (CONSTANT_P (operands[1])
4856 && GET_CODE (operands[1]) != CONST_INT)
4857 operands[1] = force_const_mem (mode, operands[1]);
4858 break;
4860 case TFmode:
4861 case TDmode:
4862 rs6000_eliminate_indexed_memrefs (operands);
4863 /* fall through */
4865 case DFmode:
4866 case DDmode:
4867 case SFmode:
4868 case SDmode:
4869 if (CONSTANT_P (operands[1])
4870 && ! easy_fp_constant (operands[1], mode))
4871 operands[1] = force_const_mem (mode, operands[1]);
4872 break;
4874 case V16QImode:
4875 case V8HImode:
4876 case V4SFmode:
4877 case V4SImode:
4878 case V4HImode:
4879 case V2SFmode:
4880 case V2SImode:
4881 case V1DImode:
4882 if (CONSTANT_P (operands[1])
4883 && !easy_vector_constant (operands[1], mode))
4884 operands[1] = force_const_mem (mode, operands[1]);
4885 break;
4887 case SImode:
4888 case DImode:
4889 /* Use default pattern for address of ELF small data */
4890 if (TARGET_ELF
4891 && mode == Pmode
4892 && DEFAULT_ABI == ABI_V4
4893 && (GET_CODE (operands[1]) == SYMBOL_REF
4894 || GET_CODE (operands[1]) == CONST)
4895 && small_data_operand (operands[1], mode))
4897 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4898 return;
4901 if (DEFAULT_ABI == ABI_V4
4902 && mode == Pmode && mode == SImode
4903 && flag_pic == 1 && got_operand (operands[1], mode))
4905 emit_insn (gen_movsi_got (operands[0], operands[1]));
4906 return;
4909 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
4910 && TARGET_NO_TOC
4911 && ! flag_pic
4912 && mode == Pmode
4913 && CONSTANT_P (operands[1])
4914 && GET_CODE (operands[1]) != HIGH
4915 && GET_CODE (operands[1]) != CONST_INT)
4917 rtx target = (!can_create_pseudo_p ()
4918 ? operands[0]
4919 : gen_reg_rtx (mode));
4921 /* If this is a function address on -mcall-aixdesc,
4922 convert it to the address of the descriptor. */
4923 if (DEFAULT_ABI == ABI_AIX
4924 && GET_CODE (operands[1]) == SYMBOL_REF
4925 && XSTR (operands[1], 0)[0] == '.')
4927 const char *name = XSTR (operands[1], 0);
4928 rtx new_ref;
4929 while (*name == '.')
4930 name++;
4931 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
4932 CONSTANT_POOL_ADDRESS_P (new_ref)
4933 = CONSTANT_POOL_ADDRESS_P (operands[1]);
4934 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
4935 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4936 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
4937 operands[1] = new_ref;
4940 if (DEFAULT_ABI == ABI_DARWIN)
4942 #if TARGET_MACHO
4943 if (MACHO_DYNAMIC_NO_PIC_P)
4945 /* Take care of any required data indirection. */
4946 operands[1] = rs6000_machopic_legitimize_pic_address (
4947 operands[1], mode, operands[0]);
4948 if (operands[0] != operands[1])
4949 emit_insn (gen_rtx_SET (VOIDmode,
4950 operands[0], operands[1]));
4951 return;
4953 #endif
4954 emit_insn (gen_macho_high (target, operands[1]));
4955 emit_insn (gen_macho_low (operands[0], target, operands[1]));
4956 return;
4959 emit_insn (gen_elf_high (target, operands[1]));
4960 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4961 return;
4964 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4965 and we have put it in the TOC, we just need to make a TOC-relative
4966 reference to it. */
4967 if (TARGET_TOC
4968 && GET_CODE (operands[1]) == SYMBOL_REF
4969 && constant_pool_expr_p (operands[1])
4970 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
4971 get_pool_mode (operands[1])))
4973 operands[1] = create_TOC_reference (operands[1]);
4975 else if (mode == Pmode
4976 && CONSTANT_P (operands[1])
4977 && ((GET_CODE (operands[1]) != CONST_INT
4978 && ! easy_fp_constant (operands[1], mode))
4979 || (GET_CODE (operands[1]) == CONST_INT
4980 && num_insns_constant (operands[1], mode) > 2)
4981 || (GET_CODE (operands[0]) == REG
4982 && FP_REGNO_P (REGNO (operands[0]))))
4983 && GET_CODE (operands[1]) != HIGH
4984 && ! legitimate_constant_pool_address_p (operands[1])
4985 && ! toc_relative_expr_p (operands[1]))
4987 /* Emit a USE operation so that the constant isn't deleted if
4988 expensive optimizations are turned on because nobody
4989 references it. This should only be done for operands that
4990 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4991 This should not be done for operands that contain LABEL_REFs.
4992 For now, we just handle the obvious case. */
4993 if (GET_CODE (operands[1]) != LABEL_REF)
4994 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
4996 #if TARGET_MACHO
4997 /* Darwin uses a special PIC legitimizer. */
4998 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
5000 operands[1] =
5001 rs6000_machopic_legitimize_pic_address (operands[1], mode,
5002 operands[0]);
5003 if (operands[0] != operands[1])
5004 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
5005 return;
5007 #endif
5009 /* If we are to limit the number of things we put in the TOC and
5010 this is a symbol plus a constant we can add in one insn,
5011 just put the symbol in the TOC and add the constant. Don't do
5012 this if reload is in progress. */
5013 if (GET_CODE (operands[1]) == CONST
5014 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
5015 && GET_CODE (XEXP (operands[1], 0)) == PLUS
5016 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
5017 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
5018 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
5019 && ! side_effects_p (operands[0]))
5021 rtx sym =
5022 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
5023 rtx other = XEXP (XEXP (operands[1], 0), 1);
5025 sym = force_reg (mode, sym);
5026 if (mode == SImode)
5027 emit_insn (gen_addsi3 (operands[0], sym, other));
5028 else
5029 emit_insn (gen_adddi3 (operands[0], sym, other));
5030 return;
5033 operands[1] = force_const_mem (mode, operands[1]);
5035 if (TARGET_TOC
5036 && constant_pool_expr_p (XEXP (operands[1], 0))
5037 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
5038 get_pool_constant (XEXP (operands[1], 0)),
5039 get_pool_mode (XEXP (operands[1], 0))))
5041 operands[1]
5042 = gen_const_mem (mode,
5043 create_TOC_reference (XEXP (operands[1], 0)));
5044 set_mem_alias_set (operands[1], get_TOC_alias_set ());
5047 break;
5049 case TImode:
5050 rs6000_eliminate_indexed_memrefs (operands);
5052 if (TARGET_POWER)
5054 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5055 gen_rtvec (2,
5056 gen_rtx_SET (VOIDmode,
5057 operands[0], operands[1]),
5058 gen_rtx_CLOBBER (VOIDmode,
5059 gen_rtx_SCRATCH (SImode)))));
5060 return;
5062 break;
5064 default:
5065 gcc_unreachable ();
5068 /* Above, we may have called force_const_mem which may have returned
5069 an invalid address. If we can, fix this up; otherwise, reload will
5070 have to deal with it. */
5071 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
5072 operands[1] = validize_mem (operands[1]);
5074 emit_set:
5075 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
5078 /* Nonzero if we can use a floating-point register to pass this arg. */
5079 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
5080 (SCALAR_FLOAT_MODE_P (MODE) \
5081 && (CUM)->fregno <= FP_ARG_MAX_REG \
5082 && TARGET_HARD_FLOAT && TARGET_FPRS)
5084 /* Nonzero if we can use an AltiVec register to pass this arg. */
5085 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
5086 (ALTIVEC_VECTOR_MODE (MODE) \
5087 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
5088 && TARGET_ALTIVEC_ABI \
5089 && (NAMED))
5091 /* Return a nonzero value to say to return the function value in
5092 memory, just as large structures are always returned. TYPE will be
5093 the data type of the value, and FNTYPE will be the type of the
5094 function doing the returning, or @code{NULL} for libcalls.
5096 The AIX ABI for the RS/6000 specifies that all structures are
5097 returned in memory. The Darwin ABI does the same. The SVR4 ABI
5098 specifies that structures <= 8 bytes are returned in r3/r4, but a
5099 draft put them in memory, and GCC used to implement the draft
5100 instead of the final standard. Therefore, aix_struct_return
5101 controls this instead of DEFAULT_ABI; V.4 targets needing backward
5102 compatibility can change DRAFT_V4_STRUCT_RET to override the
5103 default, and -m switches get the final word. See
5104 rs6000_override_options for more details.
5106 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
5107 long double support is enabled. These values are returned in memory.
5109 int_size_in_bytes returns -1 for variable size objects, which go in
5110 memory always. The cast to unsigned makes -1 > 8. */
5112 static bool
5113 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
5115 /* In the darwin64 abi, try to use registers for larger structs
5116 if possible. */
5117 if (rs6000_darwin64_abi
5118 && TREE_CODE (type) == RECORD_TYPE
5119 && int_size_in_bytes (type) > 0)
5121 CUMULATIVE_ARGS valcum;
5122 rtx valret;
5124 valcum.words = 0;
5125 valcum.fregno = FP_ARG_MIN_REG;
5126 valcum.vregno = ALTIVEC_ARG_MIN_REG;
5127 /* Do a trial code generation as if this were going to be passed
5128 as an argument; if any part goes in memory, we return NULL. */
5129 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
5130 if (valret)
5131 return false;
5132 /* Otherwise fall through to more conventional ABI rules. */
5135 if (AGGREGATE_TYPE_P (type)
5136 && (aix_struct_return
5137 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
5138 return true;
5140 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5141 modes only exist for GCC vector types if -maltivec. */
5142 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
5143 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
5144 return false;
5146 /* Return synthetic vectors in memory. */
5147 if (TREE_CODE (type) == VECTOR_TYPE
5148 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
5150 static bool warned_for_return_big_vectors = false;
5151 if (!warned_for_return_big_vectors)
5153 warning (0, "GCC vector returned by reference: "
5154 "non-standard ABI extension with no compatibility guarantee");
5155 warned_for_return_big_vectors = true;
5157 return true;
5160 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
5161 return true;
5163 return false;
5166 /* Initialize a variable CUM of type CUMULATIVE_ARGS
5167 for a call to a function whose data type is FNTYPE.
5168 For a library call, FNTYPE is 0.
5170 For incoming args we set the number of arguments in the prototype large
5171 so we never return a PARALLEL. */
5173 void
5174 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
5175 rtx libname ATTRIBUTE_UNUSED, int incoming,
5176 int libcall, int n_named_args)
5178 static CUMULATIVE_ARGS zero_cumulative;
5180 *cum = zero_cumulative;
5181 cum->words = 0;
5182 cum->fregno = FP_ARG_MIN_REG;
5183 cum->vregno = ALTIVEC_ARG_MIN_REG;
5184 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
5185 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
5186 ? CALL_LIBCALL : CALL_NORMAL);
5187 cum->sysv_gregno = GP_ARG_MIN_REG;
5188 cum->stdarg = fntype
5189 && (TYPE_ARG_TYPES (fntype) != 0
5190 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
5191 != void_type_node));
5193 cum->nargs_prototype = 0;
5194 if (incoming || cum->prototype)
5195 cum->nargs_prototype = n_named_args;
5197 /* Check for a longcall attribute. */
5198 if ((!fntype && rs6000_default_long_calls)
5199 || (fntype
5200 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
5201 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
5202 cum->call_cookie |= CALL_LONG;
5204 if (TARGET_DEBUG_ARG)
5206 fprintf (stderr, "\ninit_cumulative_args:");
5207 if (fntype)
5209 tree ret_type = TREE_TYPE (fntype);
5210 fprintf (stderr, " ret code = %s,",
5211 tree_code_name[ (int)TREE_CODE (ret_type) ]);
5214 if (cum->call_cookie & CALL_LONG)
5215 fprintf (stderr, " longcall,");
5217 fprintf (stderr, " proto = %d, nargs = %d\n",
5218 cum->prototype, cum->nargs_prototype);
5221 if (fntype
5222 && !TARGET_ALTIVEC
5223 && TARGET_ALTIVEC_ABI
5224 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
5226 error ("cannot return value in vector register because"
5227 " altivec instructions are disabled, use -maltivec"
5228 " to enable them");
5232 /* Return true if TYPE must be passed on the stack and not in registers. */
5234 static bool
5235 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
5237 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
5238 return must_pass_in_stack_var_size (mode, type);
5239 else
5240 return must_pass_in_stack_var_size_or_pad (mode, type);
5243 /* If defined, a C expression which determines whether, and in which
5244 direction, to pad out an argument with extra space. The value
5245 should be of type `enum direction': either `upward' to pad above
5246 the argument, `downward' to pad below, or `none' to inhibit
5247 padding.
5249 For the AIX ABI structs are always stored left shifted in their
5250 argument slot. */
5252 enum direction
5253 function_arg_padding (enum machine_mode mode, const_tree type)
5255 #ifndef AGGREGATE_PADDING_FIXED
5256 #define AGGREGATE_PADDING_FIXED 0
5257 #endif
5258 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
5259 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
5260 #endif
5262 if (!AGGREGATE_PADDING_FIXED)
5264 /* GCC used to pass structures of the same size as integer types as
5265 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
5266 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
5267 passed padded downward, except that -mstrict-align further
5268 muddied the water in that multi-component structures of 2 and 4
5269 bytes in size were passed padded upward.
5271 The following arranges for best compatibility with previous
5272 versions of gcc, but removes the -mstrict-align dependency. */
5273 if (BYTES_BIG_ENDIAN)
5275 HOST_WIDE_INT size = 0;
5277 if (mode == BLKmode)
5279 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
5280 size = int_size_in_bytes (type);
5282 else
5283 size = GET_MODE_SIZE (mode);
5285 if (size == 1 || size == 2 || size == 4)
5286 return downward;
5288 return upward;
5291 if (AGGREGATES_PAD_UPWARD_ALWAYS)
5293 if (type != 0 && AGGREGATE_TYPE_P (type))
5294 return upward;
5297 /* Fall back to the default. */
5298 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
5301 /* If defined, a C expression that gives the alignment boundary, in bits,
5302 of an argument with the specified mode and type. If it is not defined,
5303 PARM_BOUNDARY is used for all arguments.
5305 V.4 wants long longs and doubles to be double word aligned. Just
5306 testing the mode size is a boneheaded way to do this as it means
5307 that other types such as complex int are also double word aligned.
5308 However, we're stuck with this because changing the ABI might break
5309 existing library interfaces.
5311 Doubleword align SPE vectors.
5312 Quadword align Altivec vectors.
5313 Quadword align large synthetic vector types. */
5316 function_arg_boundary (enum machine_mode mode, tree type)
5318 if (DEFAULT_ABI == ABI_V4
5319 && (GET_MODE_SIZE (mode) == 8
5320 || (TARGET_HARD_FLOAT
5321 && TARGET_FPRS
5322 && (mode == TFmode || mode == TDmode))))
5323 return 64;
5324 else if (SPE_VECTOR_MODE (mode)
5325 || (type && TREE_CODE (type) == VECTOR_TYPE
5326 && int_size_in_bytes (type) >= 8
5327 && int_size_in_bytes (type) < 16))
5328 return 64;
5329 else if (ALTIVEC_VECTOR_MODE (mode)
5330 || (type && TREE_CODE (type) == VECTOR_TYPE
5331 && int_size_in_bytes (type) >= 16))
5332 return 128;
5333 else if (rs6000_darwin64_abi && mode == BLKmode
5334 && type && TYPE_ALIGN (type) > 64)
5335 return 128;
5336 else
5337 return PARM_BOUNDARY;
5340 /* For a function parm of MODE and TYPE, return the starting word in
5341 the parameter area. NWORDS of the parameter area are already used. */
5343 static unsigned int
5344 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
5346 unsigned int align;
5347 unsigned int parm_offset;
5349 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
5350 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
5351 return nwords + (-(parm_offset + nwords) & align);
5354 /* Compute the size (in words) of a function argument. */
5356 static unsigned long
5357 rs6000_arg_size (enum machine_mode mode, tree type)
5359 unsigned long size;
5361 if (mode != BLKmode)
5362 size = GET_MODE_SIZE (mode);
5363 else
5364 size = int_size_in_bytes (type);
5366 if (TARGET_32BIT)
5367 return (size + 3) >> 2;
5368 else
5369 return (size + 7) >> 3;
5372 /* Use this to flush pending int fields. */
5374 static void
5375 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
5376 HOST_WIDE_INT bitpos)
5378 unsigned int startbit, endbit;
5379 int intregs, intoffset;
5380 enum machine_mode mode;
5382 if (cum->intoffset == -1)
5383 return;
5385 intoffset = cum->intoffset;
5386 cum->intoffset = -1;
5388 if (intoffset % BITS_PER_WORD != 0)
5390 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5391 MODE_INT, 0);
5392 if (mode == BLKmode)
5394 /* We couldn't find an appropriate mode, which happens,
5395 e.g., in packed structs when there are 3 bytes to load.
5396 Back intoffset back to the beginning of the word in this
5397 case. */
5398 intoffset = intoffset & -BITS_PER_WORD;
5402 startbit = intoffset & -BITS_PER_WORD;
5403 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5404 intregs = (endbit - startbit) / BITS_PER_WORD;
5405 cum->words += intregs;
5408 /* The darwin64 ABI calls for us to recurse down through structs,
5409 looking for elements passed in registers. Unfortunately, we have
5410 to track int register count here also because of misalignments
5411 in powerpc alignment mode. */
5413 static void
5414 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
5415 tree type,
5416 HOST_WIDE_INT startbitpos)
5418 tree f;
5420 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5421 if (TREE_CODE (f) == FIELD_DECL)
5423 HOST_WIDE_INT bitpos = startbitpos;
5424 tree ftype = TREE_TYPE (f);
5425 enum machine_mode mode;
5426 if (ftype == error_mark_node)
5427 continue;
5428 mode = TYPE_MODE (ftype);
5430 if (DECL_SIZE (f) != 0
5431 && host_integerp (bit_position (f), 1))
5432 bitpos += int_bit_position (f);
5434 /* ??? FIXME: else assume zero offset. */
5436 if (TREE_CODE (ftype) == RECORD_TYPE)
5437 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
5438 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
5440 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
5441 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5442 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
5444 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
5446 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
5447 cum->vregno++;
5448 cum->words += 2;
5450 else if (cum->intoffset == -1)
5451 cum->intoffset = bitpos;
5455 /* Update the data in CUM to advance over an argument
5456 of mode MODE and data type TYPE.
5457 (TYPE is null for libcalls where that information may not be available.)
5459 Note that for args passed by reference, function_arg will be called
5460 with MODE and TYPE set to that of the pointer to the arg, not the arg
5461 itself. */
5463 void
5464 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5465 tree type, int named, int depth)
5467 int size;
5469 /* Only tick off an argument if we're not recursing. */
5470 if (depth == 0)
5471 cum->nargs_prototype--;
5473 if (TARGET_ALTIVEC_ABI
5474 && (ALTIVEC_VECTOR_MODE (mode)
5475 || (type && TREE_CODE (type) == VECTOR_TYPE
5476 && int_size_in_bytes (type) == 16)))
5478 bool stack = false;
5480 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
5482 cum->vregno++;
5483 if (!TARGET_ALTIVEC)
5484 error ("cannot pass argument in vector register because"
5485 " altivec instructions are disabled, use -maltivec"
5486 " to enable them");
5488 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
5489 even if it is going to be passed in a vector register.
5490 Darwin does the same for variable-argument functions. */
5491 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5492 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
5493 stack = true;
5495 else
5496 stack = true;
5498 if (stack)
5500 int align;
5502 /* Vector parameters must be 16-byte aligned. This places
5503 them at 2 mod 4 in terms of words in 32-bit mode, since
5504 the parameter save area starts at offset 24 from the
5505 stack. In 64-bit mode, they just have to start on an
5506 even word, since the parameter save area is 16-byte
5507 aligned. Space for GPRs is reserved even if the argument
5508 will be passed in memory. */
5509 if (TARGET_32BIT)
5510 align = (2 - cum->words) & 3;
5511 else
5512 align = cum->words & 1;
5513 cum->words += align + rs6000_arg_size (mode, type);
5515 if (TARGET_DEBUG_ARG)
5517 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
5518 cum->words, align);
5519 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
5520 cum->nargs_prototype, cum->prototype,
5521 GET_MODE_NAME (mode));
5525 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
5526 && !cum->stdarg
5527 && cum->sysv_gregno <= GP_ARG_MAX_REG)
5528 cum->sysv_gregno++;
5530 else if (rs6000_darwin64_abi
5531 && mode == BLKmode
5532 && TREE_CODE (type) == RECORD_TYPE
5533 && (size = int_size_in_bytes (type)) > 0)
5535 /* Variable sized types have size == -1 and are
5536 treated as if consisting entirely of ints.
5537 Pad to 16 byte boundary if needed. */
5538 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5539 && (cum->words % 2) != 0)
5540 cum->words++;
5541 /* For varargs, we can just go up by the size of the struct. */
5542 if (!named)
5543 cum->words += (size + 7) / 8;
5544 else
5546 /* It is tempting to say int register count just goes up by
5547 sizeof(type)/8, but this is wrong in a case such as
5548 { int; double; int; } [powerpc alignment]. We have to
5549 grovel through the fields for these too. */
5550 cum->intoffset = 0;
5551 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
5552 rs6000_darwin64_record_arg_advance_flush (cum,
5553 size * BITS_PER_UNIT);
5556 else if (DEFAULT_ABI == ABI_V4)
5558 if (TARGET_HARD_FLOAT && TARGET_FPRS
5559 && (mode == SFmode || mode == DFmode
5560 || mode == SDmode || mode == DDmode || mode == TDmode
5561 || (mode == TFmode && !TARGET_IEEEQUAD)))
5563 /* _Decimal128 must use an even/odd register pair. This assumes
5564 that the register number is odd when fregno is odd. */
5565 if (mode == TDmode && (cum->fregno % 2) == 1)
5566 cum->fregno++;
5568 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
5569 <= FP_ARG_V4_MAX_REG)
5570 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5571 else
5573 cum->fregno = FP_ARG_V4_MAX_REG + 1;
5574 if (mode == DFmode || mode == TFmode
5575 || mode == DDmode || mode == TDmode)
5576 cum->words += cum->words & 1;
5577 cum->words += rs6000_arg_size (mode, type);
5580 else
5582 int n_words = rs6000_arg_size (mode, type);
5583 int gregno = cum->sysv_gregno;
5585 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5586 (r7,r8) or (r9,r10). As does any other 2 word item such
5587 as complex int due to a historical mistake. */
5588 if (n_words == 2)
5589 gregno += (1 - gregno) & 1;
5591 /* Multi-reg args are not split between registers and stack. */
5592 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5594 /* Long long and SPE vectors are aligned on the stack.
5595 So are other 2 word items such as complex int due to
5596 a historical mistake. */
5597 if (n_words == 2)
5598 cum->words += cum->words & 1;
5599 cum->words += n_words;
5602 /* Note: continuing to accumulate gregno past when we've started
5603 spilling to the stack indicates the fact that we've started
5604 spilling to the stack to expand_builtin_saveregs. */
5605 cum->sysv_gregno = gregno + n_words;
5608 if (TARGET_DEBUG_ARG)
5610 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5611 cum->words, cum->fregno);
5612 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
5613 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
5614 fprintf (stderr, "mode = %4s, named = %d\n",
5615 GET_MODE_NAME (mode), named);
5618 else
5620 int n_words = rs6000_arg_size (mode, type);
5621 int start_words = cum->words;
5622 int align_words = rs6000_parm_start (mode, type, start_words);
5624 cum->words = align_words + n_words;
5626 if (SCALAR_FLOAT_MODE_P (mode)
5627 && TARGET_HARD_FLOAT && TARGET_FPRS)
5629 /* _Decimal128 must be passed in an even/odd float register pair.
5630 This assumes that the register number is odd when fregno is
5631 odd. */
5632 if (mode == TDmode && (cum->fregno % 2) == 1)
5633 cum->fregno++;
5634 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5637 if (TARGET_DEBUG_ARG)
5639 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5640 cum->words, cum->fregno);
5641 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
5642 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
5643 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
5644 named, align_words - start_words, depth);
5649 static rtx
5650 spe_build_register_parallel (enum machine_mode mode, int gregno)
5652 rtx r1, r3, r5, r7;
5654 switch (mode)
5656 case DFmode:
5657 case DDmode:
5658 r1 = gen_rtx_REG (DImode, gregno);
5659 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5660 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
5662 case DCmode:
5663 case TFmode:
5664 case TDmode:
5665 r1 = gen_rtx_REG (DImode, gregno);
5666 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5667 r3 = gen_rtx_REG (DImode, gregno + 2);
5668 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5669 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
5671 case TCmode:
5672 r1 = gen_rtx_REG (DImode, gregno);
5673 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5674 r3 = gen_rtx_REG (DImode, gregno + 2);
5675 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5676 r5 = gen_rtx_REG (DImode, gregno + 4);
5677 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
5678 r7 = gen_rtx_REG (DImode, gregno + 6);
5679 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
5680 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
5682 default:
5683 gcc_unreachable ();
5687 /* Determine where to put a SIMD argument on the SPE. */
5688 static rtx
5689 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5690 tree type)
5692 int gregno = cum->sysv_gregno;
5694 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5695 are passed and returned in a pair of GPRs for ABI compatibility. */
5696 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5697 || mode == DDmode || mode == TDmode
5698 || mode == DCmode || mode == TCmode))
5700 int n_words = rs6000_arg_size (mode, type);
5702 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5703 if (mode == DFmode || mode == DDmode)
5704 gregno += (1 - gregno) & 1;
5706 /* Multi-reg args are not split between registers and stack. */
5707 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5708 return NULL_RTX;
5710 return spe_build_register_parallel (mode, gregno);
5712 if (cum->stdarg)
5714 int n_words = rs6000_arg_size (mode, type);
5716 /* SPE vectors are put in odd registers. */
5717 if (n_words == 2 && (gregno & 1) == 0)
5718 gregno += 1;
5720 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
5722 rtx r1, r2;
5723 enum machine_mode m = SImode;
5725 r1 = gen_rtx_REG (m, gregno);
5726 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
5727 r2 = gen_rtx_REG (m, gregno + 1);
5728 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
5729 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
5731 else
5732 return NULL_RTX;
5734 else
5736 if (gregno <= GP_ARG_MAX_REG)
5737 return gen_rtx_REG (mode, gregno);
5738 else
5739 return NULL_RTX;
5743 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5744 structure between cum->intoffset and bitpos to integer registers. */
5746 static void
5747 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
5748 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
5750 enum machine_mode mode;
5751 unsigned int regno;
5752 unsigned int startbit, endbit;
5753 int this_regno, intregs, intoffset;
5754 rtx reg;
5756 if (cum->intoffset == -1)
5757 return;
5759 intoffset = cum->intoffset;
5760 cum->intoffset = -1;
5762 /* If this is the trailing part of a word, try to only load that
5763 much into the register. Otherwise load the whole register. Note
5764 that in the latter case we may pick up unwanted bits. It's not a
5765 problem at the moment but may wish to revisit. */
5767 if (intoffset % BITS_PER_WORD != 0)
5769 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5770 MODE_INT, 0);
5771 if (mode == BLKmode)
5773 /* We couldn't find an appropriate mode, which happens,
5774 e.g., in packed structs when there are 3 bytes to load.
5775 Back intoffset back to the beginning of the word in this
5776 case. */
5777 intoffset = intoffset & -BITS_PER_WORD;
5778 mode = word_mode;
5781 else
5782 mode = word_mode;
5784 startbit = intoffset & -BITS_PER_WORD;
5785 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5786 intregs = (endbit - startbit) / BITS_PER_WORD;
5787 this_regno = cum->words + intoffset / BITS_PER_WORD;
5789 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
5790 cum->use_stack = 1;
5792 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
5793 if (intregs <= 0)
5794 return;
5796 intoffset /= BITS_PER_UNIT;
5799 regno = GP_ARG_MIN_REG + this_regno;
5800 reg = gen_rtx_REG (mode, regno);
5801 rvec[(*k)++] =
5802 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
5804 this_regno += 1;
5805 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
5806 mode = word_mode;
5807 intregs -= 1;
5809 while (intregs > 0);
5812 /* Recursive workhorse for the following. */
5814 static void
5815 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
5816 HOST_WIDE_INT startbitpos, rtx rvec[],
5817 int *k)
5819 tree f;
5821 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5822 if (TREE_CODE (f) == FIELD_DECL)
5824 HOST_WIDE_INT bitpos = startbitpos;
5825 tree ftype = TREE_TYPE (f);
5826 enum machine_mode mode;
5827 if (ftype == error_mark_node)
5828 continue;
5829 mode = TYPE_MODE (ftype);
5831 if (DECL_SIZE (f) != 0
5832 && host_integerp (bit_position (f), 1))
5833 bitpos += int_bit_position (f);
5835 /* ??? FIXME: else assume zero offset. */
5837 if (TREE_CODE (ftype) == RECORD_TYPE)
5838 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
5839 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
5841 #if 0
5842 switch (mode)
5844 case SCmode: mode = SFmode; break;
5845 case DCmode: mode = DFmode; break;
5846 case TCmode: mode = TFmode; break;
5847 default: break;
5849 #endif
5850 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5851 rvec[(*k)++]
5852 = gen_rtx_EXPR_LIST (VOIDmode,
5853 gen_rtx_REG (mode, cum->fregno++),
5854 GEN_INT (bitpos / BITS_PER_UNIT));
5855 if (mode == TFmode || mode == TDmode)
5856 cum->fregno++;
5858 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
5860 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5861 rvec[(*k)++]
5862 = gen_rtx_EXPR_LIST (VOIDmode,
5863 gen_rtx_REG (mode, cum->vregno++),
5864 GEN_INT (bitpos / BITS_PER_UNIT));
5866 else if (cum->intoffset == -1)
5867 cum->intoffset = bitpos;
5871 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5872 the register(s) to be used for each field and subfield of a struct
5873 being passed by value, along with the offset of where the
5874 register's value may be found in the block. FP fields go in FP
5875 register, vector fields go in vector registers, and everything
5876 else goes in int registers, packed as in memory.
5878 This code is also used for function return values. RETVAL indicates
5879 whether this is the case.
5881 Much of this is taken from the SPARC V9 port, which has a similar
5882 calling convention. */
5884 static rtx
5885 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
5886 int named, bool retval)
5888 rtx rvec[FIRST_PSEUDO_REGISTER];
5889 int k = 1, kbase = 1;
5890 HOST_WIDE_INT typesize = int_size_in_bytes (type);
5891 /* This is a copy; modifications are not visible to our caller. */
5892 CUMULATIVE_ARGS copy_cum = *orig_cum;
5893 CUMULATIVE_ARGS *cum = &copy_cum;
5895 /* Pad to 16 byte boundary if needed. */
5896 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5897 && (cum->words % 2) != 0)
5898 cum->words++;
5900 cum->intoffset = 0;
5901 cum->use_stack = 0;
5902 cum->named = named;
5904 /* Put entries into rvec[] for individual FP and vector fields, and
5905 for the chunks of memory that go in int regs. Note we start at
5906 element 1; 0 is reserved for an indication of using memory, and
5907 may or may not be filled in below. */
5908 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
5909 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
5911 /* If any part of the struct went on the stack put all of it there.
5912 This hack is because the generic code for
5913 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5914 parts of the struct are not at the beginning. */
5915 if (cum->use_stack)
5917 if (retval)
5918 return NULL_RTX; /* doesn't go in registers at all */
5919 kbase = 0;
5920 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5922 if (k > 1 || cum->use_stack)
5923 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
5924 else
5925 return NULL_RTX;
5928 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5930 static rtx
5931 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
5933 int n_units;
5934 int i, k;
5935 rtx rvec[GP_ARG_NUM_REG + 1];
5937 if (align_words >= GP_ARG_NUM_REG)
5938 return NULL_RTX;
5940 n_units = rs6000_arg_size (mode, type);
5942 /* Optimize the simple case where the arg fits in one gpr, except in
5943 the case of BLKmode due to assign_parms assuming that registers are
5944 BITS_PER_WORD wide. */
5945 if (n_units == 0
5946 || (n_units == 1 && mode != BLKmode))
5947 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5949 k = 0;
5950 if (align_words + n_units > GP_ARG_NUM_REG)
5951 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5952 using a magic NULL_RTX component.
5953 This is not strictly correct. Only some of the arg belongs in
5954 memory, not all of it. However, the normal scheme using
5955 function_arg_partial_nregs can result in unusual subregs, eg.
5956 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5957 store the whole arg to memory is often more efficient than code
5958 to store pieces, and we know that space is available in the right
5959 place for the whole arg. */
5960 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5962 i = 0;
5965 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
5966 rtx off = GEN_INT (i++ * 4);
5967 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5969 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
5971 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5974 /* Determine where to put an argument to a function.
5975 Value is zero to push the argument on the stack,
5976 or a hard register in which to store the argument.
5978 MODE is the argument's machine mode.
5979 TYPE is the data type of the argument (as a tree).
5980 This is null for libcalls where that information may
5981 not be available.
5982 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5983 the preceding args and about the function being called. It is
5984 not modified in this routine.
5985 NAMED is nonzero if this argument is a named parameter
5986 (otherwise it is an extra parameter matching an ellipsis).
5988 On RS/6000 the first eight words of non-FP are normally in registers
5989 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5990 Under V.4, the first 8 FP args are in registers.
5992 If this is floating-point and no prototype is specified, we use
5993 both an FP and integer register (or possibly FP reg and stack). Library
5994 functions (when CALL_LIBCALL is set) always have the proper types for args,
5995 so we can pass the FP value just in one register. emit_library_function
5996 doesn't support PARALLEL anyway.
5998 Note that for args passed by reference, function_arg will be called
5999 with MODE and TYPE set to that of the pointer to the arg, not the arg
6000 itself. */
6003 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6004 tree type, int named)
6006 enum rs6000_abi abi = DEFAULT_ABI;
6008 /* Return a marker to indicate whether CR1 needs to set or clear the
6009 bit that V.4 uses to say fp args were passed in registers.
6010 Assume that we don't need the marker for software floating point,
6011 or compiler generated library calls. */
6012 if (mode == VOIDmode)
6014 if (abi == ABI_V4
6015 && (cum->call_cookie & CALL_LIBCALL) == 0
6016 && (cum->stdarg
6017 || (cum->nargs_prototype < 0
6018 && (cum->prototype || TARGET_NO_PROTOTYPE))))
6020 /* For the SPE, we need to crxor CR6 always. */
6021 if (TARGET_SPE_ABI)
6022 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
6023 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
6024 return GEN_INT (cum->call_cookie
6025 | ((cum->fregno == FP_ARG_MIN_REG)
6026 ? CALL_V4_SET_FP_ARGS
6027 : CALL_V4_CLEAR_FP_ARGS));
6030 return GEN_INT (cum->call_cookie);
6033 if (rs6000_darwin64_abi && mode == BLKmode
6034 && TREE_CODE (type) == RECORD_TYPE)
6036 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
6037 if (rslt != NULL_RTX)
6038 return rslt;
6039 /* Else fall through to usual handling. */
6042 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
6043 if (TARGET_64BIT && ! cum->prototype)
6045 /* Vector parameters get passed in vector register
6046 and also in GPRs or memory, in absence of prototype. */
6047 int align_words;
6048 rtx slot;
6049 align_words = (cum->words + 1) & ~1;
6051 if (align_words >= GP_ARG_NUM_REG)
6053 slot = NULL_RTX;
6055 else
6057 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
6059 return gen_rtx_PARALLEL (mode,
6060 gen_rtvec (2,
6061 gen_rtx_EXPR_LIST (VOIDmode,
6062 slot, const0_rtx),
6063 gen_rtx_EXPR_LIST (VOIDmode,
6064 gen_rtx_REG (mode, cum->vregno),
6065 const0_rtx)));
6067 else
6068 return gen_rtx_REG (mode, cum->vregno);
6069 else if (TARGET_ALTIVEC_ABI
6070 && (ALTIVEC_VECTOR_MODE (mode)
6071 || (type && TREE_CODE (type) == VECTOR_TYPE
6072 && int_size_in_bytes (type) == 16)))
6074 if (named || abi == ABI_V4)
6075 return NULL_RTX;
6076 else
6078 /* Vector parameters to varargs functions under AIX or Darwin
6079 get passed in memory and possibly also in GPRs. */
6080 int align, align_words, n_words;
6081 enum machine_mode part_mode;
6083 /* Vector parameters must be 16-byte aligned. This places them at
6084 2 mod 4 in terms of words in 32-bit mode, since the parameter
6085 save area starts at offset 24 from the stack. In 64-bit mode,
6086 they just have to start on an even word, since the parameter
6087 save area is 16-byte aligned. */
6088 if (TARGET_32BIT)
6089 align = (2 - cum->words) & 3;
6090 else
6091 align = cum->words & 1;
6092 align_words = cum->words + align;
6094 /* Out of registers? Memory, then. */
6095 if (align_words >= GP_ARG_NUM_REG)
6096 return NULL_RTX;
6098 if (TARGET_32BIT && TARGET_POWERPC64)
6099 return rs6000_mixed_function_arg (mode, type, align_words);
6101 /* The vector value goes in GPRs. Only the part of the
6102 value in GPRs is reported here. */
6103 part_mode = mode;
6104 n_words = rs6000_arg_size (mode, type);
6105 if (align_words + n_words > GP_ARG_NUM_REG)
6106 /* Fortunately, there are only two possibilities, the value
6107 is either wholly in GPRs or half in GPRs and half not. */
6108 part_mode = DImode;
6110 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
6113 else if (TARGET_SPE_ABI && TARGET_SPE
6114 && (SPE_VECTOR_MODE (mode)
6115 || (TARGET_E500_DOUBLE && (mode == DFmode
6116 || mode == DDmode
6117 || mode == DCmode
6118 || mode == TFmode
6119 || mode == TDmode
6120 || mode == TCmode))))
6121 return rs6000_spe_function_arg (cum, mode, type);
6123 else if (abi == ABI_V4)
6125 if (TARGET_HARD_FLOAT && TARGET_FPRS
6126 && (mode == SFmode || mode == DFmode
6127 || (mode == TFmode && !TARGET_IEEEQUAD)
6128 || mode == SDmode || mode == DDmode || mode == TDmode))
6130 /* _Decimal128 must use an even/odd register pair. This assumes
6131 that the register number is odd when fregno is odd. */
6132 if (mode == TDmode && (cum->fregno % 2) == 1)
6133 cum->fregno++;
6135 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
6136 <= FP_ARG_V4_MAX_REG)
6137 return gen_rtx_REG (mode, cum->fregno);
6138 else
6139 return NULL_RTX;
6141 else
6143 int n_words = rs6000_arg_size (mode, type);
6144 int gregno = cum->sysv_gregno;
6146 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
6147 (r7,r8) or (r9,r10). As does any other 2 word item such
6148 as complex int due to a historical mistake. */
6149 if (n_words == 2)
6150 gregno += (1 - gregno) & 1;
6152 /* Multi-reg args are not split between registers and stack. */
6153 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
6154 return NULL_RTX;
6156 if (TARGET_32BIT && TARGET_POWERPC64)
6157 return rs6000_mixed_function_arg (mode, type,
6158 gregno - GP_ARG_MIN_REG);
6159 return gen_rtx_REG (mode, gregno);
6162 else
6164 int align_words = rs6000_parm_start (mode, type, cum->words);
6166 /* _Decimal128 must be passed in an even/odd float register pair.
6167 This assumes that the register number is odd when fregno is odd. */
6168 if (mode == TDmode && (cum->fregno % 2) == 1)
6169 cum->fregno++;
6171 if (USE_FP_FOR_ARG_P (cum, mode, type))
6173 rtx rvec[GP_ARG_NUM_REG + 1];
6174 rtx r;
6175 int k;
6176 bool needs_psave;
6177 enum machine_mode fmode = mode;
6178 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
6180 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
6182 /* Currently, we only ever need one reg here because complex
6183 doubles are split. */
6184 gcc_assert (cum->fregno == FP_ARG_MAX_REG
6185 && (fmode == TFmode || fmode == TDmode));
6187 /* Long double or _Decimal128 split over regs and memory. */
6188 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
6191 /* Do we also need to pass this arg in the parameter save
6192 area? */
6193 needs_psave = (type
6194 && (cum->nargs_prototype <= 0
6195 || (DEFAULT_ABI == ABI_AIX
6196 && TARGET_XL_COMPAT
6197 && align_words >= GP_ARG_NUM_REG)));
6199 if (!needs_psave && mode == fmode)
6200 return gen_rtx_REG (fmode, cum->fregno);
6202 k = 0;
6203 if (needs_psave)
6205 /* Describe the part that goes in gprs or the stack.
6206 This piece must come first, before the fprs. */
6207 if (align_words < GP_ARG_NUM_REG)
6209 unsigned long n_words = rs6000_arg_size (mode, type);
6211 if (align_words + n_words > GP_ARG_NUM_REG
6212 || (TARGET_32BIT && TARGET_POWERPC64))
6214 /* If this is partially on the stack, then we only
6215 include the portion actually in registers here. */
6216 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
6217 rtx off;
6218 int i = 0;
6219 if (align_words + n_words > GP_ARG_NUM_REG)
6220 /* Not all of the arg fits in gprs. Say that it
6221 goes in memory too, using a magic NULL_RTX
6222 component. Also see comment in
6223 rs6000_mixed_function_arg for why the normal
6224 function_arg_partial_nregs scheme doesn't work
6225 in this case. */
6226 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
6227 const0_rtx);
6230 r = gen_rtx_REG (rmode,
6231 GP_ARG_MIN_REG + align_words);
6232 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
6233 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
6235 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
6237 else
6239 /* The whole arg fits in gprs. */
6240 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
6241 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
6244 else
6245 /* It's entirely in memory. */
6246 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
6249 /* Describe where this piece goes in the fprs. */
6250 r = gen_rtx_REG (fmode, cum->fregno);
6251 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
6253 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
6255 else if (align_words < GP_ARG_NUM_REG)
6257 if (TARGET_32BIT && TARGET_POWERPC64)
6258 return rs6000_mixed_function_arg (mode, type, align_words);
6260 if (mode == BLKmode)
6261 mode = Pmode;
6263 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
6265 else
6266 return NULL_RTX;
6270 /* For an arg passed partly in registers and partly in memory, this is
6271 the number of bytes passed in registers. For args passed entirely in
6272 registers or entirely in memory, zero. When an arg is described by a
6273 PARALLEL, perhaps using more than one register type, this function
6274 returns the number of bytes used by the first element of the PARALLEL. */
6276 static int
6277 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6278 tree type, bool named)
6280 int ret = 0;
6281 int align_words;
6283 if (DEFAULT_ABI == ABI_V4)
6284 return 0;
6286 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
6287 && cum->nargs_prototype >= 0)
6288 return 0;
6290 /* In this complicated case we just disable the partial_nregs code. */
6291 if (rs6000_darwin64_abi && mode == BLKmode
6292 && TREE_CODE (type) == RECORD_TYPE
6293 && int_size_in_bytes (type) > 0)
6294 return 0;
6296 align_words = rs6000_parm_start (mode, type, cum->words);
6298 if (USE_FP_FOR_ARG_P (cum, mode, type))
6300 /* If we are passing this arg in the fixed parameter save area
6301 (gprs or memory) as well as fprs, then this function should
6302 return the number of partial bytes passed in the parameter
6303 save area rather than partial bytes passed in fprs. */
6304 if (type
6305 && (cum->nargs_prototype <= 0
6306 || (DEFAULT_ABI == ABI_AIX
6307 && TARGET_XL_COMPAT
6308 && align_words >= GP_ARG_NUM_REG)))
6309 return 0;
6310 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
6311 > FP_ARG_MAX_REG + 1)
6312 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
6313 else if (cum->nargs_prototype >= 0)
6314 return 0;
6317 if (align_words < GP_ARG_NUM_REG
6318 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
6319 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
6321 if (ret != 0 && TARGET_DEBUG_ARG)
6322 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
6324 return ret;
6327 /* A C expression that indicates when an argument must be passed by
6328 reference. If nonzero for an argument, a copy of that argument is
6329 made in memory and a pointer to the argument is passed instead of
6330 the argument itself. The pointer is passed in whatever way is
6331 appropriate for passing a pointer to that type.
6333 Under V.4, aggregates and long double are passed by reference.
6335 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
6336 reference unless the AltiVec vector extension ABI is in force.
6338 As an extension to all ABIs, variable sized types are passed by
6339 reference. */
6341 static bool
6342 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
6343 enum machine_mode mode, const_tree type,
6344 bool named ATTRIBUTE_UNUSED)
6346 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
6348 if (TARGET_DEBUG_ARG)
6349 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
6350 return 1;
6353 if (!type)
6354 return 0;
6356 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
6358 if (TARGET_DEBUG_ARG)
6359 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
6360 return 1;
6363 if (int_size_in_bytes (type) < 0)
6365 if (TARGET_DEBUG_ARG)
6366 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
6367 return 1;
6370 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6371 modes only exist for GCC vector types if -maltivec. */
6372 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
6374 if (TARGET_DEBUG_ARG)
6375 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
6376 return 1;
6379 /* Pass synthetic vectors in memory. */
6380 if (TREE_CODE (type) == VECTOR_TYPE
6381 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6383 static bool warned_for_pass_big_vectors = false;
6384 if (TARGET_DEBUG_ARG)
6385 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
6386 if (!warned_for_pass_big_vectors)
6388 warning (0, "GCC vector passed by reference: "
6389 "non-standard ABI extension with no compatibility guarantee");
6390 warned_for_pass_big_vectors = true;
6392 return 1;
6395 return 0;
6398 static void
6399 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
6401 int i;
6402 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
6404 if (nregs == 0)
6405 return;
6407 for (i = 0; i < nregs; i++)
6409 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
6410 if (reload_completed)
6412 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
6413 tem = NULL_RTX;
6414 else
6415 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
6416 i * GET_MODE_SIZE (reg_mode));
6418 else
6419 tem = replace_equiv_address (tem, XEXP (tem, 0));
6421 gcc_assert (tem);
6423 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
6427 /* Perform any needed actions needed for a function that is receiving a
6428 variable number of arguments.
6430 CUM is as above.
6432 MODE and TYPE are the mode and type of the current parameter.
6434 PRETEND_SIZE is a variable that should be set to the amount of stack
6435 that must be pushed by the prolog to pretend that our caller pushed
6438 Normally, this macro will push all remaining incoming registers on the
6439 stack and set PRETEND_SIZE to the length of the registers pushed. */
6441 static void
6442 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6443 tree type, int *pretend_size ATTRIBUTE_UNUSED,
6444 int no_rtl)
6446 CUMULATIVE_ARGS next_cum;
6447 int reg_size = TARGET_32BIT ? 4 : 8;
6448 rtx save_area = NULL_RTX, mem;
6449 int first_reg_offset;
6450 alias_set_type set;
6452 /* Skip the last named argument. */
6453 next_cum = *cum;
6454 function_arg_advance (&next_cum, mode, type, 1, 0);
6456 if (DEFAULT_ABI == ABI_V4)
6458 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
6460 if (! no_rtl)
6462 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
6463 HOST_WIDE_INT offset = 0;
6465 /* Try to optimize the size of the varargs save area.
6466 The ABI requires that ap.reg_save_area is doubleword
6467 aligned, but we don't need to allocate space for all
6468 the bytes, only those to which we actually will save
6469 anything. */
6470 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
6471 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
6472 if (TARGET_HARD_FLOAT && TARGET_FPRS
6473 && next_cum.fregno <= FP_ARG_V4_MAX_REG
6474 && cfun->va_list_fpr_size)
6476 if (gpr_reg_num)
6477 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
6478 * UNITS_PER_FP_WORD;
6479 if (cfun->va_list_fpr_size
6480 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
6481 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
6482 else
6483 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
6484 * UNITS_PER_FP_WORD;
6486 if (gpr_reg_num)
6488 offset = -((first_reg_offset * reg_size) & ~7);
6489 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
6491 gpr_reg_num = cfun->va_list_gpr_size;
6492 if (reg_size == 4 && (first_reg_offset & 1))
6493 gpr_reg_num++;
6495 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
6497 else if (fpr_size)
6498 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
6499 * UNITS_PER_FP_WORD
6500 - (int) (GP_ARG_NUM_REG * reg_size);
6502 if (gpr_size + fpr_size)
6504 rtx reg_save_area
6505 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
6506 gcc_assert (GET_CODE (reg_save_area) == MEM);
6507 reg_save_area = XEXP (reg_save_area, 0);
6508 if (GET_CODE (reg_save_area) == PLUS)
6510 gcc_assert (XEXP (reg_save_area, 0)
6511 == virtual_stack_vars_rtx);
6512 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
6513 offset += INTVAL (XEXP (reg_save_area, 1));
6515 else
6516 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
6519 cfun->machine->varargs_save_offset = offset;
6520 save_area = plus_constant (virtual_stack_vars_rtx, offset);
6523 else
6525 first_reg_offset = next_cum.words;
6526 save_area = virtual_incoming_args_rtx;
6528 if (targetm.calls.must_pass_in_stack (mode, type))
6529 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
6532 set = get_varargs_alias_set ();
6533 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
6534 && cfun->va_list_gpr_size)
6536 int nregs = GP_ARG_NUM_REG - first_reg_offset;
6538 if (va_list_gpr_counter_field)
6540 /* V4 va_list_gpr_size counts number of registers needed. */
6541 if (nregs > cfun->va_list_gpr_size)
6542 nregs = cfun->va_list_gpr_size;
6544 else
6546 /* char * va_list instead counts number of bytes needed. */
6547 if (nregs > cfun->va_list_gpr_size / reg_size)
6548 nregs = cfun->va_list_gpr_size / reg_size;
6551 mem = gen_rtx_MEM (BLKmode,
6552 plus_constant (save_area,
6553 first_reg_offset * reg_size));
6554 MEM_NOTRAP_P (mem) = 1;
6555 set_mem_alias_set (mem, set);
6556 set_mem_align (mem, BITS_PER_WORD);
6558 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
6559 nregs);
6562 /* Save FP registers if needed. */
6563 if (DEFAULT_ABI == ABI_V4
6564 && TARGET_HARD_FLOAT && TARGET_FPRS
6565 && ! no_rtl
6566 && next_cum.fregno <= FP_ARG_V4_MAX_REG
6567 && cfun->va_list_fpr_size)
6569 int fregno = next_cum.fregno, nregs;
6570 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
6571 rtx lab = gen_label_rtx ();
6572 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
6573 * UNITS_PER_FP_WORD);
6575 emit_jump_insn
6576 (gen_rtx_SET (VOIDmode,
6577 pc_rtx,
6578 gen_rtx_IF_THEN_ELSE (VOIDmode,
6579 gen_rtx_NE (VOIDmode, cr1,
6580 const0_rtx),
6581 gen_rtx_LABEL_REF (VOIDmode, lab),
6582 pc_rtx)));
6584 for (nregs = 0;
6585 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
6586 fregno++, off += UNITS_PER_FP_WORD, nregs++)
6588 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
6589 MEM_NOTRAP_P (mem) = 1;
6590 set_mem_alias_set (mem, set);
6591 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
6592 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
6595 emit_label (lab);
6599 /* Create the va_list data type. */
6601 static tree
6602 rs6000_build_builtin_va_list (void)
6604 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
6606 /* For AIX, prefer 'char *' because that's what the system
6607 header files like. */
6608 if (DEFAULT_ABI != ABI_V4)
6609 return build_pointer_type (char_type_node);
6611 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
6612 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6614 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
6615 unsigned_char_type_node);
6616 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
6617 unsigned_char_type_node);
6618 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6619 every user file. */
6620 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
6621 short_unsigned_type_node);
6622 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
6623 ptr_type_node);
6624 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
6625 ptr_type_node);
6627 va_list_gpr_counter_field = f_gpr;
6628 va_list_fpr_counter_field = f_fpr;
6630 DECL_FIELD_CONTEXT (f_gpr) = record;
6631 DECL_FIELD_CONTEXT (f_fpr) = record;
6632 DECL_FIELD_CONTEXT (f_res) = record;
6633 DECL_FIELD_CONTEXT (f_ovf) = record;
6634 DECL_FIELD_CONTEXT (f_sav) = record;
6636 TREE_CHAIN (record) = type_decl;
6637 TYPE_NAME (record) = type_decl;
6638 TYPE_FIELDS (record) = f_gpr;
6639 TREE_CHAIN (f_gpr) = f_fpr;
6640 TREE_CHAIN (f_fpr) = f_res;
6641 TREE_CHAIN (f_res) = f_ovf;
6642 TREE_CHAIN (f_ovf) = f_sav;
6644 layout_type (record);
6646 /* The correct type is an array type of one element. */
6647 return build_array_type (record, build_index_type (size_zero_node));
6650 /* Implement va_start. */
6652 static void
6653 rs6000_va_start (tree valist, rtx nextarg)
6655 HOST_WIDE_INT words, n_gpr, n_fpr;
6656 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6657 tree gpr, fpr, ovf, sav, t;
6659 /* Only SVR4 needs something special. */
6660 if (DEFAULT_ABI != ABI_V4)
6662 std_expand_builtin_va_start (valist, nextarg);
6663 return;
6666 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6667 f_fpr = TREE_CHAIN (f_gpr);
6668 f_res = TREE_CHAIN (f_fpr);
6669 f_ovf = TREE_CHAIN (f_res);
6670 f_sav = TREE_CHAIN (f_ovf);
6672 valist = build_va_arg_indirect_ref (valist);
6673 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6674 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6675 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6676 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6678 /* Count number of gp and fp argument registers used. */
6679 words = crtl->args.info.words;
6680 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
6681 GP_ARG_NUM_REG);
6682 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
6683 FP_ARG_NUM_REG);
6685 if (TARGET_DEBUG_ARG)
6686 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
6687 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
6688 words, n_gpr, n_fpr);
6690 if (cfun->va_list_gpr_size)
6692 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr,
6693 build_int_cst (NULL_TREE, n_gpr));
6694 TREE_SIDE_EFFECTS (t) = 1;
6695 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6698 if (cfun->va_list_fpr_size)
6700 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr,
6701 build_int_cst (NULL_TREE, n_fpr));
6702 TREE_SIDE_EFFECTS (t) = 1;
6703 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6706 /* Find the overflow area. */
6707 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6708 if (words != 0)
6709 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
6710 size_int (words * UNITS_PER_WORD));
6711 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6712 TREE_SIDE_EFFECTS (t) = 1;
6713 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6715 /* If there were no va_arg invocations, don't set up the register
6716 save area. */
6717 if (!cfun->va_list_gpr_size
6718 && !cfun->va_list_fpr_size
6719 && n_gpr < GP_ARG_NUM_REG
6720 && n_fpr < FP_ARG_V4_MAX_REG)
6721 return;
6723 /* Find the register save area. */
6724 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
6725 if (cfun->machine->varargs_save_offset)
6726 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
6727 size_int (cfun->machine->varargs_save_offset));
6728 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
6729 TREE_SIDE_EFFECTS (t) = 1;
6730 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6733 /* Implement va_arg. */
6735 tree
6736 rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
6738 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6739 tree gpr, fpr, ovf, sav, reg, t, u;
6740 int size, rsize, n_reg, sav_ofs, sav_scale;
6741 tree lab_false, lab_over, addr;
6742 int align;
6743 tree ptrtype = build_pointer_type (type);
6744 int regalign = 0;
6746 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
6748 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
6749 return build_va_arg_indirect_ref (t);
6752 if (DEFAULT_ABI != ABI_V4)
6754 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
6756 tree elem_type = TREE_TYPE (type);
6757 enum machine_mode elem_mode = TYPE_MODE (elem_type);
6758 int elem_size = GET_MODE_SIZE (elem_mode);
6760 if (elem_size < UNITS_PER_WORD)
6762 tree real_part, imag_part;
6763 tree post = NULL_TREE;
6765 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6766 &post);
6767 /* Copy the value into a temporary, lest the formal temporary
6768 be reused out from under us. */
6769 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
6770 append_to_statement_list (post, pre_p);
6772 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6773 post_p);
6775 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
6779 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6782 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6783 f_fpr = TREE_CHAIN (f_gpr);
6784 f_res = TREE_CHAIN (f_fpr);
6785 f_ovf = TREE_CHAIN (f_res);
6786 f_sav = TREE_CHAIN (f_ovf);
6788 valist = build_va_arg_indirect_ref (valist);
6789 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6790 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6791 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6792 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6794 size = int_size_in_bytes (type);
6795 rsize = (size + 3) / 4;
6796 align = 1;
6798 if (TARGET_HARD_FLOAT && TARGET_FPRS
6799 && (TYPE_MODE (type) == SFmode
6800 || TYPE_MODE (type) == DFmode
6801 || TYPE_MODE (type) == TFmode
6802 || TYPE_MODE (type) == SDmode
6803 || TYPE_MODE (type) == DDmode
6804 || TYPE_MODE (type) == TDmode))
6806 /* FP args go in FP registers, if present. */
6807 reg = fpr;
6808 n_reg = (size + 7) / 8;
6809 sav_ofs = 8*4;
6810 sav_scale = 8;
6811 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
6812 align = 8;
6814 else
6816 /* Otherwise into GP registers. */
6817 reg = gpr;
6818 n_reg = rsize;
6819 sav_ofs = 0;
6820 sav_scale = 4;
6821 if (n_reg == 2)
6822 align = 8;
6825 /* Pull the value out of the saved registers.... */
6827 lab_over = NULL;
6828 addr = create_tmp_var (ptr_type_node, "addr");
6829 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
6831 /* AltiVec vectors never go in registers when -mabi=altivec. */
6832 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6833 align = 16;
6834 else
6836 lab_false = create_artificial_label ();
6837 lab_over = create_artificial_label ();
6839 /* Long long and SPE vectors are aligned in the registers.
6840 As are any other 2 gpr item such as complex int due to a
6841 historical mistake. */
6842 u = reg;
6843 if (n_reg == 2 && reg == gpr)
6845 regalign = 1;
6846 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
6847 build_int_cst (TREE_TYPE (reg), n_reg - 1));
6848 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
6850 /* _Decimal128 is passed in even/odd fpr pairs; the stored
6851 reg number is 0 for f1, so we want to make it odd. */
6852 else if (reg == fpr && TYPE_MODE (type) == TDmode)
6854 regalign = 1;
6855 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), reg,
6856 build_int_cst (TREE_TYPE (reg), 1));
6857 u = build2 (MODIFY_EXPR, void_type_node, reg, t);
6860 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
6861 t = build2 (GE_EXPR, boolean_type_node, u, t);
6862 u = build1 (GOTO_EXPR, void_type_node, lab_false);
6863 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
6864 gimplify_and_add (t, pre_p);
6866 t = sav;
6867 if (sav_ofs)
6868 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
6870 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
6871 build_int_cst (TREE_TYPE (reg), n_reg));
6872 u = fold_convert (sizetype, u);
6873 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
6874 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
6876 /* _Decimal32 varargs are located in the second word of the 64-bit
6877 FP register for 32-bit binaries. */
6878 if (!TARGET_POWERPC64 && TYPE_MODE (type) == SDmode)
6879 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
6881 t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6882 gimplify_and_add (t, pre_p);
6884 t = build1 (GOTO_EXPR, void_type_node, lab_over);
6885 gimplify_and_add (t, pre_p);
6887 t = build1 (LABEL_EXPR, void_type_node, lab_false);
6888 append_to_statement_list (t, pre_p);
6890 if ((n_reg == 2 && !regalign) || n_reg > 2)
6892 /* Ensure that we don't find any more args in regs.
6893 Alignment has taken care of for special cases. */
6894 t = build_gimple_modify_stmt (reg,
6895 build_int_cst (TREE_TYPE (reg), 8));
6896 gimplify_and_add (t, pre_p);
6900 /* ... otherwise out of the overflow area. */
6902 /* Care for on-stack alignment if needed. */
6903 t = ovf;
6904 if (align != 1)
6906 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
6907 t = fold_convert (sizetype, t);
6908 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
6909 size_int (-align));
6910 t = fold_convert (TREE_TYPE (ovf), t);
6912 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
6914 u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6915 gimplify_and_add (u, pre_p);
6917 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
6918 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6919 gimplify_and_add (t, pre_p);
6921 if (lab_over)
6923 t = build1 (LABEL_EXPR, void_type_node, lab_over);
6924 append_to_statement_list (t, pre_p);
6927 if (STRICT_ALIGNMENT
6928 && (TYPE_ALIGN (type)
6929 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
6931 /* The value (of type complex double, for example) may not be
6932 aligned in memory in the saved registers, so copy via a
6933 temporary. (This is the same code as used for SPARC.) */
6934 tree tmp = create_tmp_var (type, "va_arg_tmp");
6935 tree dest_addr = build_fold_addr_expr (tmp);
6937 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
6938 3, dest_addr, addr, size_int (rsize * 4));
6940 gimplify_and_add (copy, pre_p);
6941 addr = dest_addr;
6944 addr = fold_convert (ptrtype, addr);
6945 return build_va_arg_indirect_ref (addr);
6948 /* Builtins. */
6950 static void
6951 def_builtin (int mask, const char *name, tree type, int code)
6953 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
6955 if (rs6000_builtin_decls[code])
6956 abort ();
6958 rs6000_builtin_decls[code] =
6959 add_builtin_function (name, type, code, BUILT_IN_MD,
6960 NULL, NULL_TREE);
6964 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6966 static const struct builtin_description bdesc_3arg[] =
6968 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
6969 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
6970 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
6971 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
6972 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
6973 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
6974 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
6975 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
6976 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
6977 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
6978 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
6979 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
6980 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
6981 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
6982 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
6983 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
6984 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
6985 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
6986 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
6987 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
6988 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
6989 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
6990 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
6992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
6993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
6994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
6995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
6996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
6997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
6998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
6999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
7000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
7001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
7002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
7003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
7004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
7005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
7006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
7008 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
7009 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
7010 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
7011 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
7012 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
7013 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
7014 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
7015 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
7016 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
7019 /* DST operations: void foo (void *, const int, const char). */
7021 static const struct builtin_description bdesc_dst[] =
7023 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
7024 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
7025 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
7026 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
7028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
7029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
7030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
7031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
7034 /* Simple binary operations: VECc = foo (VECa, VECb). */
7036 static struct builtin_description bdesc_2arg[] =
7038 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
7039 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
7040 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
7041 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
7042 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
7043 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
7044 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
7045 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
7046 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
7047 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
7048 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
7049 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
7050 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
7051 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
7052 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
7053 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
7054 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
7055 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
7056 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
7057 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
7058 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
7059 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
7060 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
7061 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
7062 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
7063 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
7064 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
7065 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
7066 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
7067 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
7068 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
7069 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
7070 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
7071 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
7072 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
7073 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
7074 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
7075 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
7076 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
7077 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
7078 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
7079 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
7080 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
7081 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
7082 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
7083 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
7084 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
7085 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
7086 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
7087 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
7088 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
7089 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
7090 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
7091 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
7092 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
7093 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
7094 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
7095 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
7096 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
7097 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
7098 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
7099 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
7100 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
7101 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
7102 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
7103 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
7104 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
7105 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
7106 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
7107 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
7108 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
7109 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
7110 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
7111 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
7112 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
7113 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
7114 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
7115 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
7116 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
7117 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
7118 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
7119 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
7120 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
7121 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
7122 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
7123 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
7124 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
7125 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
7126 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
7127 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
7128 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
7129 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
7130 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
7131 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
7132 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
7133 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
7134 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
7135 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
7136 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
7137 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
7138 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
7139 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
7140 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
7141 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
7142 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
7143 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
7144 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
7145 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
7146 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
7147 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
7148 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
7150 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
7151 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
7152 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
7153 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
7154 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
7155 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
7156 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
7157 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
7158 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
7159 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
7160 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
7161 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
7162 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
7163 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
7164 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
7165 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
7166 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
7167 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
7168 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
7169 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
7170 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
7171 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
7172 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
7173 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
7174 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
7175 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
7176 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
7177 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
7178 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
7179 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
7180 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
7181 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
7182 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
7183 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
7184 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
7185 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
7186 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
7187 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
7188 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
7189 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
7190 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
7191 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
7192 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
7193 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
7194 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
7195 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
7196 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
7197 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
7198 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
7199 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
7200 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
7201 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
7202 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
7203 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
7204 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
7205 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
7206 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
7207 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
7208 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
7209 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
7210 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
7211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
7212 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
7213 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
7214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
7215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
7216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
7217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
7218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
7219 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
7220 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
7221 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
7222 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
7223 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
7224 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
7225 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
7226 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
7227 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
7228 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
7229 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
7230 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
7231 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
7232 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
7233 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
7234 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
7235 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
7236 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
7237 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
7238 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
7239 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
7240 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
7241 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
7242 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
7243 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
7244 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
7245 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
7246 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
7247 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
7248 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
7249 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
7250 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
7251 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
7252 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
7253 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
7254 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
7255 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
7256 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
7257 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
7258 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
7259 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
7260 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
7261 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
7262 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
7263 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
7264 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
7265 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
7266 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
7267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
7268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
7269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
7270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
7271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
7272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
7273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
7274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
7275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
7276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
7278 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
7279 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
7280 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
7281 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
7282 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
7283 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
7284 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
7285 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
7286 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
7287 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
7289 /* Place holder, leave as first spe builtin. */
7290 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
7291 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
7292 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
7293 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
7294 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
7295 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
7296 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
7297 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
7298 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
7299 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
7300 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
7301 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
7302 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
7303 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
7304 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
7305 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
7306 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
7307 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
7308 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
7309 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
7310 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
7311 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
7312 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
7313 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
7314 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
7315 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
7316 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
7317 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
7318 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
7319 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
7320 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
7321 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
7322 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
7323 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
7324 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
7325 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
7326 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
7327 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
7328 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
7329 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
7330 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
7331 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
7332 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
7333 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
7334 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
7335 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
7336 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
7337 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
7338 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
7339 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
7340 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
7341 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
7342 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
7343 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
7344 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
7345 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
7346 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
7347 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
7348 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
7349 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
7350 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
7351 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
7352 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
7353 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
7354 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
7355 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
7356 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
7357 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
7358 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
7359 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
7360 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
7361 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
7362 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
7363 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
7364 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
7365 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
7366 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
7367 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
7368 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
7369 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
7370 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
7371 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
7372 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
7373 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
7374 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
7375 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
7376 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
7377 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
7378 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
7379 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
7380 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
7381 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
7382 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
7383 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
7384 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
7385 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
7386 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
7387 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
7388 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
7389 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
7390 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
7391 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
7392 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
7393 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
7394 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
7395 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
7396 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
7397 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
7398 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
7400 /* SPE binary operations expecting a 5-bit unsigned literal. */
7401 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
7403 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
7404 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
7405 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
7406 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
7407 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
7408 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
7409 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
7410 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
7411 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
7412 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
7413 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
7414 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
7415 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
7416 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
7417 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
7418 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
7419 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
7420 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
7421 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
7422 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
7423 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
7424 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
7425 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
7426 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
7427 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
7428 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
7430 /* Place-holder. Leave as last binary SPE builtin. */
7431 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
7434 /* AltiVec predicates. */
7436 struct builtin_description_predicates
7438 const unsigned int mask;
7439 const enum insn_code icode;
7440 const char *opcode;
7441 const char *const name;
7442 const enum rs6000_builtins code;
7445 static const struct builtin_description_predicates bdesc_altivec_preds[] =
7447 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
7448 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
7449 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
7450 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
7451 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
7452 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
7453 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
7454 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
7455 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
7456 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
7457 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
7458 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
7459 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
7461 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
7462 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
7463 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
7466 /* SPE predicates. */
7467 static struct builtin_description bdesc_spe_predicates[] =
7469 /* Place-holder. Leave as first. */
7470 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
7471 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
7472 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
7473 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
7474 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
7475 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
7476 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
7477 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
7478 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
7479 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
7480 /* Place-holder. Leave as last. */
7481 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
7484 /* SPE evsel predicates. */
7485 static struct builtin_description bdesc_spe_evsel[] =
7487 /* Place-holder. Leave as first. */
7488 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
7489 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
7490 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
7491 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
7492 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
7493 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
7494 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
7495 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
7496 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
7497 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
7498 /* Place-holder. Leave as last. */
7499 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
7502 /* PAIRED predicates. */
7503 static const struct builtin_description bdesc_paired_preds[] =
7505 /* Place-holder. Leave as first. */
7506 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
7507 /* Place-holder. Leave as last. */
7508 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
7511 /* ABS* operations. */
7513 static const struct builtin_description bdesc_abs[] =
7515 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
7516 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
7517 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
7518 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
7519 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
7520 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
7521 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
7524 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
7525 foo (VECa). */
7527 static struct builtin_description bdesc_1arg[] =
7529 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
7530 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
7531 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
7532 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
7533 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
7534 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
7535 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
7536 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
7537 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
7538 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
7539 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
7540 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
7541 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
7542 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
7543 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
7544 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
7545 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
7547 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
7548 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
7549 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
7550 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
7551 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
7552 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
7553 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
7554 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
7555 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
7556 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
7557 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
7558 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
7559 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
7560 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
7561 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
7562 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
7563 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
7564 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
7565 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
7567 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
7568 end with SPE_BUILTIN_EVSUBFUSIAAW. */
7569 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
7570 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
7571 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
7572 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
7573 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
7574 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
7575 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
7576 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
7577 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
7578 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
7579 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
7580 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
7581 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
7582 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
7583 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
7584 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
7585 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
7586 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
7587 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
7588 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
7589 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
7590 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
7591 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
7592 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
7593 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
7594 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
7595 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
7596 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
7598 /* Place-holder. Leave as last unary SPE builtin. */
7599 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
7601 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
7602 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
7603 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
7604 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
7605 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
7608 static rtx
7609 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
7611 rtx pat;
7612 tree arg0 = CALL_EXPR_ARG (exp, 0);
7613 rtx op0 = expand_normal (arg0);
7614 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7615 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7617 if (icode == CODE_FOR_nothing)
7618 /* Builtin not supported on this processor. */
7619 return 0;
7621 /* If we got invalid arguments bail out before generating bad rtl. */
7622 if (arg0 == error_mark_node)
7623 return const0_rtx;
7625 if (icode == CODE_FOR_altivec_vspltisb
7626 || icode == CODE_FOR_altivec_vspltish
7627 || icode == CODE_FOR_altivec_vspltisw
7628 || icode == CODE_FOR_spe_evsplatfi
7629 || icode == CODE_FOR_spe_evsplati)
7631 /* Only allow 5-bit *signed* literals. */
7632 if (GET_CODE (op0) != CONST_INT
7633 || INTVAL (op0) > 15
7634 || INTVAL (op0) < -16)
7636 error ("argument 1 must be a 5-bit signed literal");
7637 return const0_rtx;
7641 if (target == 0
7642 || GET_MODE (target) != tmode
7643 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7644 target = gen_reg_rtx (tmode);
7646 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7647 op0 = copy_to_mode_reg (mode0, op0);
7649 pat = GEN_FCN (icode) (target, op0);
7650 if (! pat)
7651 return 0;
7652 emit_insn (pat);
7654 return target;
7657 static rtx
7658 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
7660 rtx pat, scratch1, scratch2;
7661 tree arg0 = CALL_EXPR_ARG (exp, 0);
7662 rtx op0 = expand_normal (arg0);
7663 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7664 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7666 /* If we have invalid arguments, bail out before generating bad rtl. */
7667 if (arg0 == error_mark_node)
7668 return const0_rtx;
7670 if (target == 0
7671 || GET_MODE (target) != tmode
7672 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7673 target = gen_reg_rtx (tmode);
7675 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7676 op0 = copy_to_mode_reg (mode0, op0);
7678 scratch1 = gen_reg_rtx (mode0);
7679 scratch2 = gen_reg_rtx (mode0);
7681 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
7682 if (! pat)
7683 return 0;
7684 emit_insn (pat);
7686 return target;
7689 static rtx
7690 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
7692 rtx pat;
7693 tree arg0 = CALL_EXPR_ARG (exp, 0);
7694 tree arg1 = CALL_EXPR_ARG (exp, 1);
7695 rtx op0 = expand_normal (arg0);
7696 rtx op1 = expand_normal (arg1);
7697 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7698 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7699 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7701 if (icode == CODE_FOR_nothing)
7702 /* Builtin not supported on this processor. */
7703 return 0;
7705 /* If we got invalid arguments bail out before generating bad rtl. */
7706 if (arg0 == error_mark_node || arg1 == error_mark_node)
7707 return const0_rtx;
7709 if (icode == CODE_FOR_altivec_vcfux
7710 || icode == CODE_FOR_altivec_vcfsx
7711 || icode == CODE_FOR_altivec_vctsxs
7712 || icode == CODE_FOR_altivec_vctuxs
7713 || icode == CODE_FOR_altivec_vspltb
7714 || icode == CODE_FOR_altivec_vsplth
7715 || icode == CODE_FOR_altivec_vspltw
7716 || icode == CODE_FOR_spe_evaddiw
7717 || icode == CODE_FOR_spe_evldd
7718 || icode == CODE_FOR_spe_evldh
7719 || icode == CODE_FOR_spe_evldw
7720 || icode == CODE_FOR_spe_evlhhesplat
7721 || icode == CODE_FOR_spe_evlhhossplat
7722 || icode == CODE_FOR_spe_evlhhousplat
7723 || icode == CODE_FOR_spe_evlwhe
7724 || icode == CODE_FOR_spe_evlwhos
7725 || icode == CODE_FOR_spe_evlwhou
7726 || icode == CODE_FOR_spe_evlwhsplat
7727 || icode == CODE_FOR_spe_evlwwsplat
7728 || icode == CODE_FOR_spe_evrlwi
7729 || icode == CODE_FOR_spe_evslwi
7730 || icode == CODE_FOR_spe_evsrwis
7731 || icode == CODE_FOR_spe_evsubifw
7732 || icode == CODE_FOR_spe_evsrwiu)
7734 /* Only allow 5-bit unsigned literals. */
7735 STRIP_NOPS (arg1);
7736 if (TREE_CODE (arg1) != INTEGER_CST
7737 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7739 error ("argument 2 must be a 5-bit unsigned literal");
7740 return const0_rtx;
7744 if (target == 0
7745 || GET_MODE (target) != tmode
7746 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7747 target = gen_reg_rtx (tmode);
7749 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7750 op0 = copy_to_mode_reg (mode0, op0);
7751 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7752 op1 = copy_to_mode_reg (mode1, op1);
7754 pat = GEN_FCN (icode) (target, op0, op1);
7755 if (! pat)
7756 return 0;
7757 emit_insn (pat);
7759 return target;
7762 static rtx
7763 altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
7764 tree exp, rtx target)
7766 rtx pat, scratch;
7767 tree cr6_form = CALL_EXPR_ARG (exp, 0);
7768 tree arg0 = CALL_EXPR_ARG (exp, 1);
7769 tree arg1 = CALL_EXPR_ARG (exp, 2);
7770 rtx op0 = expand_normal (arg0);
7771 rtx op1 = expand_normal (arg1);
7772 enum machine_mode tmode = SImode;
7773 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7774 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7775 int cr6_form_int;
7777 if (TREE_CODE (cr6_form) != INTEGER_CST)
7779 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7780 return const0_rtx;
7782 else
7783 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
7785 gcc_assert (mode0 == mode1);
7787 /* If we have invalid arguments, bail out before generating bad rtl. */
7788 if (arg0 == error_mark_node || arg1 == error_mark_node)
7789 return const0_rtx;
7791 if (target == 0
7792 || GET_MODE (target) != tmode
7793 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7794 target = gen_reg_rtx (tmode);
7796 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7797 op0 = copy_to_mode_reg (mode0, op0);
7798 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7799 op1 = copy_to_mode_reg (mode1, op1);
7801 scratch = gen_reg_rtx (mode0);
7803 pat = GEN_FCN (icode) (scratch, op0, op1,
7804 gen_rtx_SYMBOL_REF (Pmode, opcode));
7805 if (! pat)
7806 return 0;
7807 emit_insn (pat);
7809 /* The vec_any* and vec_all* predicates use the same opcodes for two
7810 different operations, but the bits in CR6 will be different
7811 depending on what information we want. So we have to play tricks
7812 with CR6 to get the right bits out.
7814 If you think this is disgusting, look at the specs for the
7815 AltiVec predicates. */
7817 switch (cr6_form_int)
7819 case 0:
7820 emit_insn (gen_cr6_test_for_zero (target));
7821 break;
7822 case 1:
7823 emit_insn (gen_cr6_test_for_zero_reverse (target));
7824 break;
7825 case 2:
7826 emit_insn (gen_cr6_test_for_lt (target));
7827 break;
7828 case 3:
7829 emit_insn (gen_cr6_test_for_lt_reverse (target));
7830 break;
7831 default:
7832 error ("argument 1 of __builtin_altivec_predicate is out of range");
7833 break;
7836 return target;
7839 static rtx
7840 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
7842 rtx pat, addr;
7843 tree arg0 = CALL_EXPR_ARG (exp, 0);
7844 tree arg1 = CALL_EXPR_ARG (exp, 1);
7845 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7846 enum machine_mode mode0 = Pmode;
7847 enum machine_mode mode1 = Pmode;
7848 rtx op0 = expand_normal (arg0);
7849 rtx op1 = expand_normal (arg1);
7851 if (icode == CODE_FOR_nothing)
7852 /* Builtin not supported on this processor. */
7853 return 0;
7855 /* If we got invalid arguments bail out before generating bad rtl. */
7856 if (arg0 == error_mark_node || arg1 == error_mark_node)
7857 return const0_rtx;
7859 if (target == 0
7860 || GET_MODE (target) != tmode
7861 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7862 target = gen_reg_rtx (tmode);
7864 op1 = copy_to_mode_reg (mode1, op1);
7866 if (op0 == const0_rtx)
7868 addr = gen_rtx_MEM (tmode, op1);
7870 else
7872 op0 = copy_to_mode_reg (mode0, op0);
7873 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7876 pat = GEN_FCN (icode) (target, addr);
7878 if (! pat)
7879 return 0;
7880 emit_insn (pat);
7882 return target;
7885 static rtx
7886 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
7888 rtx pat, addr;
7889 tree arg0 = CALL_EXPR_ARG (exp, 0);
7890 tree arg1 = CALL_EXPR_ARG (exp, 1);
7891 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7892 enum machine_mode mode0 = Pmode;
7893 enum machine_mode mode1 = Pmode;
7894 rtx op0 = expand_normal (arg0);
7895 rtx op1 = expand_normal (arg1);
7897 if (icode == CODE_FOR_nothing)
7898 /* Builtin not supported on this processor. */
7899 return 0;
7901 /* If we got invalid arguments bail out before generating bad rtl. */
7902 if (arg0 == error_mark_node || arg1 == error_mark_node)
7903 return const0_rtx;
7905 if (target == 0
7906 || GET_MODE (target) != tmode
7907 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7908 target = gen_reg_rtx (tmode);
7910 op1 = copy_to_mode_reg (mode1, op1);
7912 if (op0 == const0_rtx)
7914 addr = gen_rtx_MEM (tmode, op1);
7916 else
7918 op0 = copy_to_mode_reg (mode0, op0);
7919 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7922 pat = GEN_FCN (icode) (target, addr);
7924 if (! pat)
7925 return 0;
7926 emit_insn (pat);
7928 return target;
7931 static rtx
7932 spe_expand_stv_builtin (enum insn_code icode, tree exp)
7934 tree arg0 = CALL_EXPR_ARG (exp, 0);
7935 tree arg1 = CALL_EXPR_ARG (exp, 1);
7936 tree arg2 = CALL_EXPR_ARG (exp, 2);
7937 rtx op0 = expand_normal (arg0);
7938 rtx op1 = expand_normal (arg1);
7939 rtx op2 = expand_normal (arg2);
7940 rtx pat;
7941 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
7942 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
7943 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
7945 /* Invalid arguments. Bail before doing anything stoopid! */
7946 if (arg0 == error_mark_node
7947 || arg1 == error_mark_node
7948 || arg2 == error_mark_node)
7949 return const0_rtx;
7951 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
7952 op0 = copy_to_mode_reg (mode2, op0);
7953 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
7954 op1 = copy_to_mode_reg (mode0, op1);
7955 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7956 op2 = copy_to_mode_reg (mode1, op2);
7958 pat = GEN_FCN (icode) (op1, op2, op0);
7959 if (pat)
7960 emit_insn (pat);
7961 return NULL_RTX;
7964 static rtx
7965 paired_expand_stv_builtin (enum insn_code icode, tree exp)
7967 tree arg0 = CALL_EXPR_ARG (exp, 0);
7968 tree arg1 = CALL_EXPR_ARG (exp, 1);
7969 tree arg2 = CALL_EXPR_ARG (exp, 2);
7970 rtx op0 = expand_normal (arg0);
7971 rtx op1 = expand_normal (arg1);
7972 rtx op2 = expand_normal (arg2);
7973 rtx pat, addr;
7974 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7975 enum machine_mode mode1 = Pmode;
7976 enum machine_mode mode2 = Pmode;
7978 /* Invalid arguments. Bail before doing anything stoopid! */
7979 if (arg0 == error_mark_node
7980 || arg1 == error_mark_node
7981 || arg2 == error_mark_node)
7982 return const0_rtx;
7984 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
7985 op0 = copy_to_mode_reg (tmode, op0);
7987 op2 = copy_to_mode_reg (mode2, op2);
7989 if (op1 == const0_rtx)
7991 addr = gen_rtx_MEM (tmode, op2);
7993 else
7995 op1 = copy_to_mode_reg (mode1, op1);
7996 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
7999 pat = GEN_FCN (icode) (addr, op0);
8000 if (pat)
8001 emit_insn (pat);
8002 return NULL_RTX;
8005 static rtx
8006 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
8008 tree arg0 = CALL_EXPR_ARG (exp, 0);
8009 tree arg1 = CALL_EXPR_ARG (exp, 1);
8010 tree arg2 = CALL_EXPR_ARG (exp, 2);
8011 rtx op0 = expand_normal (arg0);
8012 rtx op1 = expand_normal (arg1);
8013 rtx op2 = expand_normal (arg2);
8014 rtx pat, addr;
8015 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8016 enum machine_mode mode1 = Pmode;
8017 enum machine_mode mode2 = Pmode;
8019 /* Invalid arguments. Bail before doing anything stoopid! */
8020 if (arg0 == error_mark_node
8021 || arg1 == error_mark_node
8022 || arg2 == error_mark_node)
8023 return const0_rtx;
8025 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
8026 op0 = copy_to_mode_reg (tmode, op0);
8028 op2 = copy_to_mode_reg (mode2, op2);
8030 if (op1 == const0_rtx)
8032 addr = gen_rtx_MEM (tmode, op2);
8034 else
8036 op1 = copy_to_mode_reg (mode1, op1);
8037 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
8040 pat = GEN_FCN (icode) (addr, op0);
8041 if (pat)
8042 emit_insn (pat);
8043 return NULL_RTX;
8046 static rtx
8047 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
8049 rtx pat;
8050 tree arg0 = CALL_EXPR_ARG (exp, 0);
8051 tree arg1 = CALL_EXPR_ARG (exp, 1);
8052 tree arg2 = CALL_EXPR_ARG (exp, 2);
8053 rtx op0 = expand_normal (arg0);
8054 rtx op1 = expand_normal (arg1);
8055 rtx op2 = expand_normal (arg2);
8056 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8057 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8058 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8059 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
8061 if (icode == CODE_FOR_nothing)
8062 /* Builtin not supported on this processor. */
8063 return 0;
8065 /* If we got invalid arguments bail out before generating bad rtl. */
8066 if (arg0 == error_mark_node
8067 || arg1 == error_mark_node
8068 || arg2 == error_mark_node)
8069 return const0_rtx;
8071 if (icode == CODE_FOR_altivec_vsldoi_v4sf
8072 || icode == CODE_FOR_altivec_vsldoi_v4si
8073 || icode == CODE_FOR_altivec_vsldoi_v8hi
8074 || icode == CODE_FOR_altivec_vsldoi_v16qi)
8076 /* Only allow 4-bit unsigned literals. */
8077 STRIP_NOPS (arg2);
8078 if (TREE_CODE (arg2) != INTEGER_CST
8079 || TREE_INT_CST_LOW (arg2) & ~0xf)
8081 error ("argument 3 must be a 4-bit unsigned literal");
8082 return const0_rtx;
8086 if (target == 0
8087 || GET_MODE (target) != tmode
8088 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8089 target = gen_reg_rtx (tmode);
8091 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8092 op0 = copy_to_mode_reg (mode0, op0);
8093 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
8094 op1 = copy_to_mode_reg (mode1, op1);
8095 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
8096 op2 = copy_to_mode_reg (mode2, op2);
8098 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
8099 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
8100 else
8101 pat = GEN_FCN (icode) (target, op0, op1, op2);
8102 if (! pat)
8103 return 0;
8104 emit_insn (pat);
8106 return target;
8109 /* Expand the lvx builtins. */
8110 static rtx
8111 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
8113 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8114 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8115 tree arg0;
8116 enum machine_mode tmode, mode0;
8117 rtx pat, op0;
8118 enum insn_code icode;
8120 switch (fcode)
8122 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
8123 icode = CODE_FOR_altivec_lvx_v16qi;
8124 break;
8125 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
8126 icode = CODE_FOR_altivec_lvx_v8hi;
8127 break;
8128 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
8129 icode = CODE_FOR_altivec_lvx_v4si;
8130 break;
8131 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
8132 icode = CODE_FOR_altivec_lvx_v4sf;
8133 break;
8134 default:
8135 *expandedp = false;
8136 return NULL_RTX;
8139 *expandedp = true;
8141 arg0 = CALL_EXPR_ARG (exp, 0);
8142 op0 = expand_normal (arg0);
8143 tmode = insn_data[icode].operand[0].mode;
8144 mode0 = insn_data[icode].operand[1].mode;
8146 if (target == 0
8147 || GET_MODE (target) != tmode
8148 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8149 target = gen_reg_rtx (tmode);
8151 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8152 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
8154 pat = GEN_FCN (icode) (target, op0);
8155 if (! pat)
8156 return 0;
8157 emit_insn (pat);
8158 return target;
8161 /* Expand the stvx builtins. */
8162 static rtx
8163 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
8164 bool *expandedp)
8166 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8167 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8168 tree arg0, arg1;
8169 enum machine_mode mode0, mode1;
8170 rtx pat, op0, op1;
8171 enum insn_code icode;
8173 switch (fcode)
8175 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
8176 icode = CODE_FOR_altivec_stvx_v16qi;
8177 break;
8178 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
8179 icode = CODE_FOR_altivec_stvx_v8hi;
8180 break;
8181 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
8182 icode = CODE_FOR_altivec_stvx_v4si;
8183 break;
8184 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
8185 icode = CODE_FOR_altivec_stvx_v4sf;
8186 break;
8187 default:
8188 *expandedp = false;
8189 return NULL_RTX;
8192 arg0 = CALL_EXPR_ARG (exp, 0);
8193 arg1 = CALL_EXPR_ARG (exp, 1);
8194 op0 = expand_normal (arg0);
8195 op1 = expand_normal (arg1);
8196 mode0 = insn_data[icode].operand[0].mode;
8197 mode1 = insn_data[icode].operand[1].mode;
8199 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8200 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
8201 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
8202 op1 = copy_to_mode_reg (mode1, op1);
8204 pat = GEN_FCN (icode) (op0, op1);
8205 if (pat)
8206 emit_insn (pat);
8208 *expandedp = true;
8209 return NULL_RTX;
8212 /* Expand the dst builtins. */
8213 static rtx
8214 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
8215 bool *expandedp)
8217 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8218 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8219 tree arg0, arg1, arg2;
8220 enum machine_mode mode0, mode1, mode2;
8221 rtx pat, op0, op1, op2;
8222 const struct builtin_description *d;
8223 size_t i;
8225 *expandedp = false;
8227 /* Handle DST variants. */
8228 d = bdesc_dst;
8229 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8230 if (d->code == fcode)
8232 arg0 = CALL_EXPR_ARG (exp, 0);
8233 arg1 = CALL_EXPR_ARG (exp, 1);
8234 arg2 = CALL_EXPR_ARG (exp, 2);
8235 op0 = expand_normal (arg0);
8236 op1 = expand_normal (arg1);
8237 op2 = expand_normal (arg2);
8238 mode0 = insn_data[d->icode].operand[0].mode;
8239 mode1 = insn_data[d->icode].operand[1].mode;
8240 mode2 = insn_data[d->icode].operand[2].mode;
8242 /* Invalid arguments, bail out before generating bad rtl. */
8243 if (arg0 == error_mark_node
8244 || arg1 == error_mark_node
8245 || arg2 == error_mark_node)
8246 return const0_rtx;
8248 *expandedp = true;
8249 STRIP_NOPS (arg2);
8250 if (TREE_CODE (arg2) != INTEGER_CST
8251 || TREE_INT_CST_LOW (arg2) & ~0x3)
8253 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
8254 return const0_rtx;
8257 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
8258 op0 = copy_to_mode_reg (Pmode, op0);
8259 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
8260 op1 = copy_to_mode_reg (mode1, op1);
8262 pat = GEN_FCN (d->icode) (op0, op1, op2);
8263 if (pat != 0)
8264 emit_insn (pat);
8266 return NULL_RTX;
8269 return NULL_RTX;
8272 /* Expand vec_init builtin. */
8273 static rtx
8274 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
8276 enum machine_mode tmode = TYPE_MODE (type);
8277 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
8278 int i, n_elt = GET_MODE_NUNITS (tmode);
8279 rtvec v = rtvec_alloc (n_elt);
8281 gcc_assert (VECTOR_MODE_P (tmode));
8282 gcc_assert (n_elt == call_expr_nargs (exp));
8284 for (i = 0; i < n_elt; ++i)
8286 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
8287 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
8290 if (!target || !register_operand (target, tmode))
8291 target = gen_reg_rtx (tmode);
8293 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
8294 return target;
8297 /* Return the integer constant in ARG. Constrain it to be in the range
8298 of the subparts of VEC_TYPE; issue an error if not. */
8300 static int
8301 get_element_number (tree vec_type, tree arg)
8303 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
8305 if (!host_integerp (arg, 1)
8306 || (elt = tree_low_cst (arg, 1), elt > max))
8308 error ("selector must be an integer constant in the range 0..%wi", max);
8309 return 0;
8312 return elt;
8315 /* Expand vec_set builtin. */
8316 static rtx
8317 altivec_expand_vec_set_builtin (tree exp)
8319 enum machine_mode tmode, mode1;
8320 tree arg0, arg1, arg2;
8321 int elt;
8322 rtx op0, op1;
8324 arg0 = CALL_EXPR_ARG (exp, 0);
8325 arg1 = CALL_EXPR_ARG (exp, 1);
8326 arg2 = CALL_EXPR_ARG (exp, 2);
8328 tmode = TYPE_MODE (TREE_TYPE (arg0));
8329 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
8330 gcc_assert (VECTOR_MODE_P (tmode));
8332 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
8333 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
8334 elt = get_element_number (TREE_TYPE (arg0), arg2);
8336 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
8337 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
8339 op0 = force_reg (tmode, op0);
8340 op1 = force_reg (mode1, op1);
8342 rs6000_expand_vector_set (op0, op1, elt);
8344 return op0;
8347 /* Expand vec_ext builtin. */
8348 static rtx
8349 altivec_expand_vec_ext_builtin (tree exp, rtx target)
8351 enum machine_mode tmode, mode0;
8352 tree arg0, arg1;
8353 int elt;
8354 rtx op0;
8356 arg0 = CALL_EXPR_ARG (exp, 0);
8357 arg1 = CALL_EXPR_ARG (exp, 1);
8359 op0 = expand_normal (arg0);
8360 elt = get_element_number (TREE_TYPE (arg0), arg1);
8362 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
8363 mode0 = TYPE_MODE (TREE_TYPE (arg0));
8364 gcc_assert (VECTOR_MODE_P (mode0));
8366 op0 = force_reg (mode0, op0);
8368 if (optimize || !target || !register_operand (target, tmode))
8369 target = gen_reg_rtx (tmode);
8371 rs6000_expand_vector_extract (target, op0, elt);
8373 return target;
8376 /* Expand the builtin in EXP and store the result in TARGET. Store
8377 true in *EXPANDEDP if we found a builtin to expand. */
8378 static rtx
8379 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
8381 const struct builtin_description *d;
8382 const struct builtin_description_predicates *dp;
8383 size_t i;
8384 enum insn_code icode;
8385 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8386 tree arg0;
8387 rtx op0, pat;
8388 enum machine_mode tmode, mode0;
8389 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8391 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8392 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
8394 *expandedp = true;
8395 error ("unresolved overload for Altivec builtin %qF", fndecl);
8396 return const0_rtx;
8399 target = altivec_expand_ld_builtin (exp, target, expandedp);
8400 if (*expandedp)
8401 return target;
8403 target = altivec_expand_st_builtin (exp, target, expandedp);
8404 if (*expandedp)
8405 return target;
8407 target = altivec_expand_dst_builtin (exp, target, expandedp);
8408 if (*expandedp)
8409 return target;
8411 *expandedp = true;
8413 switch (fcode)
8415 case ALTIVEC_BUILTIN_STVX:
8416 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
8417 case ALTIVEC_BUILTIN_STVEBX:
8418 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
8419 case ALTIVEC_BUILTIN_STVEHX:
8420 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
8421 case ALTIVEC_BUILTIN_STVEWX:
8422 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
8423 case ALTIVEC_BUILTIN_STVXL:
8424 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
8426 case ALTIVEC_BUILTIN_MFVSCR:
8427 icode = CODE_FOR_altivec_mfvscr;
8428 tmode = insn_data[icode].operand[0].mode;
8430 if (target == 0
8431 || GET_MODE (target) != tmode
8432 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8433 target = gen_reg_rtx (tmode);
8435 pat = GEN_FCN (icode) (target);
8436 if (! pat)
8437 return 0;
8438 emit_insn (pat);
8439 return target;
8441 case ALTIVEC_BUILTIN_MTVSCR:
8442 icode = CODE_FOR_altivec_mtvscr;
8443 arg0 = CALL_EXPR_ARG (exp, 0);
8444 op0 = expand_normal (arg0);
8445 mode0 = insn_data[icode].operand[0].mode;
8447 /* If we got invalid arguments bail out before generating bad rtl. */
8448 if (arg0 == error_mark_node)
8449 return const0_rtx;
8451 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8452 op0 = copy_to_mode_reg (mode0, op0);
8454 pat = GEN_FCN (icode) (op0);
8455 if (pat)
8456 emit_insn (pat);
8457 return NULL_RTX;
8459 case ALTIVEC_BUILTIN_DSSALL:
8460 emit_insn (gen_altivec_dssall ());
8461 return NULL_RTX;
8463 case ALTIVEC_BUILTIN_DSS:
8464 icode = CODE_FOR_altivec_dss;
8465 arg0 = CALL_EXPR_ARG (exp, 0);
8466 STRIP_NOPS (arg0);
8467 op0 = expand_normal (arg0);
8468 mode0 = insn_data[icode].operand[0].mode;
8470 /* If we got invalid arguments bail out before generating bad rtl. */
8471 if (arg0 == error_mark_node)
8472 return const0_rtx;
8474 if (TREE_CODE (arg0) != INTEGER_CST
8475 || TREE_INT_CST_LOW (arg0) & ~0x3)
8477 error ("argument to dss must be a 2-bit unsigned literal");
8478 return const0_rtx;
8481 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8482 op0 = copy_to_mode_reg (mode0, op0);
8484 emit_insn (gen_altivec_dss (op0));
8485 return NULL_RTX;
8487 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
8488 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
8489 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
8490 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
8491 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
8493 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
8494 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
8495 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
8496 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
8497 return altivec_expand_vec_set_builtin (exp);
8499 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
8500 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
8501 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
8502 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
8503 return altivec_expand_vec_ext_builtin (exp, target);
8505 default:
8506 break;
8507 /* Fall through. */
8510 /* Expand abs* operations. */
8511 d = bdesc_abs;
8512 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
8513 if (d->code == fcode)
8514 return altivec_expand_abs_builtin (d->icode, exp, target);
8516 /* Expand the AltiVec predicates. */
8517 dp = bdesc_altivec_preds;
8518 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
8519 if (dp->code == fcode)
8520 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
8521 exp, target);
8523 /* LV* are funky. We initialized them differently. */
8524 switch (fcode)
8526 case ALTIVEC_BUILTIN_LVSL:
8527 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
8528 exp, target);
8529 case ALTIVEC_BUILTIN_LVSR:
8530 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
8531 exp, target);
8532 case ALTIVEC_BUILTIN_LVEBX:
8533 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
8534 exp, target);
8535 case ALTIVEC_BUILTIN_LVEHX:
8536 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
8537 exp, target);
8538 case ALTIVEC_BUILTIN_LVEWX:
8539 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
8540 exp, target);
8541 case ALTIVEC_BUILTIN_LVXL:
8542 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
8543 exp, target);
8544 case ALTIVEC_BUILTIN_LVX:
8545 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
8546 exp, target);
8547 default:
8548 break;
8549 /* Fall through. */
8552 *expandedp = false;
8553 return NULL_RTX;
8556 /* Expand the builtin in EXP and store the result in TARGET. Store
8557 true in *EXPANDEDP if we found a builtin to expand. */
8558 static rtx
8559 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
8561 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8562 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8563 const struct builtin_description *d;
8564 size_t i;
8566 *expandedp = true;
8568 switch (fcode)
8570 case PAIRED_BUILTIN_STX:
8571 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
8572 case PAIRED_BUILTIN_LX:
8573 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
8574 default:
8575 break;
8576 /* Fall through. */
8579 /* Expand the paired predicates. */
8580 d = bdesc_paired_preds;
8581 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
8582 if (d->code == fcode)
8583 return paired_expand_predicate_builtin (d->icode, exp, target);
8585 *expandedp = false;
8586 return NULL_RTX;
8589 /* Binops that need to be initialized manually, but can be expanded
8590 automagically by rs6000_expand_binop_builtin. */
8591 static struct builtin_description bdesc_2arg_spe[] =
8593 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
8594 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
8595 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
8596 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
8597 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
8598 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
8599 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
8600 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
8601 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
8602 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
8603 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
8604 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
8605 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
8606 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
8607 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
8608 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
8609 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
8610 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
8611 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
8612 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
8613 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
8614 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
8617 /* Expand the builtin in EXP and store the result in TARGET. Store
8618 true in *EXPANDEDP if we found a builtin to expand.
8620 This expands the SPE builtins that are not simple unary and binary
8621 operations. */
8622 static rtx
8623 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
8625 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8626 tree arg1, arg0;
8627 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8628 enum insn_code icode;
8629 enum machine_mode tmode, mode0;
8630 rtx pat, op0;
8631 struct builtin_description *d;
8632 size_t i;
8634 *expandedp = true;
8636 /* Syntax check for a 5-bit unsigned immediate. */
8637 switch (fcode)
8639 case SPE_BUILTIN_EVSTDD:
8640 case SPE_BUILTIN_EVSTDH:
8641 case SPE_BUILTIN_EVSTDW:
8642 case SPE_BUILTIN_EVSTWHE:
8643 case SPE_BUILTIN_EVSTWHO:
8644 case SPE_BUILTIN_EVSTWWE:
8645 case SPE_BUILTIN_EVSTWWO:
8646 arg1 = CALL_EXPR_ARG (exp, 2);
8647 if (TREE_CODE (arg1) != INTEGER_CST
8648 || TREE_INT_CST_LOW (arg1) & ~0x1f)
8650 error ("argument 2 must be a 5-bit unsigned literal");
8651 return const0_rtx;
8653 break;
8654 default:
8655 break;
8658 /* The evsplat*i instructions are not quite generic. */
8659 switch (fcode)
8661 case SPE_BUILTIN_EVSPLATFI:
8662 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
8663 exp, target);
8664 case SPE_BUILTIN_EVSPLATI:
8665 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
8666 exp, target);
8667 default:
8668 break;
8671 d = (struct builtin_description *) bdesc_2arg_spe;
8672 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
8673 if (d->code == fcode)
8674 return rs6000_expand_binop_builtin (d->icode, exp, target);
8676 d = (struct builtin_description *) bdesc_spe_predicates;
8677 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
8678 if (d->code == fcode)
8679 return spe_expand_predicate_builtin (d->icode, exp, target);
8681 d = (struct builtin_description *) bdesc_spe_evsel;
8682 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
8683 if (d->code == fcode)
8684 return spe_expand_evsel_builtin (d->icode, exp, target);
8686 switch (fcode)
8688 case SPE_BUILTIN_EVSTDDX:
8689 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
8690 case SPE_BUILTIN_EVSTDHX:
8691 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
8692 case SPE_BUILTIN_EVSTDWX:
8693 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
8694 case SPE_BUILTIN_EVSTWHEX:
8695 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
8696 case SPE_BUILTIN_EVSTWHOX:
8697 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
8698 case SPE_BUILTIN_EVSTWWEX:
8699 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
8700 case SPE_BUILTIN_EVSTWWOX:
8701 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
8702 case SPE_BUILTIN_EVSTDD:
8703 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
8704 case SPE_BUILTIN_EVSTDH:
8705 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
8706 case SPE_BUILTIN_EVSTDW:
8707 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
8708 case SPE_BUILTIN_EVSTWHE:
8709 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
8710 case SPE_BUILTIN_EVSTWHO:
8711 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
8712 case SPE_BUILTIN_EVSTWWE:
8713 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
8714 case SPE_BUILTIN_EVSTWWO:
8715 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
8716 case SPE_BUILTIN_MFSPEFSCR:
8717 icode = CODE_FOR_spe_mfspefscr;
8718 tmode = insn_data[icode].operand[0].mode;
8720 if (target == 0
8721 || GET_MODE (target) != tmode
8722 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8723 target = gen_reg_rtx (tmode);
8725 pat = GEN_FCN (icode) (target);
8726 if (! pat)
8727 return 0;
8728 emit_insn (pat);
8729 return target;
8730 case SPE_BUILTIN_MTSPEFSCR:
8731 icode = CODE_FOR_spe_mtspefscr;
8732 arg0 = CALL_EXPR_ARG (exp, 0);
8733 op0 = expand_normal (arg0);
8734 mode0 = insn_data[icode].operand[0].mode;
8736 if (arg0 == error_mark_node)
8737 return const0_rtx;
8739 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8740 op0 = copy_to_mode_reg (mode0, op0);
8742 pat = GEN_FCN (icode) (op0);
8743 if (pat)
8744 emit_insn (pat);
8745 return NULL_RTX;
8746 default:
8747 break;
8750 *expandedp = false;
8751 return NULL_RTX;
8754 static rtx
8755 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
8757 rtx pat, scratch, tmp;
8758 tree form = CALL_EXPR_ARG (exp, 0);
8759 tree arg0 = CALL_EXPR_ARG (exp, 1);
8760 tree arg1 = CALL_EXPR_ARG (exp, 2);
8761 rtx op0 = expand_normal (arg0);
8762 rtx op1 = expand_normal (arg1);
8763 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8764 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8765 int form_int;
8766 enum rtx_code code;
8768 if (TREE_CODE (form) != INTEGER_CST)
8770 error ("argument 1 of __builtin_paired_predicate must be a constant");
8771 return const0_rtx;
8773 else
8774 form_int = TREE_INT_CST_LOW (form);
8776 gcc_assert (mode0 == mode1);
8778 if (arg0 == error_mark_node || arg1 == error_mark_node)
8779 return const0_rtx;
8781 if (target == 0
8782 || GET_MODE (target) != SImode
8783 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
8784 target = gen_reg_rtx (SImode);
8785 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
8786 op0 = copy_to_mode_reg (mode0, op0);
8787 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
8788 op1 = copy_to_mode_reg (mode1, op1);
8790 scratch = gen_reg_rtx (CCFPmode);
8792 pat = GEN_FCN (icode) (scratch, op0, op1);
8793 if (!pat)
8794 return const0_rtx;
8796 emit_insn (pat);
8798 switch (form_int)
8800 /* LT bit. */
8801 case 0:
8802 code = LT;
8803 break;
8804 /* GT bit. */
8805 case 1:
8806 code = GT;
8807 break;
8808 /* EQ bit. */
8809 case 2:
8810 code = EQ;
8811 break;
8812 /* UN bit. */
8813 case 3:
8814 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
8815 return target;
8816 default:
8817 error ("argument 1 of __builtin_paired_predicate is out of range");
8818 return const0_rtx;
8821 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8822 emit_move_insn (target, tmp);
8823 return target;
8826 static rtx
8827 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
8829 rtx pat, scratch, tmp;
8830 tree form = CALL_EXPR_ARG (exp, 0);
8831 tree arg0 = CALL_EXPR_ARG (exp, 1);
8832 tree arg1 = CALL_EXPR_ARG (exp, 2);
8833 rtx op0 = expand_normal (arg0);
8834 rtx op1 = expand_normal (arg1);
8835 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8836 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8837 int form_int;
8838 enum rtx_code code;
8840 if (TREE_CODE (form) != INTEGER_CST)
8842 error ("argument 1 of __builtin_spe_predicate must be a constant");
8843 return const0_rtx;
8845 else
8846 form_int = TREE_INT_CST_LOW (form);
8848 gcc_assert (mode0 == mode1);
8850 if (arg0 == error_mark_node || arg1 == error_mark_node)
8851 return const0_rtx;
8853 if (target == 0
8854 || GET_MODE (target) != SImode
8855 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
8856 target = gen_reg_rtx (SImode);
8858 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8859 op0 = copy_to_mode_reg (mode0, op0);
8860 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
8861 op1 = copy_to_mode_reg (mode1, op1);
8863 scratch = gen_reg_rtx (CCmode);
8865 pat = GEN_FCN (icode) (scratch, op0, op1);
8866 if (! pat)
8867 return const0_rtx;
8868 emit_insn (pat);
8870 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
8871 _lower_. We use one compare, but look in different bits of the
8872 CR for each variant.
8874 There are 2 elements in each SPE simd type (upper/lower). The CR
8875 bits are set as follows:
8877 BIT0 | BIT 1 | BIT 2 | BIT 3
8878 U | L | (U | L) | (U & L)
8880 So, for an "all" relationship, BIT 3 would be set.
8881 For an "any" relationship, BIT 2 would be set. Etc.
8883 Following traditional nomenclature, these bits map to:
8885 BIT0 | BIT 1 | BIT 2 | BIT 3
8886 LT | GT | EQ | OV
8888 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8891 switch (form_int)
8893 /* All variant. OV bit. */
8894 case 0:
8895 /* We need to get to the OV bit, which is the ORDERED bit. We
8896 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
8897 that's ugly and will make validate_condition_mode die.
8898 So let's just use another pattern. */
8899 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
8900 return target;
8901 /* Any variant. EQ bit. */
8902 case 1:
8903 code = EQ;
8904 break;
8905 /* Upper variant. LT bit. */
8906 case 2:
8907 code = LT;
8908 break;
8909 /* Lower variant. GT bit. */
8910 case 3:
8911 code = GT;
8912 break;
8913 default:
8914 error ("argument 1 of __builtin_spe_predicate is out of range");
8915 return const0_rtx;
8918 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8919 emit_move_insn (target, tmp);
8921 return target;
8924 /* The evsel builtins look like this:
8926 e = __builtin_spe_evsel_OP (a, b, c, d);
8928 and work like this:
8930 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8931 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8934 static rtx
8935 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
8937 rtx pat, scratch;
8938 tree arg0 = CALL_EXPR_ARG (exp, 0);
8939 tree arg1 = CALL_EXPR_ARG (exp, 1);
8940 tree arg2 = CALL_EXPR_ARG (exp, 2);
8941 tree arg3 = CALL_EXPR_ARG (exp, 3);
8942 rtx op0 = expand_normal (arg0);
8943 rtx op1 = expand_normal (arg1);
8944 rtx op2 = expand_normal (arg2);
8945 rtx op3 = expand_normal (arg3);
8946 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8947 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8949 gcc_assert (mode0 == mode1);
8951 if (arg0 == error_mark_node || arg1 == error_mark_node
8952 || arg2 == error_mark_node || arg3 == error_mark_node)
8953 return const0_rtx;
8955 if (target == 0
8956 || GET_MODE (target) != mode0
8957 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
8958 target = gen_reg_rtx (mode0);
8960 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8961 op0 = copy_to_mode_reg (mode0, op0);
8962 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
8963 op1 = copy_to_mode_reg (mode0, op1);
8964 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
8965 op2 = copy_to_mode_reg (mode0, op2);
8966 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
8967 op3 = copy_to_mode_reg (mode0, op3);
8969 /* Generate the compare. */
8970 scratch = gen_reg_rtx (CCmode);
8971 pat = GEN_FCN (icode) (scratch, op0, op1);
8972 if (! pat)
8973 return const0_rtx;
8974 emit_insn (pat);
8976 if (mode0 == V2SImode)
8977 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
8978 else
8979 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
8981 return target;
8984 /* Expand an expression EXP that calls a built-in function,
8985 with result going to TARGET if that's convenient
8986 (and in mode MODE if that's convenient).
8987 SUBTARGET may be used as the target for computing one of EXP's operands.
8988 IGNORE is nonzero if the value is to be ignored. */
8990 static rtx
8991 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8992 enum machine_mode mode ATTRIBUTE_UNUSED,
8993 int ignore ATTRIBUTE_UNUSED)
8995 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8996 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8997 const struct builtin_description *d;
8998 size_t i;
8999 rtx ret;
9000 bool success;
9002 if (fcode == RS6000_BUILTIN_RECIP)
9003 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
9005 if (fcode == RS6000_BUILTIN_RECIPF)
9006 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
9008 if (fcode == RS6000_BUILTIN_RSQRTF)
9009 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
9011 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
9012 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
9014 int icode = (int) CODE_FOR_altivec_lvsr;
9015 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9016 enum machine_mode mode = insn_data[icode].operand[1].mode;
9017 tree arg;
9018 rtx op, addr, pat;
9020 gcc_assert (TARGET_ALTIVEC);
9022 arg = CALL_EXPR_ARG (exp, 0);
9023 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
9024 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
9025 addr = memory_address (mode, op);
9026 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
9027 op = addr;
9028 else
9030 /* For the load case need to negate the address. */
9031 op = gen_reg_rtx (GET_MODE (addr));
9032 emit_insn (gen_rtx_SET (VOIDmode, op,
9033 gen_rtx_NEG (GET_MODE (addr), addr)));
9035 op = gen_rtx_MEM (mode, op);
9037 if (target == 0
9038 || GET_MODE (target) != tmode
9039 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9040 target = gen_reg_rtx (tmode);
9042 /*pat = gen_altivec_lvsr (target, op);*/
9043 pat = GEN_FCN (icode) (target, op);
9044 if (!pat)
9045 return 0;
9046 emit_insn (pat);
9048 return target;
9051 /* FIXME: There's got to be a nicer way to handle this case than
9052 constructing a new CALL_EXPR. */
9053 if (fcode == ALTIVEC_BUILTIN_VCFUX
9054 || fcode == ALTIVEC_BUILTIN_VCFSX)
9056 if (call_expr_nargs (exp) == 1)
9057 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
9058 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
9061 if (TARGET_ALTIVEC)
9063 ret = altivec_expand_builtin (exp, target, &success);
9065 if (success)
9066 return ret;
9068 if (TARGET_SPE)
9070 ret = spe_expand_builtin (exp, target, &success);
9072 if (success)
9073 return ret;
9075 if (TARGET_PAIRED_FLOAT)
9077 ret = paired_expand_builtin (exp, target, &success);
9079 if (success)
9080 return ret;
9083 gcc_assert (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT);
9085 /* Handle simple unary operations. */
9086 d = (struct builtin_description *) bdesc_1arg;
9087 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
9088 if (d->code == fcode)
9089 return rs6000_expand_unop_builtin (d->icode, exp, target);
9091 /* Handle simple binary operations. */
9092 d = (struct builtin_description *) bdesc_2arg;
9093 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
9094 if (d->code == fcode)
9095 return rs6000_expand_binop_builtin (d->icode, exp, target);
9097 /* Handle simple ternary operations. */
9098 d = bdesc_3arg;
9099 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
9100 if (d->code == fcode)
9101 return rs6000_expand_ternop_builtin (d->icode, exp, target);
9103 gcc_unreachable ();
9106 static tree
9107 build_opaque_vector_type (tree node, int nunits)
9109 node = copy_node (node);
9110 TYPE_MAIN_VARIANT (node) = node;
9111 return build_vector_type (node, nunits);
9114 static void
9115 rs6000_init_builtins (void)
9117 V2SI_type_node = build_vector_type (intSI_type_node, 2);
9118 V2SF_type_node = build_vector_type (float_type_node, 2);
9119 V4HI_type_node = build_vector_type (intHI_type_node, 4);
9120 V4SI_type_node = build_vector_type (intSI_type_node, 4);
9121 V4SF_type_node = build_vector_type (float_type_node, 4);
9122 V8HI_type_node = build_vector_type (intHI_type_node, 8);
9123 V16QI_type_node = build_vector_type (intQI_type_node, 16);
9125 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
9126 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
9127 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
9129 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
9130 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
9131 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
9132 opaque_V4SI_type_node = copy_node (V4SI_type_node);
9134 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
9135 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
9136 'vector unsigned short'. */
9138 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
9139 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
9140 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
9141 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
9143 long_integer_type_internal_node = long_integer_type_node;
9144 long_unsigned_type_internal_node = long_unsigned_type_node;
9145 intQI_type_internal_node = intQI_type_node;
9146 uintQI_type_internal_node = unsigned_intQI_type_node;
9147 intHI_type_internal_node = intHI_type_node;
9148 uintHI_type_internal_node = unsigned_intHI_type_node;
9149 intSI_type_internal_node = intSI_type_node;
9150 uintSI_type_internal_node = unsigned_intSI_type_node;
9151 float_type_internal_node = float_type_node;
9152 void_type_internal_node = void_type_node;
9154 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9155 get_identifier ("__bool char"),
9156 bool_char_type_node));
9157 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9158 get_identifier ("__bool short"),
9159 bool_short_type_node));
9160 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9161 get_identifier ("__bool int"),
9162 bool_int_type_node));
9163 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9164 get_identifier ("__pixel"),
9165 pixel_type_node));
9167 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
9168 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
9169 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
9170 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
9172 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9173 get_identifier ("__vector unsigned char"),
9174 unsigned_V16QI_type_node));
9175 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9176 get_identifier ("__vector signed char"),
9177 V16QI_type_node));
9178 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9179 get_identifier ("__vector __bool char"),
9180 bool_V16QI_type_node));
9182 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9183 get_identifier ("__vector unsigned short"),
9184 unsigned_V8HI_type_node));
9185 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9186 get_identifier ("__vector signed short"),
9187 V8HI_type_node));
9188 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9189 get_identifier ("__vector __bool short"),
9190 bool_V8HI_type_node));
9192 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9193 get_identifier ("__vector unsigned int"),
9194 unsigned_V4SI_type_node));
9195 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9196 get_identifier ("__vector signed int"),
9197 V4SI_type_node));
9198 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9199 get_identifier ("__vector __bool int"),
9200 bool_V4SI_type_node));
9202 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9203 get_identifier ("__vector float"),
9204 V4SF_type_node));
9205 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9206 get_identifier ("__vector __pixel"),
9207 pixel_V8HI_type_node));
9209 if (TARGET_PAIRED_FLOAT)
9210 paired_init_builtins ();
9211 if (TARGET_SPE)
9212 spe_init_builtins ();
9213 if (TARGET_ALTIVEC)
9214 altivec_init_builtins ();
9215 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT)
9216 rs6000_common_init_builtins ();
9217 if (TARGET_PPC_GFXOPT)
9219 tree ftype = build_function_type_list (float_type_node,
9220 float_type_node,
9221 float_type_node,
9222 NULL_TREE);
9223 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
9224 RS6000_BUILTIN_RECIPF);
9226 ftype = build_function_type_list (float_type_node,
9227 float_type_node,
9228 NULL_TREE);
9229 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
9230 RS6000_BUILTIN_RSQRTF);
9232 if (TARGET_POPCNTB)
9234 tree ftype = build_function_type_list (double_type_node,
9235 double_type_node,
9236 double_type_node,
9237 NULL_TREE);
9238 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
9239 RS6000_BUILTIN_RECIP);
9243 #if TARGET_XCOFF
9244 /* AIX libm provides clog as __clog. */
9245 if (built_in_decls [BUILT_IN_CLOG])
9246 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
9247 #endif
9249 #ifdef SUBTARGET_INIT_BUILTINS
9250 SUBTARGET_INIT_BUILTINS;
9251 #endif
9254 /* Search through a set of builtins and enable the mask bits.
9255 DESC is an array of builtins.
9256 SIZE is the total number of builtins.
9257 START is the builtin enum at which to start.
9258 END is the builtin enum at which to end. */
9259 static void
9260 enable_mask_for_builtins (struct builtin_description *desc, int size,
9261 enum rs6000_builtins start,
9262 enum rs6000_builtins end)
9264 int i;
9266 for (i = 0; i < size; ++i)
9267 if (desc[i].code == start)
9268 break;
9270 if (i == size)
9271 return;
9273 for (; i < size; ++i)
9275 /* Flip all the bits on. */
9276 desc[i].mask = target_flags;
9277 if (desc[i].code == end)
9278 break;
9282 static void
9283 spe_init_builtins (void)
9285 tree endlink = void_list_node;
9286 tree puint_type_node = build_pointer_type (unsigned_type_node);
9287 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
9288 struct builtin_description *d;
9289 size_t i;
9291 tree v2si_ftype_4_v2si
9292 = build_function_type
9293 (opaque_V2SI_type_node,
9294 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9295 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9296 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9297 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9298 endlink)))));
9300 tree v2sf_ftype_4_v2sf
9301 = build_function_type
9302 (opaque_V2SF_type_node,
9303 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9304 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9305 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9306 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9307 endlink)))));
9309 tree int_ftype_int_v2si_v2si
9310 = build_function_type
9311 (integer_type_node,
9312 tree_cons (NULL_TREE, integer_type_node,
9313 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9314 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9315 endlink))));
9317 tree int_ftype_int_v2sf_v2sf
9318 = build_function_type
9319 (integer_type_node,
9320 tree_cons (NULL_TREE, integer_type_node,
9321 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9322 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9323 endlink))));
9325 tree void_ftype_v2si_puint_int
9326 = build_function_type (void_type_node,
9327 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9328 tree_cons (NULL_TREE, puint_type_node,
9329 tree_cons (NULL_TREE,
9330 integer_type_node,
9331 endlink))));
9333 tree void_ftype_v2si_puint_char
9334 = build_function_type (void_type_node,
9335 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9336 tree_cons (NULL_TREE, puint_type_node,
9337 tree_cons (NULL_TREE,
9338 char_type_node,
9339 endlink))));
9341 tree void_ftype_v2si_pv2si_int
9342 = build_function_type (void_type_node,
9343 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9344 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
9345 tree_cons (NULL_TREE,
9346 integer_type_node,
9347 endlink))));
9349 tree void_ftype_v2si_pv2si_char
9350 = build_function_type (void_type_node,
9351 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9352 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
9353 tree_cons (NULL_TREE,
9354 char_type_node,
9355 endlink))));
9357 tree void_ftype_int
9358 = build_function_type (void_type_node,
9359 tree_cons (NULL_TREE, integer_type_node, endlink));
9361 tree int_ftype_void
9362 = build_function_type (integer_type_node, endlink);
9364 tree v2si_ftype_pv2si_int
9365 = build_function_type (opaque_V2SI_type_node,
9366 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
9367 tree_cons (NULL_TREE, integer_type_node,
9368 endlink)));
9370 tree v2si_ftype_puint_int
9371 = build_function_type (opaque_V2SI_type_node,
9372 tree_cons (NULL_TREE, puint_type_node,
9373 tree_cons (NULL_TREE, integer_type_node,
9374 endlink)));
9376 tree v2si_ftype_pushort_int
9377 = build_function_type (opaque_V2SI_type_node,
9378 tree_cons (NULL_TREE, pushort_type_node,
9379 tree_cons (NULL_TREE, integer_type_node,
9380 endlink)));
9382 tree v2si_ftype_signed_char
9383 = build_function_type (opaque_V2SI_type_node,
9384 tree_cons (NULL_TREE, signed_char_type_node,
9385 endlink));
9387 /* The initialization of the simple binary and unary builtins is
9388 done in rs6000_common_init_builtins, but we have to enable the
9389 mask bits here manually because we have run out of `target_flags'
9390 bits. We really need to redesign this mask business. */
9392 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
9393 ARRAY_SIZE (bdesc_2arg),
9394 SPE_BUILTIN_EVADDW,
9395 SPE_BUILTIN_EVXOR);
9396 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
9397 ARRAY_SIZE (bdesc_1arg),
9398 SPE_BUILTIN_EVABS,
9399 SPE_BUILTIN_EVSUBFUSIAAW);
9400 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
9401 ARRAY_SIZE (bdesc_spe_predicates),
9402 SPE_BUILTIN_EVCMPEQ,
9403 SPE_BUILTIN_EVFSTSTLT);
9404 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
9405 ARRAY_SIZE (bdesc_spe_evsel),
9406 SPE_BUILTIN_EVSEL_CMPGTS,
9407 SPE_BUILTIN_EVSEL_FSTSTEQ);
9409 (*lang_hooks.decls.pushdecl)
9410 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
9411 opaque_V2SI_type_node));
9413 /* Initialize irregular SPE builtins. */
9415 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
9416 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
9417 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
9418 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
9419 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
9420 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
9421 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
9422 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
9423 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
9424 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
9425 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
9426 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
9427 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
9428 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
9429 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
9430 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
9431 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
9432 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
9434 /* Loads. */
9435 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
9436 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
9437 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
9438 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
9439 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
9440 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
9441 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
9442 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
9443 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
9444 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
9445 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
9446 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
9447 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
9448 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
9449 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
9450 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
9451 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
9452 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
9453 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
9454 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
9455 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
9456 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
9458 /* Predicates. */
9459 d = (struct builtin_description *) bdesc_spe_predicates;
9460 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
9462 tree type;
9464 switch (insn_data[d->icode].operand[1].mode)
9466 case V2SImode:
9467 type = int_ftype_int_v2si_v2si;
9468 break;
9469 case V2SFmode:
9470 type = int_ftype_int_v2sf_v2sf;
9471 break;
9472 default:
9473 gcc_unreachable ();
9476 def_builtin (d->mask, d->name, type, d->code);
9479 /* Evsel predicates. */
9480 d = (struct builtin_description *) bdesc_spe_evsel;
9481 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
9483 tree type;
9485 switch (insn_data[d->icode].operand[1].mode)
9487 case V2SImode:
9488 type = v2si_ftype_4_v2si;
9489 break;
9490 case V2SFmode:
9491 type = v2sf_ftype_4_v2sf;
9492 break;
9493 default:
9494 gcc_unreachable ();
9497 def_builtin (d->mask, d->name, type, d->code);
9501 static void
9502 paired_init_builtins (void)
9504 const struct builtin_description *d;
9505 size_t i;
9506 tree endlink = void_list_node;
9508 tree int_ftype_int_v2sf_v2sf
9509 = build_function_type
9510 (integer_type_node,
9511 tree_cons (NULL_TREE, integer_type_node,
9512 tree_cons (NULL_TREE, V2SF_type_node,
9513 tree_cons (NULL_TREE, V2SF_type_node,
9514 endlink))));
9515 tree pcfloat_type_node =
9516 build_pointer_type (build_qualified_type
9517 (float_type_node, TYPE_QUAL_CONST));
9519 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
9520 long_integer_type_node,
9521 pcfloat_type_node,
9522 NULL_TREE);
9523 tree void_ftype_v2sf_long_pcfloat =
9524 build_function_type_list (void_type_node,
9525 V2SF_type_node,
9526 long_integer_type_node,
9527 pcfloat_type_node,
9528 NULL_TREE);
9531 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
9532 PAIRED_BUILTIN_LX);
9535 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
9536 PAIRED_BUILTIN_STX);
9538 /* Predicates. */
9539 d = bdesc_paired_preds;
9540 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
9542 tree type;
9544 switch (insn_data[d->icode].operand[1].mode)
9546 case V2SFmode:
9547 type = int_ftype_int_v2sf_v2sf;
9548 break;
9549 default:
9550 gcc_unreachable ();
9553 def_builtin (d->mask, d->name, type, d->code);
9557 static void
9558 altivec_init_builtins (void)
9560 const struct builtin_description *d;
9561 const struct builtin_description_predicates *dp;
9562 size_t i;
9563 tree ftype;
9565 tree pfloat_type_node = build_pointer_type (float_type_node);
9566 tree pint_type_node = build_pointer_type (integer_type_node);
9567 tree pshort_type_node = build_pointer_type (short_integer_type_node);
9568 tree pchar_type_node = build_pointer_type (char_type_node);
9570 tree pvoid_type_node = build_pointer_type (void_type_node);
9572 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
9573 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
9574 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
9575 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
9577 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
9579 tree int_ftype_opaque
9580 = build_function_type_list (integer_type_node,
9581 opaque_V4SI_type_node, NULL_TREE);
9583 tree opaque_ftype_opaque_int
9584 = build_function_type_list (opaque_V4SI_type_node,
9585 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
9586 tree opaque_ftype_opaque_opaque_int
9587 = build_function_type_list (opaque_V4SI_type_node,
9588 opaque_V4SI_type_node, opaque_V4SI_type_node,
9589 integer_type_node, NULL_TREE);
9590 tree int_ftype_int_opaque_opaque
9591 = build_function_type_list (integer_type_node,
9592 integer_type_node, opaque_V4SI_type_node,
9593 opaque_V4SI_type_node, NULL_TREE);
9594 tree int_ftype_int_v4si_v4si
9595 = build_function_type_list (integer_type_node,
9596 integer_type_node, V4SI_type_node,
9597 V4SI_type_node, NULL_TREE);
9598 tree v4sf_ftype_pcfloat
9599 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
9600 tree void_ftype_pfloat_v4sf
9601 = build_function_type_list (void_type_node,
9602 pfloat_type_node, V4SF_type_node, NULL_TREE);
9603 tree v4si_ftype_pcint
9604 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
9605 tree void_ftype_pint_v4si
9606 = build_function_type_list (void_type_node,
9607 pint_type_node, V4SI_type_node, NULL_TREE);
9608 tree v8hi_ftype_pcshort
9609 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
9610 tree void_ftype_pshort_v8hi
9611 = build_function_type_list (void_type_node,
9612 pshort_type_node, V8HI_type_node, NULL_TREE);
9613 tree v16qi_ftype_pcchar
9614 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
9615 tree void_ftype_pchar_v16qi
9616 = build_function_type_list (void_type_node,
9617 pchar_type_node, V16QI_type_node, NULL_TREE);
9618 tree void_ftype_v4si
9619 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
9620 tree v8hi_ftype_void
9621 = build_function_type (V8HI_type_node, void_list_node);
9622 tree void_ftype_void
9623 = build_function_type (void_type_node, void_list_node);
9624 tree void_ftype_int
9625 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
9627 tree opaque_ftype_long_pcvoid
9628 = build_function_type_list (opaque_V4SI_type_node,
9629 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9630 tree v16qi_ftype_long_pcvoid
9631 = build_function_type_list (V16QI_type_node,
9632 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9633 tree v8hi_ftype_long_pcvoid
9634 = build_function_type_list (V8HI_type_node,
9635 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9636 tree v4si_ftype_long_pcvoid
9637 = build_function_type_list (V4SI_type_node,
9638 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9640 tree void_ftype_opaque_long_pvoid
9641 = build_function_type_list (void_type_node,
9642 opaque_V4SI_type_node, long_integer_type_node,
9643 pvoid_type_node, NULL_TREE);
9644 tree void_ftype_v4si_long_pvoid
9645 = build_function_type_list (void_type_node,
9646 V4SI_type_node, long_integer_type_node,
9647 pvoid_type_node, NULL_TREE);
9648 tree void_ftype_v16qi_long_pvoid
9649 = build_function_type_list (void_type_node,
9650 V16QI_type_node, long_integer_type_node,
9651 pvoid_type_node, NULL_TREE);
9652 tree void_ftype_v8hi_long_pvoid
9653 = build_function_type_list (void_type_node,
9654 V8HI_type_node, long_integer_type_node,
9655 pvoid_type_node, NULL_TREE);
9656 tree int_ftype_int_v8hi_v8hi
9657 = build_function_type_list (integer_type_node,
9658 integer_type_node, V8HI_type_node,
9659 V8HI_type_node, NULL_TREE);
9660 tree int_ftype_int_v16qi_v16qi
9661 = build_function_type_list (integer_type_node,
9662 integer_type_node, V16QI_type_node,
9663 V16QI_type_node, NULL_TREE);
9664 tree int_ftype_int_v4sf_v4sf
9665 = build_function_type_list (integer_type_node,
9666 integer_type_node, V4SF_type_node,
9667 V4SF_type_node, NULL_TREE);
9668 tree v4si_ftype_v4si
9669 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
9670 tree v8hi_ftype_v8hi
9671 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
9672 tree v16qi_ftype_v16qi
9673 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
9674 tree v4sf_ftype_v4sf
9675 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
9676 tree void_ftype_pcvoid_int_int
9677 = build_function_type_list (void_type_node,
9678 pcvoid_type_node, integer_type_node,
9679 integer_type_node, NULL_TREE);
9681 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
9682 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
9683 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
9684 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
9685 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
9686 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
9687 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
9688 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
9689 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
9690 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
9691 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
9692 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
9693 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
9694 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
9695 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
9696 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
9697 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
9698 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
9699 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
9700 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
9701 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
9702 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
9703 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
9704 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
9705 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
9706 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
9707 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
9708 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
9709 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
9710 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
9711 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
9712 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
9713 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
9714 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
9715 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
9716 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
9717 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
9718 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
9719 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
9720 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
9721 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
9722 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
9723 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
9724 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
9725 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
9726 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
9728 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
9730 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
9731 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
9732 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
9733 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
9734 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
9735 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
9736 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
9737 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
9738 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
9739 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
9741 /* Add the DST variants. */
9742 d = bdesc_dst;
9743 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
9744 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
9746 /* Initialize the predicates. */
9747 dp = bdesc_altivec_preds;
9748 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
9750 enum machine_mode mode1;
9751 tree type;
9752 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9753 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9755 if (is_overloaded)
9756 mode1 = VOIDmode;
9757 else
9758 mode1 = insn_data[dp->icode].operand[1].mode;
9760 switch (mode1)
9762 case VOIDmode:
9763 type = int_ftype_int_opaque_opaque;
9764 break;
9765 case V4SImode:
9766 type = int_ftype_int_v4si_v4si;
9767 break;
9768 case V8HImode:
9769 type = int_ftype_int_v8hi_v8hi;
9770 break;
9771 case V16QImode:
9772 type = int_ftype_int_v16qi_v16qi;
9773 break;
9774 case V4SFmode:
9775 type = int_ftype_int_v4sf_v4sf;
9776 break;
9777 default:
9778 gcc_unreachable ();
9781 def_builtin (dp->mask, dp->name, type, dp->code);
9784 /* Initialize the abs* operators. */
9785 d = bdesc_abs;
9786 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
9788 enum machine_mode mode0;
9789 tree type;
9791 mode0 = insn_data[d->icode].operand[0].mode;
9793 switch (mode0)
9795 case V4SImode:
9796 type = v4si_ftype_v4si;
9797 break;
9798 case V8HImode:
9799 type = v8hi_ftype_v8hi;
9800 break;
9801 case V16QImode:
9802 type = v16qi_ftype_v16qi;
9803 break;
9804 case V4SFmode:
9805 type = v4sf_ftype_v4sf;
9806 break;
9807 default:
9808 gcc_unreachable ();
9811 def_builtin (d->mask, d->name, type, d->code);
9814 if (TARGET_ALTIVEC)
9816 tree decl;
9818 /* Initialize target builtin that implements
9819 targetm.vectorize.builtin_mask_for_load. */
9821 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
9822 v16qi_ftype_long_pcvoid,
9823 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
9824 BUILT_IN_MD, NULL, NULL_TREE);
9825 TREE_READONLY (decl) = 1;
9826 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
9827 altivec_builtin_mask_for_load = decl;
9830 /* Access to the vec_init patterns. */
9831 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
9832 integer_type_node, integer_type_node,
9833 integer_type_node, NULL_TREE);
9834 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
9835 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
9837 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
9838 short_integer_type_node,
9839 short_integer_type_node,
9840 short_integer_type_node,
9841 short_integer_type_node,
9842 short_integer_type_node,
9843 short_integer_type_node,
9844 short_integer_type_node, NULL_TREE);
9845 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
9846 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
9848 ftype = build_function_type_list (V16QI_type_node, char_type_node,
9849 char_type_node, char_type_node,
9850 char_type_node, char_type_node,
9851 char_type_node, char_type_node,
9852 char_type_node, char_type_node,
9853 char_type_node, char_type_node,
9854 char_type_node, char_type_node,
9855 char_type_node, char_type_node,
9856 char_type_node, NULL_TREE);
9857 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
9858 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
9860 ftype = build_function_type_list (V4SF_type_node, float_type_node,
9861 float_type_node, float_type_node,
9862 float_type_node, NULL_TREE);
9863 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
9864 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
9866 /* Access to the vec_set patterns. */
9867 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
9868 intSI_type_node,
9869 integer_type_node, NULL_TREE);
9870 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
9871 ALTIVEC_BUILTIN_VEC_SET_V4SI);
9873 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
9874 intHI_type_node,
9875 integer_type_node, NULL_TREE);
9876 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
9877 ALTIVEC_BUILTIN_VEC_SET_V8HI);
9879 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
9880 intQI_type_node,
9881 integer_type_node, NULL_TREE);
9882 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
9883 ALTIVEC_BUILTIN_VEC_SET_V16QI);
9885 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
9886 float_type_node,
9887 integer_type_node, NULL_TREE);
9888 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
9889 ALTIVEC_BUILTIN_VEC_SET_V4SF);
9891 /* Access to the vec_extract patterns. */
9892 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
9893 integer_type_node, NULL_TREE);
9894 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
9895 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
9897 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
9898 integer_type_node, NULL_TREE);
9899 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
9900 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
9902 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
9903 integer_type_node, NULL_TREE);
9904 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
9905 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
9907 ftype = build_function_type_list (float_type_node, V4SF_type_node,
9908 integer_type_node, NULL_TREE);
9909 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
9910 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
9913 static void
9914 rs6000_common_init_builtins (void)
9916 const struct builtin_description *d;
9917 size_t i;
9919 tree v2sf_ftype_v2sf_v2sf_v2sf
9920 = build_function_type_list (V2SF_type_node,
9921 V2SF_type_node, V2SF_type_node,
9922 V2SF_type_node, NULL_TREE);
9924 tree v4sf_ftype_v4sf_v4sf_v16qi
9925 = build_function_type_list (V4SF_type_node,
9926 V4SF_type_node, V4SF_type_node,
9927 V16QI_type_node, NULL_TREE);
9928 tree v4si_ftype_v4si_v4si_v16qi
9929 = build_function_type_list (V4SI_type_node,
9930 V4SI_type_node, V4SI_type_node,
9931 V16QI_type_node, NULL_TREE);
9932 tree v8hi_ftype_v8hi_v8hi_v16qi
9933 = build_function_type_list (V8HI_type_node,
9934 V8HI_type_node, V8HI_type_node,
9935 V16QI_type_node, NULL_TREE);
9936 tree v16qi_ftype_v16qi_v16qi_v16qi
9937 = build_function_type_list (V16QI_type_node,
9938 V16QI_type_node, V16QI_type_node,
9939 V16QI_type_node, NULL_TREE);
9940 tree v4si_ftype_int
9941 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
9942 tree v8hi_ftype_int
9943 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
9944 tree v16qi_ftype_int
9945 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
9946 tree v8hi_ftype_v16qi
9947 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
9948 tree v4sf_ftype_v4sf
9949 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
9951 tree v2si_ftype_v2si_v2si
9952 = build_function_type_list (opaque_V2SI_type_node,
9953 opaque_V2SI_type_node,
9954 opaque_V2SI_type_node, NULL_TREE);
9956 tree v2sf_ftype_v2sf_v2sf_spe
9957 = build_function_type_list (opaque_V2SF_type_node,
9958 opaque_V2SF_type_node,
9959 opaque_V2SF_type_node, NULL_TREE);
9961 tree v2sf_ftype_v2sf_v2sf
9962 = build_function_type_list (V2SF_type_node,
9963 V2SF_type_node,
9964 V2SF_type_node, NULL_TREE);
9967 tree v2si_ftype_int_int
9968 = build_function_type_list (opaque_V2SI_type_node,
9969 integer_type_node, integer_type_node,
9970 NULL_TREE);
9972 tree opaque_ftype_opaque
9973 = build_function_type_list (opaque_V4SI_type_node,
9974 opaque_V4SI_type_node, NULL_TREE);
9976 tree v2si_ftype_v2si
9977 = build_function_type_list (opaque_V2SI_type_node,
9978 opaque_V2SI_type_node, NULL_TREE);
9980 tree v2sf_ftype_v2sf_spe
9981 = build_function_type_list (opaque_V2SF_type_node,
9982 opaque_V2SF_type_node, NULL_TREE);
9984 tree v2sf_ftype_v2sf
9985 = build_function_type_list (V2SF_type_node,
9986 V2SF_type_node, NULL_TREE);
9988 tree v2sf_ftype_v2si
9989 = build_function_type_list (opaque_V2SF_type_node,
9990 opaque_V2SI_type_node, NULL_TREE);
9992 tree v2si_ftype_v2sf
9993 = build_function_type_list (opaque_V2SI_type_node,
9994 opaque_V2SF_type_node, NULL_TREE);
9996 tree v2si_ftype_v2si_char
9997 = build_function_type_list (opaque_V2SI_type_node,
9998 opaque_V2SI_type_node,
9999 char_type_node, NULL_TREE);
10001 tree v2si_ftype_int_char
10002 = build_function_type_list (opaque_V2SI_type_node,
10003 integer_type_node, char_type_node, NULL_TREE);
10005 tree v2si_ftype_char
10006 = build_function_type_list (opaque_V2SI_type_node,
10007 char_type_node, NULL_TREE);
10009 tree int_ftype_int_int
10010 = build_function_type_list (integer_type_node,
10011 integer_type_node, integer_type_node,
10012 NULL_TREE);
10014 tree opaque_ftype_opaque_opaque
10015 = build_function_type_list (opaque_V4SI_type_node,
10016 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
10017 tree v4si_ftype_v4si_v4si
10018 = build_function_type_list (V4SI_type_node,
10019 V4SI_type_node, V4SI_type_node, NULL_TREE);
10020 tree v4sf_ftype_v4si_int
10021 = build_function_type_list (V4SF_type_node,
10022 V4SI_type_node, integer_type_node, NULL_TREE);
10023 tree v4si_ftype_v4sf_int
10024 = build_function_type_list (V4SI_type_node,
10025 V4SF_type_node, integer_type_node, NULL_TREE);
10026 tree v4si_ftype_v4si_int
10027 = build_function_type_list (V4SI_type_node,
10028 V4SI_type_node, integer_type_node, NULL_TREE);
10029 tree v8hi_ftype_v8hi_int
10030 = build_function_type_list (V8HI_type_node,
10031 V8HI_type_node, integer_type_node, NULL_TREE);
10032 tree v16qi_ftype_v16qi_int
10033 = build_function_type_list (V16QI_type_node,
10034 V16QI_type_node, integer_type_node, NULL_TREE);
10035 tree v16qi_ftype_v16qi_v16qi_int
10036 = build_function_type_list (V16QI_type_node,
10037 V16QI_type_node, V16QI_type_node,
10038 integer_type_node, NULL_TREE);
10039 tree v8hi_ftype_v8hi_v8hi_int
10040 = build_function_type_list (V8HI_type_node,
10041 V8HI_type_node, V8HI_type_node,
10042 integer_type_node, NULL_TREE);
10043 tree v4si_ftype_v4si_v4si_int
10044 = build_function_type_list (V4SI_type_node,
10045 V4SI_type_node, V4SI_type_node,
10046 integer_type_node, NULL_TREE);
10047 tree v4sf_ftype_v4sf_v4sf_int
10048 = build_function_type_list (V4SF_type_node,
10049 V4SF_type_node, V4SF_type_node,
10050 integer_type_node, NULL_TREE);
10051 tree v4sf_ftype_v4sf_v4sf
10052 = build_function_type_list (V4SF_type_node,
10053 V4SF_type_node, V4SF_type_node, NULL_TREE);
10054 tree opaque_ftype_opaque_opaque_opaque
10055 = build_function_type_list (opaque_V4SI_type_node,
10056 opaque_V4SI_type_node, opaque_V4SI_type_node,
10057 opaque_V4SI_type_node, NULL_TREE);
10058 tree v4sf_ftype_v4sf_v4sf_v4si
10059 = build_function_type_list (V4SF_type_node,
10060 V4SF_type_node, V4SF_type_node,
10061 V4SI_type_node, NULL_TREE);
10062 tree v4sf_ftype_v4sf_v4sf_v4sf
10063 = build_function_type_list (V4SF_type_node,
10064 V4SF_type_node, V4SF_type_node,
10065 V4SF_type_node, NULL_TREE);
10066 tree v4si_ftype_v4si_v4si_v4si
10067 = build_function_type_list (V4SI_type_node,
10068 V4SI_type_node, V4SI_type_node,
10069 V4SI_type_node, NULL_TREE);
10070 tree v8hi_ftype_v8hi_v8hi
10071 = build_function_type_list (V8HI_type_node,
10072 V8HI_type_node, V8HI_type_node, NULL_TREE);
10073 tree v8hi_ftype_v8hi_v8hi_v8hi
10074 = build_function_type_list (V8HI_type_node,
10075 V8HI_type_node, V8HI_type_node,
10076 V8HI_type_node, NULL_TREE);
10077 tree v4si_ftype_v8hi_v8hi_v4si
10078 = build_function_type_list (V4SI_type_node,
10079 V8HI_type_node, V8HI_type_node,
10080 V4SI_type_node, NULL_TREE);
10081 tree v4si_ftype_v16qi_v16qi_v4si
10082 = build_function_type_list (V4SI_type_node,
10083 V16QI_type_node, V16QI_type_node,
10084 V4SI_type_node, NULL_TREE);
10085 tree v16qi_ftype_v16qi_v16qi
10086 = build_function_type_list (V16QI_type_node,
10087 V16QI_type_node, V16QI_type_node, NULL_TREE);
10088 tree v4si_ftype_v4sf_v4sf
10089 = build_function_type_list (V4SI_type_node,
10090 V4SF_type_node, V4SF_type_node, NULL_TREE);
10091 tree v8hi_ftype_v16qi_v16qi
10092 = build_function_type_list (V8HI_type_node,
10093 V16QI_type_node, V16QI_type_node, NULL_TREE);
10094 tree v4si_ftype_v8hi_v8hi
10095 = build_function_type_list (V4SI_type_node,
10096 V8HI_type_node, V8HI_type_node, NULL_TREE);
10097 tree v8hi_ftype_v4si_v4si
10098 = build_function_type_list (V8HI_type_node,
10099 V4SI_type_node, V4SI_type_node, NULL_TREE);
10100 tree v16qi_ftype_v8hi_v8hi
10101 = build_function_type_list (V16QI_type_node,
10102 V8HI_type_node, V8HI_type_node, NULL_TREE);
10103 tree v4si_ftype_v16qi_v4si
10104 = build_function_type_list (V4SI_type_node,
10105 V16QI_type_node, V4SI_type_node, NULL_TREE);
10106 tree v4si_ftype_v16qi_v16qi
10107 = build_function_type_list (V4SI_type_node,
10108 V16QI_type_node, V16QI_type_node, NULL_TREE);
10109 tree v4si_ftype_v8hi_v4si
10110 = build_function_type_list (V4SI_type_node,
10111 V8HI_type_node, V4SI_type_node, NULL_TREE);
10112 tree v4si_ftype_v8hi
10113 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
10114 tree int_ftype_v4si_v4si
10115 = build_function_type_list (integer_type_node,
10116 V4SI_type_node, V4SI_type_node, NULL_TREE);
10117 tree int_ftype_v4sf_v4sf
10118 = build_function_type_list (integer_type_node,
10119 V4SF_type_node, V4SF_type_node, NULL_TREE);
10120 tree int_ftype_v16qi_v16qi
10121 = build_function_type_list (integer_type_node,
10122 V16QI_type_node, V16QI_type_node, NULL_TREE);
10123 tree int_ftype_v8hi_v8hi
10124 = build_function_type_list (integer_type_node,
10125 V8HI_type_node, V8HI_type_node, NULL_TREE);
10127 /* Add the simple ternary operators. */
10128 d = bdesc_3arg;
10129 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10131 enum machine_mode mode0, mode1, mode2, mode3;
10132 tree type;
10133 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10134 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
10136 if (is_overloaded)
10138 mode0 = VOIDmode;
10139 mode1 = VOIDmode;
10140 mode2 = VOIDmode;
10141 mode3 = VOIDmode;
10143 else
10145 if (d->name == 0 || d->icode == CODE_FOR_nothing)
10146 continue;
10148 mode0 = insn_data[d->icode].operand[0].mode;
10149 mode1 = insn_data[d->icode].operand[1].mode;
10150 mode2 = insn_data[d->icode].operand[2].mode;
10151 mode3 = insn_data[d->icode].operand[3].mode;
10154 /* When all four are of the same mode. */
10155 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
10157 switch (mode0)
10159 case VOIDmode:
10160 type = opaque_ftype_opaque_opaque_opaque;
10161 break;
10162 case V4SImode:
10163 type = v4si_ftype_v4si_v4si_v4si;
10164 break;
10165 case V4SFmode:
10166 type = v4sf_ftype_v4sf_v4sf_v4sf;
10167 break;
10168 case V8HImode:
10169 type = v8hi_ftype_v8hi_v8hi_v8hi;
10170 break;
10171 case V16QImode:
10172 type = v16qi_ftype_v16qi_v16qi_v16qi;
10173 break;
10174 case V2SFmode:
10175 type = v2sf_ftype_v2sf_v2sf_v2sf;
10176 break;
10177 default:
10178 gcc_unreachable ();
10181 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
10183 switch (mode0)
10185 case V4SImode:
10186 type = v4si_ftype_v4si_v4si_v16qi;
10187 break;
10188 case V4SFmode:
10189 type = v4sf_ftype_v4sf_v4sf_v16qi;
10190 break;
10191 case V8HImode:
10192 type = v8hi_ftype_v8hi_v8hi_v16qi;
10193 break;
10194 case V16QImode:
10195 type = v16qi_ftype_v16qi_v16qi_v16qi;
10196 break;
10197 default:
10198 gcc_unreachable ();
10201 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
10202 && mode3 == V4SImode)
10203 type = v4si_ftype_v16qi_v16qi_v4si;
10204 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
10205 && mode3 == V4SImode)
10206 type = v4si_ftype_v8hi_v8hi_v4si;
10207 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
10208 && mode3 == V4SImode)
10209 type = v4sf_ftype_v4sf_v4sf_v4si;
10211 /* vchar, vchar, vchar, 4-bit literal. */
10212 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
10213 && mode3 == QImode)
10214 type = v16qi_ftype_v16qi_v16qi_int;
10216 /* vshort, vshort, vshort, 4-bit literal. */
10217 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
10218 && mode3 == QImode)
10219 type = v8hi_ftype_v8hi_v8hi_int;
10221 /* vint, vint, vint, 4-bit literal. */
10222 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
10223 && mode3 == QImode)
10224 type = v4si_ftype_v4si_v4si_int;
10226 /* vfloat, vfloat, vfloat, 4-bit literal. */
10227 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
10228 && mode3 == QImode)
10229 type = v4sf_ftype_v4sf_v4sf_int;
10231 else
10232 gcc_unreachable ();
10234 def_builtin (d->mask, d->name, type, d->code);
10237 /* Add the simple binary operators. */
10238 d = (struct builtin_description *) bdesc_2arg;
10239 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10241 enum machine_mode mode0, mode1, mode2;
10242 tree type;
10243 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10244 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
10246 if (is_overloaded)
10248 mode0 = VOIDmode;
10249 mode1 = VOIDmode;
10250 mode2 = VOIDmode;
10252 else
10254 if (d->name == 0 || d->icode == CODE_FOR_nothing)
10255 continue;
10257 mode0 = insn_data[d->icode].operand[0].mode;
10258 mode1 = insn_data[d->icode].operand[1].mode;
10259 mode2 = insn_data[d->icode].operand[2].mode;
10262 /* When all three operands are of the same mode. */
10263 if (mode0 == mode1 && mode1 == mode2)
10265 switch (mode0)
10267 case VOIDmode:
10268 type = opaque_ftype_opaque_opaque;
10269 break;
10270 case V4SFmode:
10271 type = v4sf_ftype_v4sf_v4sf;
10272 break;
10273 case V4SImode:
10274 type = v4si_ftype_v4si_v4si;
10275 break;
10276 case V16QImode:
10277 type = v16qi_ftype_v16qi_v16qi;
10278 break;
10279 case V8HImode:
10280 type = v8hi_ftype_v8hi_v8hi;
10281 break;
10282 case V2SImode:
10283 type = v2si_ftype_v2si_v2si;
10284 break;
10285 case V2SFmode:
10286 if (TARGET_PAIRED_FLOAT)
10287 type = v2sf_ftype_v2sf_v2sf;
10288 else
10289 type = v2sf_ftype_v2sf_v2sf_spe;
10290 break;
10291 case SImode:
10292 type = int_ftype_int_int;
10293 break;
10294 default:
10295 gcc_unreachable ();
10299 /* A few other combos we really don't want to do manually. */
10301 /* vint, vfloat, vfloat. */
10302 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
10303 type = v4si_ftype_v4sf_v4sf;
10305 /* vshort, vchar, vchar. */
10306 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
10307 type = v8hi_ftype_v16qi_v16qi;
10309 /* vint, vshort, vshort. */
10310 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
10311 type = v4si_ftype_v8hi_v8hi;
10313 /* vshort, vint, vint. */
10314 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
10315 type = v8hi_ftype_v4si_v4si;
10317 /* vchar, vshort, vshort. */
10318 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
10319 type = v16qi_ftype_v8hi_v8hi;
10321 /* vint, vchar, vint. */
10322 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
10323 type = v4si_ftype_v16qi_v4si;
10325 /* vint, vchar, vchar. */
10326 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
10327 type = v4si_ftype_v16qi_v16qi;
10329 /* vint, vshort, vint. */
10330 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
10331 type = v4si_ftype_v8hi_v4si;
10333 /* vint, vint, 5-bit literal. */
10334 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
10335 type = v4si_ftype_v4si_int;
10337 /* vshort, vshort, 5-bit literal. */
10338 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
10339 type = v8hi_ftype_v8hi_int;
10341 /* vchar, vchar, 5-bit literal. */
10342 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
10343 type = v16qi_ftype_v16qi_int;
10345 /* vfloat, vint, 5-bit literal. */
10346 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
10347 type = v4sf_ftype_v4si_int;
10349 /* vint, vfloat, 5-bit literal. */
10350 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
10351 type = v4si_ftype_v4sf_int;
10353 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
10354 type = v2si_ftype_int_int;
10356 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
10357 type = v2si_ftype_v2si_char;
10359 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
10360 type = v2si_ftype_int_char;
10362 else
10364 /* int, x, x. */
10365 gcc_assert (mode0 == SImode);
10366 switch (mode1)
10368 case V4SImode:
10369 type = int_ftype_v4si_v4si;
10370 break;
10371 case V4SFmode:
10372 type = int_ftype_v4sf_v4sf;
10373 break;
10374 case V16QImode:
10375 type = int_ftype_v16qi_v16qi;
10376 break;
10377 case V8HImode:
10378 type = int_ftype_v8hi_v8hi;
10379 break;
10380 default:
10381 gcc_unreachable ();
10385 def_builtin (d->mask, d->name, type, d->code);
10388 /* Add the simple unary operators. */
10389 d = (struct builtin_description *) bdesc_1arg;
10390 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10392 enum machine_mode mode0, mode1;
10393 tree type;
10394 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10395 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
10397 if (is_overloaded)
10399 mode0 = VOIDmode;
10400 mode1 = VOIDmode;
10402 else
10404 if (d->name == 0 || d->icode == CODE_FOR_nothing)
10405 continue;
10407 mode0 = insn_data[d->icode].operand[0].mode;
10408 mode1 = insn_data[d->icode].operand[1].mode;
10411 if (mode0 == V4SImode && mode1 == QImode)
10412 type = v4si_ftype_int;
10413 else if (mode0 == V8HImode && mode1 == QImode)
10414 type = v8hi_ftype_int;
10415 else if (mode0 == V16QImode && mode1 == QImode)
10416 type = v16qi_ftype_int;
10417 else if (mode0 == VOIDmode && mode1 == VOIDmode)
10418 type = opaque_ftype_opaque;
10419 else if (mode0 == V4SFmode && mode1 == V4SFmode)
10420 type = v4sf_ftype_v4sf;
10421 else if (mode0 == V8HImode && mode1 == V16QImode)
10422 type = v8hi_ftype_v16qi;
10423 else if (mode0 == V4SImode && mode1 == V8HImode)
10424 type = v4si_ftype_v8hi;
10425 else if (mode0 == V2SImode && mode1 == V2SImode)
10426 type = v2si_ftype_v2si;
10427 else if (mode0 == V2SFmode && mode1 == V2SFmode)
10429 if (TARGET_PAIRED_FLOAT)
10430 type = v2sf_ftype_v2sf;
10431 else
10432 type = v2sf_ftype_v2sf_spe;
10434 else if (mode0 == V2SFmode && mode1 == V2SImode)
10435 type = v2sf_ftype_v2si;
10436 else if (mode0 == V2SImode && mode1 == V2SFmode)
10437 type = v2si_ftype_v2sf;
10438 else if (mode0 == V2SImode && mode1 == QImode)
10439 type = v2si_ftype_char;
10440 else
10441 gcc_unreachable ();
10443 def_builtin (d->mask, d->name, type, d->code);
10447 static void
10448 rs6000_init_libfuncs (void)
10450 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
10451 && !TARGET_POWER2 && !TARGET_POWERPC)
10453 /* AIX library routines for float->int conversion. */
10454 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
10455 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
10456 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
10457 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
10460 if (!TARGET_IEEEQUAD)
10461 /* AIX/Darwin/64-bit Linux quad floating point routines. */
10462 if (!TARGET_XL_COMPAT)
10464 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
10465 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
10466 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
10467 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
10469 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
10471 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
10472 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
10473 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
10474 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
10475 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
10476 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
10477 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
10479 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
10480 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
10481 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
10482 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
10483 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
10484 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
10485 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
10486 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
10489 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
10490 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
10492 else
10494 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
10495 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
10496 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
10497 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
10499 else
10501 /* 32-bit SVR4 quad floating point routines. */
10503 set_optab_libfunc (add_optab, TFmode, "_q_add");
10504 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
10505 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
10506 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
10507 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
10508 if (TARGET_PPC_GPOPT || TARGET_POWER2)
10509 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
10511 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
10512 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
10513 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
10514 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
10515 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
10516 set_optab_libfunc (le_optab, TFmode, "_q_fle");
10518 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
10519 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
10520 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
10521 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
10522 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
10523 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
10524 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
10525 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
10530 /* Expand a block clear operation, and return 1 if successful. Return 0
10531 if we should let the compiler generate normal code.
10533 operands[0] is the destination
10534 operands[1] is the length
10535 operands[3] is the alignment */
10538 expand_block_clear (rtx operands[])
10540 rtx orig_dest = operands[0];
10541 rtx bytes_rtx = operands[1];
10542 rtx align_rtx = operands[3];
10543 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
10544 HOST_WIDE_INT align;
10545 HOST_WIDE_INT bytes;
10546 int offset;
10547 int clear_bytes;
10548 int clear_step;
10550 /* If this is not a fixed size move, just call memcpy */
10551 if (! constp)
10552 return 0;
10554 /* This must be a fixed size alignment */
10555 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
10556 align = INTVAL (align_rtx) * BITS_PER_UNIT;
10558 /* Anything to clear? */
10559 bytes = INTVAL (bytes_rtx);
10560 if (bytes <= 0)
10561 return 1;
10563 /* Use the builtin memset after a point, to avoid huge code bloat.
10564 When optimize_size, avoid any significant code bloat; calling
10565 memset is about 4 instructions, so allow for one instruction to
10566 load zero and three to do clearing. */
10567 if (TARGET_ALTIVEC && align >= 128)
10568 clear_step = 16;
10569 else if (TARGET_POWERPC64 && align >= 32)
10570 clear_step = 8;
10571 else if (TARGET_SPE && align >= 64)
10572 clear_step = 8;
10573 else
10574 clear_step = 4;
10576 if (optimize_size && bytes > 3 * clear_step)
10577 return 0;
10578 if (! optimize_size && bytes > 8 * clear_step)
10579 return 0;
10581 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
10583 enum machine_mode mode = BLKmode;
10584 rtx dest;
10586 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
10588 clear_bytes = 16;
10589 mode = V4SImode;
10591 else if (bytes >= 8 && TARGET_SPE && align >= 64)
10593 clear_bytes = 8;
10594 mode = V2SImode;
10596 else if (bytes >= 8 && TARGET_POWERPC64
10597 /* 64-bit loads and stores require word-aligned
10598 displacements. */
10599 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
10601 clear_bytes = 8;
10602 mode = DImode;
10604 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
10605 { /* move 4 bytes */
10606 clear_bytes = 4;
10607 mode = SImode;
10609 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
10610 { /* move 2 bytes */
10611 clear_bytes = 2;
10612 mode = HImode;
10614 else /* move 1 byte at a time */
10616 clear_bytes = 1;
10617 mode = QImode;
10620 dest = adjust_address (orig_dest, mode, offset);
10622 emit_move_insn (dest, CONST0_RTX (mode));
10625 return 1;
10629 /* Expand a block move operation, and return 1 if successful. Return 0
10630 if we should let the compiler generate normal code.
10632 operands[0] is the destination
10633 operands[1] is the source
10634 operands[2] is the length
10635 operands[3] is the alignment */
10637 #define MAX_MOVE_REG 4
10640 expand_block_move (rtx operands[])
10642 rtx orig_dest = operands[0];
10643 rtx orig_src = operands[1];
10644 rtx bytes_rtx = operands[2];
10645 rtx align_rtx = operands[3];
10646 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
10647 int align;
10648 int bytes;
10649 int offset;
10650 int move_bytes;
10651 rtx stores[MAX_MOVE_REG];
10652 int num_reg = 0;
10654 /* If this is not a fixed size move, just call memcpy */
10655 if (! constp)
10656 return 0;
10658 /* This must be a fixed size alignment */
10659 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
10660 align = INTVAL (align_rtx) * BITS_PER_UNIT;
10662 /* Anything to move? */
10663 bytes = INTVAL (bytes_rtx);
10664 if (bytes <= 0)
10665 return 1;
10667 /* store_one_arg depends on expand_block_move to handle at least the size of
10668 reg_parm_stack_space. */
10669 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
10670 return 0;
10672 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
10674 union {
10675 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
10676 rtx (*mov) (rtx, rtx);
10677 } gen_func;
10678 enum machine_mode mode = BLKmode;
10679 rtx src, dest;
10681 /* Altivec first, since it will be faster than a string move
10682 when it applies, and usually not significantly larger. */
10683 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
10685 move_bytes = 16;
10686 mode = V4SImode;
10687 gen_func.mov = gen_movv4si;
10689 else if (TARGET_SPE && bytes >= 8 && align >= 64)
10691 move_bytes = 8;
10692 mode = V2SImode;
10693 gen_func.mov = gen_movv2si;
10695 else if (TARGET_STRING
10696 && bytes > 24 /* move up to 32 bytes at a time */
10697 && ! fixed_regs[5]
10698 && ! fixed_regs[6]
10699 && ! fixed_regs[7]
10700 && ! fixed_regs[8]
10701 && ! fixed_regs[9]
10702 && ! fixed_regs[10]
10703 && ! fixed_regs[11]
10704 && ! fixed_regs[12])
10706 move_bytes = (bytes > 32) ? 32 : bytes;
10707 gen_func.movmemsi = gen_movmemsi_8reg;
10709 else if (TARGET_STRING
10710 && bytes > 16 /* move up to 24 bytes at a time */
10711 && ! fixed_regs[5]
10712 && ! fixed_regs[6]
10713 && ! fixed_regs[7]
10714 && ! fixed_regs[8]
10715 && ! fixed_regs[9]
10716 && ! fixed_regs[10])
10718 move_bytes = (bytes > 24) ? 24 : bytes;
10719 gen_func.movmemsi = gen_movmemsi_6reg;
10721 else if (TARGET_STRING
10722 && bytes > 8 /* move up to 16 bytes at a time */
10723 && ! fixed_regs[5]
10724 && ! fixed_regs[6]
10725 && ! fixed_regs[7]
10726 && ! fixed_regs[8])
10728 move_bytes = (bytes > 16) ? 16 : bytes;
10729 gen_func.movmemsi = gen_movmemsi_4reg;
10731 else if (bytes >= 8 && TARGET_POWERPC64
10732 /* 64-bit loads and stores require word-aligned
10733 displacements. */
10734 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
10736 move_bytes = 8;
10737 mode = DImode;
10738 gen_func.mov = gen_movdi;
10740 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
10741 { /* move up to 8 bytes at a time */
10742 move_bytes = (bytes > 8) ? 8 : bytes;
10743 gen_func.movmemsi = gen_movmemsi_2reg;
10745 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
10746 { /* move 4 bytes */
10747 move_bytes = 4;
10748 mode = SImode;
10749 gen_func.mov = gen_movsi;
10751 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
10752 { /* move 2 bytes */
10753 move_bytes = 2;
10754 mode = HImode;
10755 gen_func.mov = gen_movhi;
10757 else if (TARGET_STRING && bytes > 1)
10758 { /* move up to 4 bytes at a time */
10759 move_bytes = (bytes > 4) ? 4 : bytes;
10760 gen_func.movmemsi = gen_movmemsi_1reg;
10762 else /* move 1 byte at a time */
10764 move_bytes = 1;
10765 mode = QImode;
10766 gen_func.mov = gen_movqi;
10769 src = adjust_address (orig_src, mode, offset);
10770 dest = adjust_address (orig_dest, mode, offset);
10772 if (mode != BLKmode)
10774 rtx tmp_reg = gen_reg_rtx (mode);
10776 emit_insn ((*gen_func.mov) (tmp_reg, src));
10777 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
10780 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
10782 int i;
10783 for (i = 0; i < num_reg; i++)
10784 emit_insn (stores[i]);
10785 num_reg = 0;
10788 if (mode == BLKmode)
10790 /* Move the address into scratch registers. The movmemsi
10791 patterns require zero offset. */
10792 if (!REG_P (XEXP (src, 0)))
10794 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
10795 src = replace_equiv_address (src, src_reg);
10797 set_mem_size (src, GEN_INT (move_bytes));
10799 if (!REG_P (XEXP (dest, 0)))
10801 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
10802 dest = replace_equiv_address (dest, dest_reg);
10804 set_mem_size (dest, GEN_INT (move_bytes));
10806 emit_insn ((*gen_func.movmemsi) (dest, src,
10807 GEN_INT (move_bytes & 31),
10808 align_rtx));
10812 return 1;
10816 /* Return a string to perform a load_multiple operation.
10817 operands[0] is the vector.
10818 operands[1] is the source address.
10819 operands[2] is the first destination register. */
10821 const char *
10822 rs6000_output_load_multiple (rtx operands[3])
10824 /* We have to handle the case where the pseudo used to contain the address
10825 is assigned to one of the output registers. */
10826 int i, j;
10827 int words = XVECLEN (operands[0], 0);
10828 rtx xop[10];
10830 if (XVECLEN (operands[0], 0) == 1)
10831 return "{l|lwz} %2,0(%1)";
10833 for (i = 0; i < words; i++)
10834 if (refers_to_regno_p (REGNO (operands[2]) + i,
10835 REGNO (operands[2]) + i + 1, operands[1], 0))
10837 if (i == words-1)
10839 xop[0] = GEN_INT (4 * (words-1));
10840 xop[1] = operands[1];
10841 xop[2] = operands[2];
10842 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
10843 return "";
10845 else if (i == 0)
10847 xop[0] = GEN_INT (4 * (words-1));
10848 xop[1] = operands[1];
10849 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
10850 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);
10851 return "";
10853 else
10855 for (j = 0; j < words; j++)
10856 if (j != i)
10858 xop[0] = GEN_INT (j * 4);
10859 xop[1] = operands[1];
10860 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
10861 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
10863 xop[0] = GEN_INT (i * 4);
10864 xop[1] = operands[1];
10865 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
10866 return "";
10870 return "{lsi|lswi} %2,%1,%N0";
10874 /* A validation routine: say whether CODE, a condition code, and MODE
10875 match. The other alternatives either don't make sense or should
10876 never be generated. */
10878 void
10879 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
10881 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
10882 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
10883 && GET_MODE_CLASS (mode) == MODE_CC);
10885 /* These don't make sense. */
10886 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
10887 || mode != CCUNSmode);
10889 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
10890 || mode == CCUNSmode);
10892 gcc_assert (mode == CCFPmode
10893 || (code != ORDERED && code != UNORDERED
10894 && code != UNEQ && code != LTGT
10895 && code != UNGT && code != UNLT
10896 && code != UNGE && code != UNLE));
10898 /* These should never be generated except for
10899 flag_finite_math_only. */
10900 gcc_assert (mode != CCFPmode
10901 || flag_finite_math_only
10902 || (code != LE && code != GE
10903 && code != UNEQ && code != LTGT
10904 && code != UNGT && code != UNLT));
10906 /* These are invalid; the information is not there. */
10907 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
10911 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
10912 mask required to convert the result of a rotate insn into a shift
10913 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
10916 includes_lshift_p (rtx shiftop, rtx andop)
10918 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
10920 shift_mask <<= INTVAL (shiftop);
10922 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
10925 /* Similar, but for right shift. */
10928 includes_rshift_p (rtx shiftop, rtx andop)
10930 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
10932 shift_mask >>= INTVAL (shiftop);
10934 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
10937 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
10938 to perform a left shift. It must have exactly SHIFTOP least
10939 significant 0's, then one or more 1's, then zero or more 0's. */
10942 includes_rldic_lshift_p (rtx shiftop, rtx andop)
10944 if (GET_CODE (andop) == CONST_INT)
10946 HOST_WIDE_INT c, lsb, shift_mask;
10948 c = INTVAL (andop);
10949 if (c == 0 || c == ~0)
10950 return 0;
10952 shift_mask = ~0;
10953 shift_mask <<= INTVAL (shiftop);
10955 /* Find the least significant one bit. */
10956 lsb = c & -c;
10958 /* It must coincide with the LSB of the shift mask. */
10959 if (-lsb != shift_mask)
10960 return 0;
10962 /* Invert to look for the next transition (if any). */
10963 c = ~c;
10965 /* Remove the low group of ones (originally low group of zeros). */
10966 c &= -lsb;
10968 /* Again find the lsb, and check we have all 1's above. */
10969 lsb = c & -c;
10970 return c == -lsb;
10972 else if (GET_CODE (andop) == CONST_DOUBLE
10973 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
10975 HOST_WIDE_INT low, high, lsb;
10976 HOST_WIDE_INT shift_mask_low, shift_mask_high;
10978 low = CONST_DOUBLE_LOW (andop);
10979 if (HOST_BITS_PER_WIDE_INT < 64)
10980 high = CONST_DOUBLE_HIGH (andop);
10982 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
10983 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
10984 return 0;
10986 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
10988 shift_mask_high = ~0;
10989 if (INTVAL (shiftop) > 32)
10990 shift_mask_high <<= INTVAL (shiftop) - 32;
10992 lsb = high & -high;
10994 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
10995 return 0;
10997 high = ~high;
10998 high &= -lsb;
11000 lsb = high & -high;
11001 return high == -lsb;
11004 shift_mask_low = ~0;
11005 shift_mask_low <<= INTVAL (shiftop);
11007 lsb = low & -low;
11009 if (-lsb != shift_mask_low)
11010 return 0;
11012 if (HOST_BITS_PER_WIDE_INT < 64)
11013 high = ~high;
11014 low = ~low;
11015 low &= -lsb;
11017 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
11019 lsb = high & -high;
11020 return high == -lsb;
11023 lsb = low & -low;
11024 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
11026 else
11027 return 0;
11030 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
11031 to perform a left shift. It must have SHIFTOP or more least
11032 significant 0's, with the remainder of the word 1's. */
11035 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
11037 if (GET_CODE (andop) == CONST_INT)
11039 HOST_WIDE_INT c, lsb, shift_mask;
11041 shift_mask = ~0;
11042 shift_mask <<= INTVAL (shiftop);
11043 c = INTVAL (andop);
11045 /* Find the least significant one bit. */
11046 lsb = c & -c;
11048 /* It must be covered by the shift mask.
11049 This test also rejects c == 0. */
11050 if ((lsb & shift_mask) == 0)
11051 return 0;
11053 /* Check we have all 1's above the transition, and reject all 1's. */
11054 return c == -lsb && lsb != 1;
11056 else if (GET_CODE (andop) == CONST_DOUBLE
11057 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
11059 HOST_WIDE_INT low, lsb, shift_mask_low;
11061 low = CONST_DOUBLE_LOW (andop);
11063 if (HOST_BITS_PER_WIDE_INT < 64)
11065 HOST_WIDE_INT high, shift_mask_high;
11067 high = CONST_DOUBLE_HIGH (andop);
11069 if (low == 0)
11071 shift_mask_high = ~0;
11072 if (INTVAL (shiftop) > 32)
11073 shift_mask_high <<= INTVAL (shiftop) - 32;
11075 lsb = high & -high;
11077 if ((lsb & shift_mask_high) == 0)
11078 return 0;
11080 return high == -lsb;
11082 if (high != ~0)
11083 return 0;
11086 shift_mask_low = ~0;
11087 shift_mask_low <<= INTVAL (shiftop);
11089 lsb = low & -low;
11091 if ((lsb & shift_mask_low) == 0)
11092 return 0;
11094 return low == -lsb && lsb != 1;
11096 else
11097 return 0;
11100 /* Return 1 if operands will generate a valid arguments to rlwimi
11101 instruction for insert with right shift in 64-bit mode. The mask may
11102 not start on the first bit or stop on the last bit because wrap-around
11103 effects of instruction do not correspond to semantics of RTL insn. */
11106 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
11108 if (INTVAL (startop) > 32
11109 && INTVAL (startop) < 64
11110 && INTVAL (sizeop) > 1
11111 && INTVAL (sizeop) + INTVAL (startop) < 64
11112 && INTVAL (shiftop) > 0
11113 && INTVAL (sizeop) + INTVAL (shiftop) < 32
11114 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
11115 return 1;
11117 return 0;
11120 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
11121 for lfq and stfq insns iff the registers are hard registers. */
11124 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
11126 /* We might have been passed a SUBREG. */
11127 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
11128 return 0;
11130 /* We might have been passed non floating point registers. */
11131 if (!FP_REGNO_P (REGNO (reg1))
11132 || !FP_REGNO_P (REGNO (reg2)))
11133 return 0;
11135 return (REGNO (reg1) == REGNO (reg2) - 1);
11138 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
11139 addr1 and addr2 must be in consecutive memory locations
11140 (addr2 == addr1 + 8). */
11143 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
11145 rtx addr1, addr2;
11146 unsigned int reg1, reg2;
11147 int offset1, offset2;
11149 /* The mems cannot be volatile. */
11150 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
11151 return 0;
11153 addr1 = XEXP (mem1, 0);
11154 addr2 = XEXP (mem2, 0);
11156 /* Extract an offset (if used) from the first addr. */
11157 if (GET_CODE (addr1) == PLUS)
11159 /* If not a REG, return zero. */
11160 if (GET_CODE (XEXP (addr1, 0)) != REG)
11161 return 0;
11162 else
11164 reg1 = REGNO (XEXP (addr1, 0));
11165 /* The offset must be constant! */
11166 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
11167 return 0;
11168 offset1 = INTVAL (XEXP (addr1, 1));
11171 else if (GET_CODE (addr1) != REG)
11172 return 0;
11173 else
11175 reg1 = REGNO (addr1);
11176 /* This was a simple (mem (reg)) expression. Offset is 0. */
11177 offset1 = 0;
11180 /* And now for the second addr. */
11181 if (GET_CODE (addr2) == PLUS)
11183 /* If not a REG, return zero. */
11184 if (GET_CODE (XEXP (addr2, 0)) != REG)
11185 return 0;
11186 else
11188 reg2 = REGNO (XEXP (addr2, 0));
11189 /* The offset must be constant. */
11190 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
11191 return 0;
11192 offset2 = INTVAL (XEXP (addr2, 1));
11195 else if (GET_CODE (addr2) != REG)
11196 return 0;
11197 else
11199 reg2 = REGNO (addr2);
11200 /* This was a simple (mem (reg)) expression. Offset is 0. */
11201 offset2 = 0;
11204 /* Both of these must have the same base register. */
11205 if (reg1 != reg2)
11206 return 0;
11208 /* The offset for the second addr must be 8 more than the first addr. */
11209 if (offset2 != offset1 + 8)
11210 return 0;
11212 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
11213 instructions. */
11214 return 1;
11219 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
11221 static bool eliminated = false;
11222 if (mode != SDmode)
11223 return assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
11224 else
11226 rtx mem = cfun->machine->sdmode_stack_slot;
11227 gcc_assert (mem != NULL_RTX);
11229 if (!eliminated)
11231 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
11232 cfun->machine->sdmode_stack_slot = mem;
11233 eliminated = true;
11235 return mem;
11239 static tree
11240 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
11242 /* Don't walk into types. */
11243 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
11245 *walk_subtrees = 0;
11246 return NULL_TREE;
11249 switch (TREE_CODE (*tp))
11251 case VAR_DECL:
11252 case PARM_DECL:
11253 case FIELD_DECL:
11254 case RESULT_DECL:
11255 case REAL_CST:
11256 case INDIRECT_REF:
11257 case ALIGN_INDIRECT_REF:
11258 case MISALIGNED_INDIRECT_REF:
11259 case VIEW_CONVERT_EXPR:
11260 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
11261 return *tp;
11262 break;
11263 default:
11264 break;
11267 return NULL_TREE;
11271 /* Allocate a 64-bit stack slot to be used for copying SDmode
11272 values through if this function has any SDmode references. */
11274 static void
11275 rs6000_alloc_sdmode_stack_slot (void)
11277 tree t;
11278 basic_block bb;
11279 block_stmt_iterator bsi;
11281 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
11283 FOR_EACH_BB (bb)
11284 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
11286 tree ret = walk_tree_without_duplicates (bsi_stmt_ptr (bsi),
11287 rs6000_check_sdmode, NULL);
11288 if (ret)
11290 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
11291 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
11292 SDmode, 0);
11293 return;
11297 /* Check for any SDmode parameters of the function. */
11298 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
11300 if (TREE_TYPE (t) == error_mark_node)
11301 continue;
11303 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
11304 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
11306 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
11307 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
11308 SDmode, 0);
11309 return;
11314 static void
11315 rs6000_instantiate_decls (void)
11317 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
11318 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
11321 /* Return the register class of a scratch register needed to copy IN into
11322 or out of a register in CLASS in MODE. If it can be done directly,
11323 NO_REGS is returned. */
11325 enum reg_class
11326 rs6000_secondary_reload_class (enum reg_class class,
11327 enum machine_mode mode ATTRIBUTE_UNUSED,
11328 rtx in)
11330 int regno;
11332 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
11333 #if TARGET_MACHO
11334 && MACHOPIC_INDIRECT
11335 #endif
11338 /* We cannot copy a symbolic operand directly into anything
11339 other than BASE_REGS for TARGET_ELF. So indicate that a
11340 register from BASE_REGS is needed as an intermediate
11341 register.
11343 On Darwin, pic addresses require a load from memory, which
11344 needs a base register. */
11345 if (class != BASE_REGS
11346 && (GET_CODE (in) == SYMBOL_REF
11347 || GET_CODE (in) == HIGH
11348 || GET_CODE (in) == LABEL_REF
11349 || GET_CODE (in) == CONST))
11350 return BASE_REGS;
11353 if (GET_CODE (in) == REG)
11355 regno = REGNO (in);
11356 if (regno >= FIRST_PSEUDO_REGISTER)
11358 regno = true_regnum (in);
11359 if (regno >= FIRST_PSEUDO_REGISTER)
11360 regno = -1;
11363 else if (GET_CODE (in) == SUBREG)
11365 regno = true_regnum (in);
11366 if (regno >= FIRST_PSEUDO_REGISTER)
11367 regno = -1;
11369 else
11370 regno = -1;
11372 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
11373 into anything. */
11374 if (class == GENERAL_REGS || class == BASE_REGS
11375 || (regno >= 0 && INT_REGNO_P (regno)))
11376 return NO_REGS;
11378 /* Constants, memory, and FP registers can go into FP registers. */
11379 if ((regno == -1 || FP_REGNO_P (regno))
11380 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
11381 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
11383 /* Memory, and AltiVec registers can go into AltiVec registers. */
11384 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
11385 && class == ALTIVEC_REGS)
11386 return NO_REGS;
11388 /* We can copy among the CR registers. */
11389 if ((class == CR_REGS || class == CR0_REGS)
11390 && regno >= 0 && CR_REGNO_P (regno))
11391 return NO_REGS;
11393 /* Otherwise, we need GENERAL_REGS. */
11394 return GENERAL_REGS;
11397 /* Given a comparison operation, return the bit number in CCR to test. We
11398 know this is a valid comparison.
11400 SCC_P is 1 if this is for an scc. That means that %D will have been
11401 used instead of %C, so the bits will be in different places.
11403 Return -1 if OP isn't a valid comparison for some reason. */
11406 ccr_bit (rtx op, int scc_p)
11408 enum rtx_code code = GET_CODE (op);
11409 enum machine_mode cc_mode;
11410 int cc_regnum;
11411 int base_bit;
11412 rtx reg;
11414 if (!COMPARISON_P (op))
11415 return -1;
11417 reg = XEXP (op, 0);
11419 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
11421 cc_mode = GET_MODE (reg);
11422 cc_regnum = REGNO (reg);
11423 base_bit = 4 * (cc_regnum - CR0_REGNO);
11425 validate_condition_mode (code, cc_mode);
11427 /* When generating a sCOND operation, only positive conditions are
11428 allowed. */
11429 gcc_assert (!scc_p
11430 || code == EQ || code == GT || code == LT || code == UNORDERED
11431 || code == GTU || code == LTU);
11433 switch (code)
11435 case NE:
11436 return scc_p ? base_bit + 3 : base_bit + 2;
11437 case EQ:
11438 return base_bit + 2;
11439 case GT: case GTU: case UNLE:
11440 return base_bit + 1;
11441 case LT: case LTU: case UNGE:
11442 return base_bit;
11443 case ORDERED: case UNORDERED:
11444 return base_bit + 3;
11446 case GE: case GEU:
11447 /* If scc, we will have done a cror to put the bit in the
11448 unordered position. So test that bit. For integer, this is ! LT
11449 unless this is an scc insn. */
11450 return scc_p ? base_bit + 3 : base_bit;
11452 case LE: case LEU:
11453 return scc_p ? base_bit + 3 : base_bit + 1;
11455 default:
11456 gcc_unreachable ();
11460 /* Return the GOT register. */
11463 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
11465 /* The second flow pass currently (June 1999) can't update
11466 regs_ever_live without disturbing other parts of the compiler, so
11467 update it here to make the prolog/epilogue code happy. */
11468 if (!can_create_pseudo_p ()
11469 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
11470 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
11472 crtl->uses_pic_offset_table = 1;
11474 return pic_offset_table_rtx;
11477 /* Function to init struct machine_function.
11478 This will be called, via a pointer variable,
11479 from push_function_context. */
11481 static struct machine_function *
11482 rs6000_init_machine_status (void)
11484 return ggc_alloc_cleared (sizeof (machine_function));
11487 /* These macros test for integers and extract the low-order bits. */
11488 #define INT_P(X) \
11489 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
11490 && GET_MODE (X) == VOIDmode)
11492 #define INT_LOWPART(X) \
11493 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
11496 extract_MB (rtx op)
11498 int i;
11499 unsigned long val = INT_LOWPART (op);
11501 /* If the high bit is zero, the value is the first 1 bit we find
11502 from the left. */
11503 if ((val & 0x80000000) == 0)
11505 gcc_assert (val & 0xffffffff);
11507 i = 1;
11508 while (((val <<= 1) & 0x80000000) == 0)
11509 ++i;
11510 return i;
11513 /* If the high bit is set and the low bit is not, or the mask is all
11514 1's, the value is zero. */
11515 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
11516 return 0;
11518 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11519 from the right. */
11520 i = 31;
11521 while (((val >>= 1) & 1) != 0)
11522 --i;
11524 return i;
11528 extract_ME (rtx op)
11530 int i;
11531 unsigned long val = INT_LOWPART (op);
11533 /* If the low bit is zero, the value is the first 1 bit we find from
11534 the right. */
11535 if ((val & 1) == 0)
11537 gcc_assert (val & 0xffffffff);
11539 i = 30;
11540 while (((val >>= 1) & 1) == 0)
11541 --i;
11543 return i;
11546 /* If the low bit is set and the high bit is not, or the mask is all
11547 1's, the value is 31. */
11548 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
11549 return 31;
11551 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11552 from the left. */
11553 i = 0;
11554 while (((val <<= 1) & 0x80000000) != 0)
11555 ++i;
11557 return i;
11560 /* Locate some local-dynamic symbol still in use by this function
11561 so that we can print its name in some tls_ld pattern. */
11563 static const char *
11564 rs6000_get_some_local_dynamic_name (void)
11566 rtx insn;
11568 if (cfun->machine->some_ld_name)
11569 return cfun->machine->some_ld_name;
11571 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
11572 if (INSN_P (insn)
11573 && for_each_rtx (&PATTERN (insn),
11574 rs6000_get_some_local_dynamic_name_1, 0))
11575 return cfun->machine->some_ld_name;
11577 gcc_unreachable ();
11580 /* Helper function for rs6000_get_some_local_dynamic_name. */
11582 static int
11583 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
11585 rtx x = *px;
11587 if (GET_CODE (x) == SYMBOL_REF)
11589 const char *str = XSTR (x, 0);
11590 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
11592 cfun->machine->some_ld_name = str;
11593 return 1;
11597 return 0;
11600 /* Write out a function code label. */
11602 void
11603 rs6000_output_function_entry (FILE *file, const char *fname)
11605 if (fname[0] != '.')
11607 switch (DEFAULT_ABI)
11609 default:
11610 gcc_unreachable ();
11612 case ABI_AIX:
11613 if (DOT_SYMBOLS)
11614 putc ('.', file);
11615 else
11616 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
11617 break;
11619 case ABI_V4:
11620 case ABI_DARWIN:
11621 break;
11624 if (TARGET_AIX)
11625 RS6000_OUTPUT_BASENAME (file, fname);
11626 else
11627 assemble_name (file, fname);
11630 /* Print an operand. Recognize special options, documented below. */
11632 #if TARGET_ELF
11633 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
11634 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
11635 #else
11636 #define SMALL_DATA_RELOC "sda21"
11637 #define SMALL_DATA_REG 0
11638 #endif
11640 void
11641 print_operand (FILE *file, rtx x, int code)
11643 int i;
11644 HOST_WIDE_INT val;
11645 unsigned HOST_WIDE_INT uval;
11647 switch (code)
11649 case '.':
11650 /* Write out an instruction after the call which may be replaced
11651 with glue code by the loader. This depends on the AIX version. */
11652 asm_fprintf (file, RS6000_CALL_GLUE);
11653 return;
11655 /* %a is output_address. */
11657 case 'A':
11658 /* If X is a constant integer whose low-order 5 bits are zero,
11659 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
11660 in the AIX assembler where "sri" with a zero shift count
11661 writes a trash instruction. */
11662 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
11663 putc ('l', file);
11664 else
11665 putc ('r', file);
11666 return;
11668 case 'b':
11669 /* If constant, low-order 16 bits of constant, unsigned.
11670 Otherwise, write normally. */
11671 if (INT_P (x))
11672 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
11673 else
11674 print_operand (file, x, 0);
11675 return;
11677 case 'B':
11678 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
11679 for 64-bit mask direction. */
11680 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
11681 return;
11683 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
11684 output_operand. */
11686 case 'c':
11687 /* X is a CR register. Print the number of the GT bit of the CR. */
11688 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11689 output_operand_lossage ("invalid %%E value");
11690 else
11691 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
11692 return;
11694 case 'D':
11695 /* Like 'J' but get to the GT bit only. */
11696 gcc_assert (GET_CODE (x) == REG);
11698 /* Bit 1 is GT bit. */
11699 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
11701 /* Add one for shift count in rlinm for scc. */
11702 fprintf (file, "%d", i + 1);
11703 return;
11705 case 'E':
11706 /* X is a CR register. Print the number of the EQ bit of the CR */
11707 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11708 output_operand_lossage ("invalid %%E value");
11709 else
11710 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
11711 return;
11713 case 'f':
11714 /* X is a CR register. Print the shift count needed to move it
11715 to the high-order four bits. */
11716 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11717 output_operand_lossage ("invalid %%f value");
11718 else
11719 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
11720 return;
11722 case 'F':
11723 /* Similar, but print the count for the rotate in the opposite
11724 direction. */
11725 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11726 output_operand_lossage ("invalid %%F value");
11727 else
11728 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
11729 return;
11731 case 'G':
11732 /* X is a constant integer. If it is negative, print "m",
11733 otherwise print "z". This is to make an aze or ame insn. */
11734 if (GET_CODE (x) != CONST_INT)
11735 output_operand_lossage ("invalid %%G value");
11736 else if (INTVAL (x) >= 0)
11737 putc ('z', file);
11738 else
11739 putc ('m', file);
11740 return;
11742 case 'h':
11743 /* If constant, output low-order five bits. Otherwise, write
11744 normally. */
11745 if (INT_P (x))
11746 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
11747 else
11748 print_operand (file, x, 0);
11749 return;
11751 case 'H':
11752 /* If constant, output low-order six bits. Otherwise, write
11753 normally. */
11754 if (INT_P (x))
11755 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
11756 else
11757 print_operand (file, x, 0);
11758 return;
11760 case 'I':
11761 /* Print `i' if this is a constant, else nothing. */
11762 if (INT_P (x))
11763 putc ('i', file);
11764 return;
11766 case 'j':
11767 /* Write the bit number in CCR for jump. */
11768 i = ccr_bit (x, 0);
11769 if (i == -1)
11770 output_operand_lossage ("invalid %%j code");
11771 else
11772 fprintf (file, "%d", i);
11773 return;
11775 case 'J':
11776 /* Similar, but add one for shift count in rlinm for scc and pass
11777 scc flag to `ccr_bit'. */
11778 i = ccr_bit (x, 1);
11779 if (i == -1)
11780 output_operand_lossage ("invalid %%J code");
11781 else
11782 /* If we want bit 31, write a shift count of zero, not 32. */
11783 fprintf (file, "%d", i == 31 ? 0 : i + 1);
11784 return;
11786 case 'k':
11787 /* X must be a constant. Write the 1's complement of the
11788 constant. */
11789 if (! INT_P (x))
11790 output_operand_lossage ("invalid %%k value");
11791 else
11792 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
11793 return;
11795 case 'K':
11796 /* X must be a symbolic constant on ELF. Write an
11797 expression suitable for an 'addi' that adds in the low 16
11798 bits of the MEM. */
11799 if (GET_CODE (x) != CONST)
11801 print_operand_address (file, x);
11802 fputs ("@l", file);
11804 else
11806 if (GET_CODE (XEXP (x, 0)) != PLUS
11807 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
11808 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
11809 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
11810 output_operand_lossage ("invalid %%K value");
11811 print_operand_address (file, XEXP (XEXP (x, 0), 0));
11812 fputs ("@l", file);
11813 /* For GNU as, there must be a non-alphanumeric character
11814 between 'l' and the number. The '-' is added by
11815 print_operand() already. */
11816 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
11817 fputs ("+", file);
11818 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
11820 return;
11822 /* %l is output_asm_label. */
11824 case 'L':
11825 /* Write second word of DImode or DFmode reference. Works on register
11826 or non-indexed memory only. */
11827 if (GET_CODE (x) == REG)
11828 fputs (reg_names[REGNO (x) + 1], file);
11829 else if (GET_CODE (x) == MEM)
11831 /* Handle possible auto-increment. Since it is pre-increment and
11832 we have already done it, we can just use an offset of word. */
11833 if (GET_CODE (XEXP (x, 0)) == PRE_INC
11834 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
11835 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
11836 UNITS_PER_WORD));
11837 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
11838 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
11839 UNITS_PER_WORD));
11840 else
11841 output_address (XEXP (adjust_address_nv (x, SImode,
11842 UNITS_PER_WORD),
11843 0));
11845 if (small_data_operand (x, GET_MODE (x)))
11846 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11847 reg_names[SMALL_DATA_REG]);
11849 return;
11851 case 'm':
11852 /* MB value for a mask operand. */
11853 if (! mask_operand (x, SImode))
11854 output_operand_lossage ("invalid %%m value");
11856 fprintf (file, "%d", extract_MB (x));
11857 return;
11859 case 'M':
11860 /* ME value for a mask operand. */
11861 if (! mask_operand (x, SImode))
11862 output_operand_lossage ("invalid %%M value");
11864 fprintf (file, "%d", extract_ME (x));
11865 return;
11867 /* %n outputs the negative of its operand. */
11869 case 'N':
11870 /* Write the number of elements in the vector times 4. */
11871 if (GET_CODE (x) != PARALLEL)
11872 output_operand_lossage ("invalid %%N value");
11873 else
11874 fprintf (file, "%d", XVECLEN (x, 0) * 4);
11875 return;
11877 case 'O':
11878 /* Similar, but subtract 1 first. */
11879 if (GET_CODE (x) != PARALLEL)
11880 output_operand_lossage ("invalid %%O value");
11881 else
11882 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
11883 return;
11885 case 'p':
11886 /* X is a CONST_INT that is a power of two. Output the logarithm. */
11887 if (! INT_P (x)
11888 || INT_LOWPART (x) < 0
11889 || (i = exact_log2 (INT_LOWPART (x))) < 0)
11890 output_operand_lossage ("invalid %%p value");
11891 else
11892 fprintf (file, "%d", i);
11893 return;
11895 case 'P':
11896 /* The operand must be an indirect memory reference. The result
11897 is the register name. */
11898 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
11899 || REGNO (XEXP (x, 0)) >= 32)
11900 output_operand_lossage ("invalid %%P value");
11901 else
11902 fputs (reg_names[REGNO (XEXP (x, 0))], file);
11903 return;
11905 case 'q':
11906 /* This outputs the logical code corresponding to a boolean
11907 expression. The expression may have one or both operands
11908 negated (if one, only the first one). For condition register
11909 logical operations, it will also treat the negated
11910 CR codes as NOTs, but not handle NOTs of them. */
11912 const char *const *t = 0;
11913 const char *s;
11914 enum rtx_code code = GET_CODE (x);
11915 static const char * const tbl[3][3] = {
11916 { "and", "andc", "nor" },
11917 { "or", "orc", "nand" },
11918 { "xor", "eqv", "xor" } };
11920 if (code == AND)
11921 t = tbl[0];
11922 else if (code == IOR)
11923 t = tbl[1];
11924 else if (code == XOR)
11925 t = tbl[2];
11926 else
11927 output_operand_lossage ("invalid %%q value");
11929 if (GET_CODE (XEXP (x, 0)) != NOT)
11930 s = t[0];
11931 else
11933 if (GET_CODE (XEXP (x, 1)) == NOT)
11934 s = t[2];
11935 else
11936 s = t[1];
11939 fputs (s, file);
11941 return;
11943 case 'Q':
11944 if (TARGET_MFCRF)
11945 fputc (',', file);
11946 /* FALLTHRU */
11947 else
11948 return;
11950 case 'R':
11951 /* X is a CR register. Print the mask for `mtcrf'. */
11952 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11953 output_operand_lossage ("invalid %%R value");
11954 else
11955 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
11956 return;
11958 case 's':
11959 /* Low 5 bits of 32 - value */
11960 if (! INT_P (x))
11961 output_operand_lossage ("invalid %%s value");
11962 else
11963 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
11964 return;
11966 case 'S':
11967 /* PowerPC64 mask position. All 0's is excluded.
11968 CONST_INT 32-bit mask is considered sign-extended so any
11969 transition must occur within the CONST_INT, not on the boundary. */
11970 if (! mask64_operand (x, DImode))
11971 output_operand_lossage ("invalid %%S value");
11973 uval = INT_LOWPART (x);
11975 if (uval & 1) /* Clear Left */
11977 #if HOST_BITS_PER_WIDE_INT > 64
11978 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
11979 #endif
11980 i = 64;
11982 else /* Clear Right */
11984 uval = ~uval;
11985 #if HOST_BITS_PER_WIDE_INT > 64
11986 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
11987 #endif
11988 i = 63;
11990 while (uval != 0)
11991 --i, uval >>= 1;
11992 gcc_assert (i >= 0);
11993 fprintf (file, "%d", i);
11994 return;
11996 case 't':
11997 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
11998 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
12000 /* Bit 3 is OV bit. */
12001 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
12003 /* If we want bit 31, write a shift count of zero, not 32. */
12004 fprintf (file, "%d", i == 31 ? 0 : i + 1);
12005 return;
12007 case 'T':
12008 /* Print the symbolic name of a branch target register. */
12009 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
12010 && REGNO (x) != CTR_REGNO))
12011 output_operand_lossage ("invalid %%T value");
12012 else if (REGNO (x) == LR_REGNO)
12013 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
12014 else
12015 fputs ("ctr", file);
12016 return;
12018 case 'u':
12019 /* High-order 16 bits of constant for use in unsigned operand. */
12020 if (! INT_P (x))
12021 output_operand_lossage ("invalid %%u value");
12022 else
12023 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
12024 (INT_LOWPART (x) >> 16) & 0xffff);
12025 return;
12027 case 'v':
12028 /* High-order 16 bits of constant for use in signed operand. */
12029 if (! INT_P (x))
12030 output_operand_lossage ("invalid %%v value");
12031 else
12032 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
12033 (INT_LOWPART (x) >> 16) & 0xffff);
12034 return;
12036 case 'U':
12037 /* Print `u' if this has an auto-increment or auto-decrement. */
12038 if (GET_CODE (x) == MEM
12039 && (GET_CODE (XEXP (x, 0)) == PRE_INC
12040 || GET_CODE (XEXP (x, 0)) == PRE_DEC
12041 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
12042 putc ('u', file);
12043 return;
12045 case 'V':
12046 /* Print the trap code for this operand. */
12047 switch (GET_CODE (x))
12049 case EQ:
12050 fputs ("eq", file); /* 4 */
12051 break;
12052 case NE:
12053 fputs ("ne", file); /* 24 */
12054 break;
12055 case LT:
12056 fputs ("lt", file); /* 16 */
12057 break;
12058 case LE:
12059 fputs ("le", file); /* 20 */
12060 break;
12061 case GT:
12062 fputs ("gt", file); /* 8 */
12063 break;
12064 case GE:
12065 fputs ("ge", file); /* 12 */
12066 break;
12067 case LTU:
12068 fputs ("llt", file); /* 2 */
12069 break;
12070 case LEU:
12071 fputs ("lle", file); /* 6 */
12072 break;
12073 case GTU:
12074 fputs ("lgt", file); /* 1 */
12075 break;
12076 case GEU:
12077 fputs ("lge", file); /* 5 */
12078 break;
12079 default:
12080 gcc_unreachable ();
12082 break;
12084 case 'w':
12085 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
12086 normally. */
12087 if (INT_P (x))
12088 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
12089 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
12090 else
12091 print_operand (file, x, 0);
12092 return;
12094 case 'W':
12095 /* MB value for a PowerPC64 rldic operand. */
12096 val = (GET_CODE (x) == CONST_INT
12097 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
12099 if (val < 0)
12100 i = -1;
12101 else
12102 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
12103 if ((val <<= 1) < 0)
12104 break;
12106 #if HOST_BITS_PER_WIDE_INT == 32
12107 if (GET_CODE (x) == CONST_INT && i >= 0)
12108 i += 32; /* zero-extend high-part was all 0's */
12109 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
12111 val = CONST_DOUBLE_LOW (x);
12113 gcc_assert (val);
12114 if (val < 0)
12115 --i;
12116 else
12117 for ( ; i < 64; i++)
12118 if ((val <<= 1) < 0)
12119 break;
12121 #endif
12123 fprintf (file, "%d", i + 1);
12124 return;
12126 case 'X':
12127 if (GET_CODE (x) == MEM
12128 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
12129 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
12130 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
12131 putc ('x', file);
12132 return;
12134 case 'Y':
12135 /* Like 'L', for third word of TImode */
12136 if (GET_CODE (x) == REG)
12137 fputs (reg_names[REGNO (x) + 2], file);
12138 else if (GET_CODE (x) == MEM)
12140 if (GET_CODE (XEXP (x, 0)) == PRE_INC
12141 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
12142 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
12143 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
12144 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
12145 else
12146 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
12147 if (small_data_operand (x, GET_MODE (x)))
12148 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
12149 reg_names[SMALL_DATA_REG]);
12151 return;
12153 case 'z':
12154 /* X is a SYMBOL_REF. Write out the name preceded by a
12155 period and without any trailing data in brackets. Used for function
12156 names. If we are configured for System V (or the embedded ABI) on
12157 the PowerPC, do not emit the period, since those systems do not use
12158 TOCs and the like. */
12159 gcc_assert (GET_CODE (x) == SYMBOL_REF);
12161 /* Mark the decl as referenced so that cgraph will output the
12162 function. */
12163 if (SYMBOL_REF_DECL (x))
12164 mark_decl_referenced (SYMBOL_REF_DECL (x));
12166 /* For macho, check to see if we need a stub. */
12167 if (TARGET_MACHO)
12169 const char *name = XSTR (x, 0);
12170 #if TARGET_MACHO
12171 if (MACHOPIC_INDIRECT
12172 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
12173 name = machopic_indirection_name (x, /*stub_p=*/true);
12174 #endif
12175 assemble_name (file, name);
12177 else if (!DOT_SYMBOLS)
12178 assemble_name (file, XSTR (x, 0));
12179 else
12180 rs6000_output_function_entry (file, XSTR (x, 0));
12181 return;
12183 case 'Z':
12184 /* Like 'L', for last word of TImode. */
12185 if (GET_CODE (x) == REG)
12186 fputs (reg_names[REGNO (x) + 3], file);
12187 else if (GET_CODE (x) == MEM)
12189 if (GET_CODE (XEXP (x, 0)) == PRE_INC
12190 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
12191 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
12192 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
12193 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
12194 else
12195 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
12196 if (small_data_operand (x, GET_MODE (x)))
12197 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
12198 reg_names[SMALL_DATA_REG]);
12200 return;
12202 /* Print AltiVec or SPE memory operand. */
12203 case 'y':
12205 rtx tmp;
12207 gcc_assert (GET_CODE (x) == MEM);
12209 tmp = XEXP (x, 0);
12211 /* Ugly hack because %y is overloaded. */
12212 if ((TARGET_SPE || TARGET_E500_DOUBLE)
12213 && (GET_MODE_SIZE (GET_MODE (x)) == 8
12214 || GET_MODE (x) == TFmode
12215 || GET_MODE (x) == TImode))
12217 /* Handle [reg]. */
12218 if (GET_CODE (tmp) == REG)
12220 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
12221 break;
12223 /* Handle [reg+UIMM]. */
12224 else if (GET_CODE (tmp) == PLUS &&
12225 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
12227 int x;
12229 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
12231 x = INTVAL (XEXP (tmp, 1));
12232 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
12233 break;
12236 /* Fall through. Must be [reg+reg]. */
12238 if (TARGET_ALTIVEC
12239 && GET_CODE (tmp) == AND
12240 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
12241 && INTVAL (XEXP (tmp, 1)) == -16)
12242 tmp = XEXP (tmp, 0);
12243 if (GET_CODE (tmp) == REG)
12244 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
12245 else
12247 gcc_assert (GET_CODE (tmp) == PLUS
12248 && REG_P (XEXP (tmp, 0))
12249 && REG_P (XEXP (tmp, 1)));
12251 if (REGNO (XEXP (tmp, 0)) == 0)
12252 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
12253 reg_names[ REGNO (XEXP (tmp, 0)) ]);
12254 else
12255 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
12256 reg_names[ REGNO (XEXP (tmp, 1)) ]);
12258 break;
12261 case 0:
12262 if (GET_CODE (x) == REG)
12263 fprintf (file, "%s", reg_names[REGNO (x)]);
12264 else if (GET_CODE (x) == MEM)
12266 /* We need to handle PRE_INC and PRE_DEC here, since we need to
12267 know the width from the mode. */
12268 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
12269 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
12270 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
12271 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
12272 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
12273 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
12274 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
12275 output_address (XEXP (XEXP (x, 0), 1));
12276 else
12277 output_address (XEXP (x, 0));
12279 else
12280 output_addr_const (file, x);
12281 return;
12283 case '&':
12284 assemble_name (file, rs6000_get_some_local_dynamic_name ());
12285 return;
12287 default:
12288 output_operand_lossage ("invalid %%xn code");
12292 /* Print the address of an operand. */
12294 void
12295 print_operand_address (FILE *file, rtx x)
12297 if (GET_CODE (x) == REG)
12298 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
12299 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
12300 || GET_CODE (x) == LABEL_REF)
12302 output_addr_const (file, x);
12303 if (small_data_operand (x, GET_MODE (x)))
12304 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
12305 reg_names[SMALL_DATA_REG]);
12306 else
12307 gcc_assert (!TARGET_TOC);
12309 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
12311 gcc_assert (REG_P (XEXP (x, 0)));
12312 if (REGNO (XEXP (x, 0)) == 0)
12313 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
12314 reg_names[ REGNO (XEXP (x, 0)) ]);
12315 else
12316 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
12317 reg_names[ REGNO (XEXP (x, 1)) ]);
12319 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
12320 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
12321 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
12322 #if TARGET_ELF
12323 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
12324 && CONSTANT_P (XEXP (x, 1)))
12326 output_addr_const (file, XEXP (x, 1));
12327 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
12329 #endif
12330 #if TARGET_MACHO
12331 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
12332 && CONSTANT_P (XEXP (x, 1)))
12334 fprintf (file, "lo16(");
12335 output_addr_const (file, XEXP (x, 1));
12336 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
12338 #endif
12339 else if (legitimate_constant_pool_address_p (x))
12341 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
12343 rtx contains_minus = XEXP (x, 1);
12344 rtx minus, symref;
12345 const char *name;
12347 /* Find the (minus (sym) (toc)) buried in X, and temporarily
12348 turn it into (sym) for output_addr_const. */
12349 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
12350 contains_minus = XEXP (contains_minus, 0);
12352 minus = XEXP (contains_minus, 0);
12353 symref = XEXP (minus, 0);
12354 XEXP (contains_minus, 0) = symref;
12355 if (TARGET_ELF)
12357 char *newname;
12359 name = XSTR (symref, 0);
12360 newname = alloca (strlen (name) + sizeof ("@toc"));
12361 strcpy (newname, name);
12362 strcat (newname, "@toc");
12363 XSTR (symref, 0) = newname;
12365 output_addr_const (file, XEXP (x, 1));
12366 if (TARGET_ELF)
12367 XSTR (symref, 0) = name;
12368 XEXP (contains_minus, 0) = minus;
12370 else
12371 output_addr_const (file, XEXP (x, 1));
12373 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
12375 else
12376 gcc_unreachable ();
12379 /* Target hook for assembling integer objects. The PowerPC version has
12380 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
12381 is defined. It also needs to handle DI-mode objects on 64-bit
12382 targets. */
12384 static bool
12385 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
12387 #ifdef RELOCATABLE_NEEDS_FIXUP
12388 /* Special handling for SI values. */
12389 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
12391 static int recurse = 0;
12393 /* For -mrelocatable, we mark all addresses that need to be fixed up
12394 in the .fixup section. */
12395 if (TARGET_RELOCATABLE
12396 && in_section != toc_section
12397 && in_section != text_section
12398 && !unlikely_text_section_p (in_section)
12399 && !recurse
12400 && GET_CODE (x) != CONST_INT
12401 && GET_CODE (x) != CONST_DOUBLE
12402 && CONSTANT_P (x))
12404 char buf[256];
12406 recurse = 1;
12407 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
12408 fixuplabelno++;
12409 ASM_OUTPUT_LABEL (asm_out_file, buf);
12410 fprintf (asm_out_file, "\t.long\t(");
12411 output_addr_const (asm_out_file, x);
12412 fprintf (asm_out_file, ")@fixup\n");
12413 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
12414 ASM_OUTPUT_ALIGN (asm_out_file, 2);
12415 fprintf (asm_out_file, "\t.long\t");
12416 assemble_name (asm_out_file, buf);
12417 fprintf (asm_out_file, "\n\t.previous\n");
12418 recurse = 0;
12419 return true;
12421 /* Remove initial .'s to turn a -mcall-aixdesc function
12422 address into the address of the descriptor, not the function
12423 itself. */
12424 else if (GET_CODE (x) == SYMBOL_REF
12425 && XSTR (x, 0)[0] == '.'
12426 && DEFAULT_ABI == ABI_AIX)
12428 const char *name = XSTR (x, 0);
12429 while (*name == '.')
12430 name++;
12432 fprintf (asm_out_file, "\t.long\t%s\n", name);
12433 return true;
12436 #endif /* RELOCATABLE_NEEDS_FIXUP */
12437 return default_assemble_integer (x, size, aligned_p);
12440 #ifdef HAVE_GAS_HIDDEN
12441 /* Emit an assembler directive to set symbol visibility for DECL to
12442 VISIBILITY_TYPE. */
12444 static void
12445 rs6000_assemble_visibility (tree decl, int vis)
12447 /* Functions need to have their entry point symbol visibility set as
12448 well as their descriptor symbol visibility. */
12449 if (DEFAULT_ABI == ABI_AIX
12450 && DOT_SYMBOLS
12451 && TREE_CODE (decl) == FUNCTION_DECL)
12453 static const char * const visibility_types[] = {
12454 NULL, "internal", "hidden", "protected"
12457 const char *name, *type;
12459 name = ((* targetm.strip_name_encoding)
12460 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
12461 type = visibility_types[vis];
12463 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
12464 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
12466 else
12467 default_assemble_visibility (decl, vis);
12469 #endif
12471 enum rtx_code
12472 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
12474 /* Reversal of FP compares takes care -- an ordered compare
12475 becomes an unordered compare and vice versa. */
12476 if (mode == CCFPmode
12477 && (!flag_finite_math_only
12478 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
12479 || code == UNEQ || code == LTGT))
12480 return reverse_condition_maybe_unordered (code);
12481 else
12482 return reverse_condition (code);
12485 /* Generate a compare for CODE. Return a brand-new rtx that
12486 represents the result of the compare. */
12488 static rtx
12489 rs6000_generate_compare (enum rtx_code code)
12491 enum machine_mode comp_mode;
12492 rtx compare_result;
12494 if (rs6000_compare_fp_p)
12495 comp_mode = CCFPmode;
12496 else if (code == GTU || code == LTU
12497 || code == GEU || code == LEU)
12498 comp_mode = CCUNSmode;
12499 else if ((code == EQ || code == NE)
12500 && GET_CODE (rs6000_compare_op0) == SUBREG
12501 && GET_CODE (rs6000_compare_op1) == SUBREG
12502 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
12503 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
12504 /* These are unsigned values, perhaps there will be a later
12505 ordering compare that can be shared with this one.
12506 Unfortunately we cannot detect the signedness of the operands
12507 for non-subregs. */
12508 comp_mode = CCUNSmode;
12509 else
12510 comp_mode = CCmode;
12512 /* First, the compare. */
12513 compare_result = gen_reg_rtx (comp_mode);
12515 /* E500 FP compare instructions on the GPRs. Yuck! */
12516 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
12517 && rs6000_compare_fp_p)
12519 rtx cmp, or_result, compare_result2;
12520 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
12522 if (op_mode == VOIDmode)
12523 op_mode = GET_MODE (rs6000_compare_op1);
12525 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
12526 This explains the following mess. */
12528 switch (code)
12530 case EQ: case UNEQ: case NE: case LTGT:
12531 switch (op_mode)
12533 case SFmode:
12534 cmp = flag_unsafe_math_optimizations
12535 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
12536 rs6000_compare_op1)
12537 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
12538 rs6000_compare_op1);
12539 break;
12541 case DFmode:
12542 cmp = flag_unsafe_math_optimizations
12543 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
12544 rs6000_compare_op1)
12545 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
12546 rs6000_compare_op1);
12547 break;
12549 case TFmode:
12550 cmp = flag_unsafe_math_optimizations
12551 ? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
12552 rs6000_compare_op1)
12553 : gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
12554 rs6000_compare_op1);
12555 break;
12557 default:
12558 gcc_unreachable ();
12560 break;
12562 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
12563 switch (op_mode)
12565 case SFmode:
12566 cmp = flag_unsafe_math_optimizations
12567 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
12568 rs6000_compare_op1)
12569 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
12570 rs6000_compare_op1);
12571 break;
12573 case DFmode:
12574 cmp = flag_unsafe_math_optimizations
12575 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
12576 rs6000_compare_op1)
12577 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
12578 rs6000_compare_op1);
12579 break;
12581 case TFmode:
12582 cmp = flag_unsafe_math_optimizations
12583 ? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
12584 rs6000_compare_op1)
12585 : gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
12586 rs6000_compare_op1);
12587 break;
12589 default:
12590 gcc_unreachable ();
12592 break;
12594 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
12595 switch (op_mode)
12597 case SFmode:
12598 cmp = flag_unsafe_math_optimizations
12599 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
12600 rs6000_compare_op1)
12601 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
12602 rs6000_compare_op1);
12603 break;
12605 case DFmode:
12606 cmp = flag_unsafe_math_optimizations
12607 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
12608 rs6000_compare_op1)
12609 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
12610 rs6000_compare_op1);
12611 break;
12613 case TFmode:
12614 cmp = flag_unsafe_math_optimizations
12615 ? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
12616 rs6000_compare_op1)
12617 : gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
12618 rs6000_compare_op1);
12619 break;
12621 default:
12622 gcc_unreachable ();
12624 break;
12625 default:
12626 gcc_unreachable ();
12629 /* Synthesize LE and GE from LT/GT || EQ. */
12630 if (code == LE || code == GE || code == LEU || code == GEU)
12632 emit_insn (cmp);
12634 switch (code)
12636 case LE: code = LT; break;
12637 case GE: code = GT; break;
12638 case LEU: code = LT; break;
12639 case GEU: code = GT; break;
12640 default: gcc_unreachable ();
12643 compare_result2 = gen_reg_rtx (CCFPmode);
12645 /* Do the EQ. */
12646 switch (op_mode)
12648 case SFmode:
12649 cmp = flag_unsafe_math_optimizations
12650 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
12651 rs6000_compare_op1)
12652 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
12653 rs6000_compare_op1);
12654 break;
12656 case DFmode:
12657 cmp = flag_unsafe_math_optimizations
12658 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
12659 rs6000_compare_op1)
12660 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
12661 rs6000_compare_op1);
12662 break;
12664 case TFmode:
12665 cmp = flag_unsafe_math_optimizations
12666 ? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
12667 rs6000_compare_op1)
12668 : gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
12669 rs6000_compare_op1);
12670 break;
12672 default:
12673 gcc_unreachable ();
12675 emit_insn (cmp);
12677 /* OR them together. */
12678 or_result = gen_reg_rtx (CCFPmode);
12679 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
12680 compare_result2);
12681 compare_result = or_result;
12682 code = EQ;
12684 else
12686 if (code == NE || code == LTGT)
12687 code = NE;
12688 else
12689 code = EQ;
12692 emit_insn (cmp);
12694 else
12696 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
12697 CLOBBERs to match cmptf_internal2 pattern. */
12698 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
12699 && GET_MODE (rs6000_compare_op0) == TFmode
12700 && !TARGET_IEEEQUAD
12701 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
12702 emit_insn (gen_rtx_PARALLEL (VOIDmode,
12703 gen_rtvec (9,
12704 gen_rtx_SET (VOIDmode,
12705 compare_result,
12706 gen_rtx_COMPARE (comp_mode,
12707 rs6000_compare_op0,
12708 rs6000_compare_op1)),
12709 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12710 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12711 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12712 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12713 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12714 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12715 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12716 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
12717 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
12718 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
12720 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
12721 comp_mode = CCEQmode;
12722 compare_result = gen_reg_rtx (CCEQmode);
12723 if (TARGET_64BIT)
12724 emit_insn (gen_stack_protect_testdi (compare_result,
12725 rs6000_compare_op0, op1));
12726 else
12727 emit_insn (gen_stack_protect_testsi (compare_result,
12728 rs6000_compare_op0, op1));
12730 else
12731 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
12732 gen_rtx_COMPARE (comp_mode,
12733 rs6000_compare_op0,
12734 rs6000_compare_op1)));
12737 /* Some kinds of FP comparisons need an OR operation;
12738 under flag_finite_math_only we don't bother. */
12739 if (rs6000_compare_fp_p
12740 && !flag_finite_math_only
12741 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
12742 && (code == LE || code == GE
12743 || code == UNEQ || code == LTGT
12744 || code == UNGT || code == UNLT))
12746 enum rtx_code or1, or2;
12747 rtx or1_rtx, or2_rtx, compare2_rtx;
12748 rtx or_result = gen_reg_rtx (CCEQmode);
12750 switch (code)
12752 case LE: or1 = LT; or2 = EQ; break;
12753 case GE: or1 = GT; or2 = EQ; break;
12754 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
12755 case LTGT: or1 = LT; or2 = GT; break;
12756 case UNGT: or1 = UNORDERED; or2 = GT; break;
12757 case UNLT: or1 = UNORDERED; or2 = LT; break;
12758 default: gcc_unreachable ();
12760 validate_condition_mode (or1, comp_mode);
12761 validate_condition_mode (or2, comp_mode);
12762 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
12763 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
12764 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
12765 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
12766 const_true_rtx);
12767 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
12769 compare_result = or_result;
12770 code = EQ;
12773 validate_condition_mode (code, GET_MODE (compare_result));
12775 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
12779 /* Emit the RTL for an sCOND pattern. */
12781 void
12782 rs6000_emit_sCOND (enum rtx_code code, rtx result)
12784 rtx condition_rtx;
12785 enum machine_mode op_mode;
12786 enum rtx_code cond_code;
12788 condition_rtx = rs6000_generate_compare (code);
12789 cond_code = GET_CODE (condition_rtx);
12791 if (rs6000_compare_fp_p
12792 && !TARGET_FPRS && TARGET_HARD_FLOAT)
12794 rtx t;
12796 PUT_MODE (condition_rtx, SImode);
12797 t = XEXP (condition_rtx, 0);
12799 gcc_assert (cond_code == NE || cond_code == EQ);
12801 if (cond_code == NE)
12802 emit_insn (gen_e500_flip_gt_bit (t, t));
12804 emit_insn (gen_move_from_CR_gt_bit (result, t));
12805 return;
12808 if (cond_code == NE
12809 || cond_code == GE || cond_code == LE
12810 || cond_code == GEU || cond_code == LEU
12811 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
12813 rtx not_result = gen_reg_rtx (CCEQmode);
12814 rtx not_op, rev_cond_rtx;
12815 enum machine_mode cc_mode;
12817 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
12819 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
12820 SImode, XEXP (condition_rtx, 0), const0_rtx);
12821 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
12822 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
12823 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
12826 op_mode = GET_MODE (rs6000_compare_op0);
12827 if (op_mode == VOIDmode)
12828 op_mode = GET_MODE (rs6000_compare_op1);
12830 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
12832 PUT_MODE (condition_rtx, DImode);
12833 convert_move (result, condition_rtx, 0);
12835 else
12837 PUT_MODE (condition_rtx, SImode);
12838 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
12842 /* Emit a branch of kind CODE to location LOC. */
12844 void
12845 rs6000_emit_cbranch (enum rtx_code code, rtx loc)
12847 rtx condition_rtx, loc_ref;
12849 condition_rtx = rs6000_generate_compare (code);
12850 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
12851 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
12852 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
12853 loc_ref, pc_rtx)));
12856 /* Return the string to output a conditional branch to LABEL, which is
12857 the operand number of the label, or -1 if the branch is really a
12858 conditional return.
12860 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
12861 condition code register and its mode specifies what kind of
12862 comparison we made.
12864 REVERSED is nonzero if we should reverse the sense of the comparison.
12866 INSN is the insn. */
12868 char *
12869 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
12871 static char string[64];
12872 enum rtx_code code = GET_CODE (op);
12873 rtx cc_reg = XEXP (op, 0);
12874 enum machine_mode mode = GET_MODE (cc_reg);
12875 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
12876 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12877 int really_reversed = reversed ^ need_longbranch;
12878 char *s = string;
12879 const char *ccode;
12880 const char *pred;
12881 rtx note;
12883 validate_condition_mode (code, mode);
12885 /* Work out which way this really branches. We could use
12886 reverse_condition_maybe_unordered here always but this
12887 makes the resulting assembler clearer. */
12888 if (really_reversed)
12890 /* Reversal of FP compares takes care -- an ordered compare
12891 becomes an unordered compare and vice versa. */
12892 if (mode == CCFPmode)
12893 code = reverse_condition_maybe_unordered (code);
12894 else
12895 code = reverse_condition (code);
12898 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
12900 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
12901 to the GT bit. */
12902 switch (code)
12904 case EQ:
12905 /* Opposite of GT. */
12906 code = GT;
12907 break;
12909 case NE:
12910 code = UNLE;
12911 break;
12913 default:
12914 gcc_unreachable ();
12918 switch (code)
12920 /* Not all of these are actually distinct opcodes, but
12921 we distinguish them for clarity of the resulting assembler. */
12922 case NE: case LTGT:
12923 ccode = "ne"; break;
12924 case EQ: case UNEQ:
12925 ccode = "eq"; break;
12926 case GE: case GEU:
12927 ccode = "ge"; break;
12928 case GT: case GTU: case UNGT:
12929 ccode = "gt"; break;
12930 case LE: case LEU:
12931 ccode = "le"; break;
12932 case LT: case LTU: case UNLT:
12933 ccode = "lt"; break;
12934 case UNORDERED: ccode = "un"; break;
12935 case ORDERED: ccode = "nu"; break;
12936 case UNGE: ccode = "nl"; break;
12937 case UNLE: ccode = "ng"; break;
12938 default:
12939 gcc_unreachable ();
12942 /* Maybe we have a guess as to how likely the branch is.
12943 The old mnemonics don't have a way to specify this information. */
12944 pred = "";
12945 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
12946 if (note != NULL_RTX)
12948 /* PROB is the difference from 50%. */
12949 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
12951 /* Only hint for highly probable/improbable branches on newer
12952 cpus as static prediction overrides processor dynamic
12953 prediction. For older cpus we may as well always hint, but
12954 assume not taken for branches that are very close to 50% as a
12955 mispredicted taken branch is more expensive than a
12956 mispredicted not-taken branch. */
12957 if (rs6000_always_hint
12958 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
12959 && br_prob_note_reliable_p (note)))
12961 if (abs (prob) > REG_BR_PROB_BASE / 20
12962 && ((prob > 0) ^ need_longbranch))
12963 pred = "+";
12964 else
12965 pred = "-";
12969 if (label == NULL)
12970 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12971 else
12972 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12974 /* We need to escape any '%' characters in the reg_names string.
12975 Assume they'd only be the first character.... */
12976 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
12977 *s++ = '%';
12978 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12980 if (label != NULL)
12982 /* If the branch distance was too far, we may have to use an
12983 unconditional branch to go the distance. */
12984 if (need_longbranch)
12985 s += sprintf (s, ",$+8\n\tb %s", label);
12986 else
12987 s += sprintf (s, ",%s", label);
12990 return string;
12993 /* Return the string to flip the GT bit on a CR. */
12994 char *
12995 output_e500_flip_gt_bit (rtx dst, rtx src)
12997 static char string[64];
12998 int a, b;
13000 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
13001 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
13003 /* GT bit. */
13004 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
13005 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
13007 sprintf (string, "crnot %d,%d", a, b);
13008 return string;
13011 /* Return insn index for the vector compare instruction for given CODE,
13012 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
13013 not available. */
13015 static int
13016 get_vec_cmp_insn (enum rtx_code code,
13017 enum machine_mode dest_mode,
13018 enum machine_mode op_mode)
13020 if (!TARGET_ALTIVEC)
13021 return INSN_NOT_AVAILABLE;
13023 switch (code)
13025 case EQ:
13026 if (dest_mode == V16QImode && op_mode == V16QImode)
13027 return UNSPEC_VCMPEQUB;
13028 if (dest_mode == V8HImode && op_mode == V8HImode)
13029 return UNSPEC_VCMPEQUH;
13030 if (dest_mode == V4SImode && op_mode == V4SImode)
13031 return UNSPEC_VCMPEQUW;
13032 if (dest_mode == V4SImode && op_mode == V4SFmode)
13033 return UNSPEC_VCMPEQFP;
13034 break;
13035 case GE:
13036 if (dest_mode == V4SImode && op_mode == V4SFmode)
13037 return UNSPEC_VCMPGEFP;
13038 case GT:
13039 if (dest_mode == V16QImode && op_mode == V16QImode)
13040 return UNSPEC_VCMPGTSB;
13041 if (dest_mode == V8HImode && op_mode == V8HImode)
13042 return UNSPEC_VCMPGTSH;
13043 if (dest_mode == V4SImode && op_mode == V4SImode)
13044 return UNSPEC_VCMPGTSW;
13045 if (dest_mode == V4SImode && op_mode == V4SFmode)
13046 return UNSPEC_VCMPGTFP;
13047 break;
13048 case GTU:
13049 if (dest_mode == V16QImode && op_mode == V16QImode)
13050 return UNSPEC_VCMPGTUB;
13051 if (dest_mode == V8HImode && op_mode == V8HImode)
13052 return UNSPEC_VCMPGTUH;
13053 if (dest_mode == V4SImode && op_mode == V4SImode)
13054 return UNSPEC_VCMPGTUW;
13055 break;
13056 default:
13057 break;
13059 return INSN_NOT_AVAILABLE;
13062 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
13063 DMODE is expected destination mode. This is a recursive function. */
13065 static rtx
13066 rs6000_emit_vector_compare (enum rtx_code rcode,
13067 rtx op0, rtx op1,
13068 enum machine_mode dmode)
13070 int vec_cmp_insn;
13071 rtx mask;
13072 enum machine_mode dest_mode;
13073 enum machine_mode op_mode = GET_MODE (op1);
13075 gcc_assert (TARGET_ALTIVEC);
13076 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
13078 /* Floating point vector compare instructions uses destination V4SImode.
13079 Move destination to appropriate mode later. */
13080 if (dmode == V4SFmode)
13081 dest_mode = V4SImode;
13082 else
13083 dest_mode = dmode;
13085 mask = gen_reg_rtx (dest_mode);
13086 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
13088 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
13090 bool swap_operands = false;
13091 bool try_again = false;
13092 switch (rcode)
13094 case LT:
13095 rcode = GT;
13096 swap_operands = true;
13097 try_again = true;
13098 break;
13099 case LTU:
13100 rcode = GTU;
13101 swap_operands = true;
13102 try_again = true;
13103 break;
13104 case NE:
13105 case UNLE:
13106 case UNLT:
13107 case UNGE:
13108 case UNGT:
13109 /* Invert condition and try again.
13110 e.g., A != B becomes ~(A==B). */
13112 enum rtx_code rev_code;
13113 enum insn_code nor_code;
13114 rtx eq_rtx;
13116 rev_code = reverse_condition_maybe_unordered (rcode);
13117 eq_rtx = rs6000_emit_vector_compare (rev_code, op0, op1,
13118 dest_mode);
13120 nor_code = optab_handler (one_cmpl_optab, (int)dest_mode)->insn_code;
13121 gcc_assert (nor_code != CODE_FOR_nothing);
13122 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
13124 if (dmode != dest_mode)
13126 rtx temp = gen_reg_rtx (dest_mode);
13127 convert_move (temp, mask, 0);
13128 return temp;
13130 return mask;
13132 break;
13133 case GE:
13134 case GEU:
13135 case LE:
13136 case LEU:
13137 /* Try GT/GTU/LT/LTU OR EQ */
13139 rtx c_rtx, eq_rtx;
13140 enum insn_code ior_code;
13141 enum rtx_code new_code;
13143 switch (rcode)
13145 case GE:
13146 new_code = GT;
13147 break;
13149 case GEU:
13150 new_code = GTU;
13151 break;
13153 case LE:
13154 new_code = LT;
13155 break;
13157 case LEU:
13158 new_code = LTU;
13159 break;
13161 default:
13162 gcc_unreachable ();
13165 c_rtx = rs6000_emit_vector_compare (new_code,
13166 op0, op1, dest_mode);
13167 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
13168 dest_mode);
13170 ior_code = optab_handler (ior_optab, (int)dest_mode)->insn_code;
13171 gcc_assert (ior_code != CODE_FOR_nothing);
13172 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
13173 if (dmode != dest_mode)
13175 rtx temp = gen_reg_rtx (dest_mode);
13176 convert_move (temp, mask, 0);
13177 return temp;
13179 return mask;
13181 break;
13182 default:
13183 gcc_unreachable ();
13186 if (try_again)
13188 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
13189 /* You only get two chances. */
13190 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
13193 if (swap_operands)
13195 rtx tmp;
13196 tmp = op0;
13197 op0 = op1;
13198 op1 = tmp;
13202 emit_insn (gen_rtx_SET (VOIDmode, mask,
13203 gen_rtx_UNSPEC (dest_mode,
13204 gen_rtvec (2, op0, op1),
13205 vec_cmp_insn)));
13206 if (dmode != dest_mode)
13208 rtx temp = gen_reg_rtx (dest_mode);
13209 convert_move (temp, mask, 0);
13210 return temp;
13212 return mask;
13215 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
13216 valid insn doesn exist for given mode. */
13218 static int
13219 get_vsel_insn (enum machine_mode mode)
13221 switch (mode)
13223 case V4SImode:
13224 return UNSPEC_VSEL4SI;
13225 break;
13226 case V4SFmode:
13227 return UNSPEC_VSEL4SF;
13228 break;
13229 case V8HImode:
13230 return UNSPEC_VSEL8HI;
13231 break;
13232 case V16QImode:
13233 return UNSPEC_VSEL16QI;
13234 break;
13235 default:
13236 return INSN_NOT_AVAILABLE;
13237 break;
13239 return INSN_NOT_AVAILABLE;
13242 /* Emit vector select insn where DEST is destination using
13243 operands OP1, OP2 and MASK. */
13245 static void
13246 rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
13248 rtx t, temp;
13249 enum machine_mode dest_mode = GET_MODE (dest);
13250 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
13252 temp = gen_reg_rtx (dest_mode);
13254 /* For each vector element, select op1 when mask is 1 otherwise
13255 select op2. */
13256 t = gen_rtx_SET (VOIDmode, temp,
13257 gen_rtx_UNSPEC (dest_mode,
13258 gen_rtvec (3, op2, op1, mask),
13259 vsel_insn_index));
13260 emit_insn (t);
13261 emit_move_insn (dest, temp);
13262 return;
13265 /* Emit vector conditional expression.
13266 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
13267 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
13270 rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
13271 rtx cond, rtx cc_op0, rtx cc_op1)
13273 enum machine_mode dest_mode = GET_MODE (dest);
13274 enum rtx_code rcode = GET_CODE (cond);
13275 rtx mask;
13277 if (!TARGET_ALTIVEC)
13278 return 0;
13280 /* Get the vector mask for the given relational operations. */
13281 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
13283 rs6000_emit_vector_select (dest, op1, op2, mask);
13285 return 1;
13288 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
13289 operands of the last comparison is nonzero/true, FALSE_COND if it
13290 is zero/false. Return 0 if the hardware has no such operation. */
13293 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
13295 enum rtx_code code = GET_CODE (op);
13296 rtx op0 = rs6000_compare_op0;
13297 rtx op1 = rs6000_compare_op1;
13298 REAL_VALUE_TYPE c1;
13299 enum machine_mode compare_mode = GET_MODE (op0);
13300 enum machine_mode result_mode = GET_MODE (dest);
13301 rtx temp;
13302 bool is_against_zero;
13304 /* These modes should always match. */
13305 if (GET_MODE (op1) != compare_mode
13306 /* In the isel case however, we can use a compare immediate, so
13307 op1 may be a small constant. */
13308 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
13309 return 0;
13310 if (GET_MODE (true_cond) != result_mode)
13311 return 0;
13312 if (GET_MODE (false_cond) != result_mode)
13313 return 0;
13315 /* First, work out if the hardware can do this at all, or
13316 if it's too slow.... */
13317 if (! rs6000_compare_fp_p)
13319 if (TARGET_ISEL)
13320 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
13321 return 0;
13323 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
13324 && SCALAR_FLOAT_MODE_P (compare_mode))
13325 return 0;
13327 is_against_zero = op1 == CONST0_RTX (compare_mode);
13329 /* A floating-point subtract might overflow, underflow, or produce
13330 an inexact result, thus changing the floating-point flags, so it
13331 can't be generated if we care about that. It's safe if one side
13332 of the construct is zero, since then no subtract will be
13333 generated. */
13334 if (SCALAR_FLOAT_MODE_P (compare_mode)
13335 && flag_trapping_math && ! is_against_zero)
13336 return 0;
13338 /* Eliminate half of the comparisons by switching operands, this
13339 makes the remaining code simpler. */
13340 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
13341 || code == LTGT || code == LT || code == UNLE)
13343 code = reverse_condition_maybe_unordered (code);
13344 temp = true_cond;
13345 true_cond = false_cond;
13346 false_cond = temp;
13349 /* UNEQ and LTGT take four instructions for a comparison with zero,
13350 it'll probably be faster to use a branch here too. */
13351 if (code == UNEQ && HONOR_NANS (compare_mode))
13352 return 0;
13354 if (GET_CODE (op1) == CONST_DOUBLE)
13355 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
13357 /* We're going to try to implement comparisons by performing
13358 a subtract, then comparing against zero. Unfortunately,
13359 Inf - Inf is NaN which is not zero, and so if we don't
13360 know that the operand is finite and the comparison
13361 would treat EQ different to UNORDERED, we can't do it. */
13362 if (HONOR_INFINITIES (compare_mode)
13363 && code != GT && code != UNGE
13364 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
13365 /* Constructs of the form (a OP b ? a : b) are safe. */
13366 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
13367 || (! rtx_equal_p (op0, true_cond)
13368 && ! rtx_equal_p (op1, true_cond))))
13369 return 0;
13371 /* At this point we know we can use fsel. */
13373 /* Reduce the comparison to a comparison against zero. */
13374 if (! is_against_zero)
13376 temp = gen_reg_rtx (compare_mode);
13377 emit_insn (gen_rtx_SET (VOIDmode, temp,
13378 gen_rtx_MINUS (compare_mode, op0, op1)));
13379 op0 = temp;
13380 op1 = CONST0_RTX (compare_mode);
13383 /* If we don't care about NaNs we can reduce some of the comparisons
13384 down to faster ones. */
13385 if (! HONOR_NANS (compare_mode))
13386 switch (code)
13388 case GT:
13389 code = LE;
13390 temp = true_cond;
13391 true_cond = false_cond;
13392 false_cond = temp;
13393 break;
13394 case UNGE:
13395 code = GE;
13396 break;
13397 case UNEQ:
13398 code = EQ;
13399 break;
13400 default:
13401 break;
13404 /* Now, reduce everything down to a GE. */
13405 switch (code)
13407 case GE:
13408 break;
13410 case LE:
13411 temp = gen_reg_rtx (compare_mode);
13412 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
13413 op0 = temp;
13414 break;
13416 case ORDERED:
13417 temp = gen_reg_rtx (compare_mode);
13418 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
13419 op0 = temp;
13420 break;
13422 case EQ:
13423 temp = gen_reg_rtx (compare_mode);
13424 emit_insn (gen_rtx_SET (VOIDmode, temp,
13425 gen_rtx_NEG (compare_mode,
13426 gen_rtx_ABS (compare_mode, op0))));
13427 op0 = temp;
13428 break;
13430 case UNGE:
13431 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
13432 temp = gen_reg_rtx (result_mode);
13433 emit_insn (gen_rtx_SET (VOIDmode, temp,
13434 gen_rtx_IF_THEN_ELSE (result_mode,
13435 gen_rtx_GE (VOIDmode,
13436 op0, op1),
13437 true_cond, false_cond)));
13438 false_cond = true_cond;
13439 true_cond = temp;
13441 temp = gen_reg_rtx (compare_mode);
13442 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
13443 op0 = temp;
13444 break;
13446 case GT:
13447 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
13448 temp = gen_reg_rtx (result_mode);
13449 emit_insn (gen_rtx_SET (VOIDmode, temp,
13450 gen_rtx_IF_THEN_ELSE (result_mode,
13451 gen_rtx_GE (VOIDmode,
13452 op0, op1),
13453 true_cond, false_cond)));
13454 true_cond = false_cond;
13455 false_cond = temp;
13457 temp = gen_reg_rtx (compare_mode);
13458 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
13459 op0 = temp;
13460 break;
13462 default:
13463 gcc_unreachable ();
13466 emit_insn (gen_rtx_SET (VOIDmode, dest,
13467 gen_rtx_IF_THEN_ELSE (result_mode,
13468 gen_rtx_GE (VOIDmode,
13469 op0, op1),
13470 true_cond, false_cond)));
13471 return 1;
13474 /* Same as above, but for ints (isel). */
13476 static int
13477 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
13479 rtx condition_rtx, cr;
13481 /* All isel implementations thus far are 32-bits. */
13482 if (GET_MODE (rs6000_compare_op0) != SImode)
13483 return 0;
13485 /* We still have to do the compare, because isel doesn't do a
13486 compare, it just looks at the CRx bits set by a previous compare
13487 instruction. */
13488 condition_rtx = rs6000_generate_compare (GET_CODE (op));
13489 cr = XEXP (condition_rtx, 0);
13491 if (GET_MODE (cr) == CCmode)
13492 emit_insn (gen_isel_signed (dest, condition_rtx,
13493 true_cond, false_cond, cr));
13494 else
13495 emit_insn (gen_isel_unsigned (dest, condition_rtx,
13496 true_cond, false_cond, cr));
13498 return 1;
13501 const char *
13502 output_isel (rtx *operands)
13504 enum rtx_code code;
13506 code = GET_CODE (operands[1]);
13507 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
13509 PUT_CODE (operands[1], reverse_condition (code));
13510 return "isel %0,%3,%2,%j1";
13512 else
13513 return "isel %0,%2,%3,%j1";
13516 void
13517 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
13519 enum machine_mode mode = GET_MODE (op0);
13520 enum rtx_code c;
13521 rtx target;
13523 if (code == SMAX || code == SMIN)
13524 c = GE;
13525 else
13526 c = GEU;
13528 if (code == SMAX || code == UMAX)
13529 target = emit_conditional_move (dest, c, op0, op1, mode,
13530 op0, op1, mode, 0);
13531 else
13532 target = emit_conditional_move (dest, c, op0, op1, mode,
13533 op1, op0, mode, 0);
13534 gcc_assert (target);
13535 if (target != dest)
13536 emit_move_insn (dest, target);
13539 /* Emit instructions to perform a load-reserved/store-conditional operation.
13540 The operation performed is an atomic
13541 (set M (CODE:MODE M OP))
13542 If not NULL, BEFORE is atomically set to M before the operation, and
13543 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
13544 If SYNC_P then a memory barrier is emitted before the operation.
13545 Either OP or M may be wrapped in a NOT operation. */
13547 void
13548 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
13549 rtx m, rtx op, rtx before_param, rtx after_param,
13550 bool sync_p)
13552 enum machine_mode used_mode;
13553 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
13554 rtx used_m;
13555 rtvec vec;
13556 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
13557 rtx shift = NULL_RTX;
13559 if (sync_p)
13560 emit_insn (gen_memory_barrier ());
13562 if (GET_CODE (m) == NOT)
13563 used_m = XEXP (m, 0);
13564 else
13565 used_m = m;
13567 /* If this is smaller than SImode, we'll have to use SImode with
13568 adjustments. */
13569 if (mode == QImode || mode == HImode)
13571 rtx newop, oldop;
13573 if (MEM_ALIGN (used_m) >= 32)
13575 int ishift = 0;
13576 if (BYTES_BIG_ENDIAN)
13577 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
13579 shift = GEN_INT (ishift);
13580 used_m = change_address (used_m, SImode, 0);
13582 else
13584 rtx addrSI, aligned_addr;
13585 int shift_mask = mode == QImode ? 0x18 : 0x10;
13587 addrSI = gen_lowpart_common (SImode,
13588 force_reg (Pmode, XEXP (used_m, 0)));
13589 addrSI = force_reg (SImode, addrSI);
13590 shift = gen_reg_rtx (SImode);
13592 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
13593 GEN_INT (shift_mask)));
13594 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
13596 aligned_addr = expand_binop (Pmode, and_optab,
13597 XEXP (used_m, 0),
13598 GEN_INT (-4), NULL_RTX,
13599 1, OPTAB_LIB_WIDEN);
13600 used_m = change_address (used_m, SImode, aligned_addr);
13601 set_mem_align (used_m, 32);
13603 /* It's safe to keep the old alias set of USED_M, because
13604 the operation is atomic and only affects the original
13605 USED_M. */
13606 if (GET_CODE (m) == NOT)
13607 m = gen_rtx_NOT (SImode, used_m);
13608 else
13609 m = used_m;
13611 if (GET_CODE (op) == NOT)
13613 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
13614 oldop = gen_rtx_NOT (SImode, oldop);
13616 else
13617 oldop = lowpart_subreg (SImode, op, mode);
13619 switch (code)
13621 case IOR:
13622 case XOR:
13623 newop = expand_binop (SImode, and_optab,
13624 oldop, GEN_INT (imask), NULL_RTX,
13625 1, OPTAB_LIB_WIDEN);
13626 emit_insn (gen_ashlsi3 (newop, newop, shift));
13627 break;
13629 case AND:
13630 newop = expand_binop (SImode, ior_optab,
13631 oldop, GEN_INT (~imask), NULL_RTX,
13632 1, OPTAB_LIB_WIDEN);
13633 emit_insn (gen_rotlsi3 (newop, newop, shift));
13634 break;
13636 case PLUS:
13637 case MINUS:
13639 rtx mask;
13641 newop = expand_binop (SImode, and_optab,
13642 oldop, GEN_INT (imask), NULL_RTX,
13643 1, OPTAB_LIB_WIDEN);
13644 emit_insn (gen_ashlsi3 (newop, newop, shift));
13646 mask = gen_reg_rtx (SImode);
13647 emit_move_insn (mask, GEN_INT (imask));
13648 emit_insn (gen_ashlsi3 (mask, mask, shift));
13650 if (code == PLUS)
13651 newop = gen_rtx_PLUS (SImode, m, newop);
13652 else
13653 newop = gen_rtx_MINUS (SImode, m, newop);
13654 newop = gen_rtx_AND (SImode, newop, mask);
13655 newop = gen_rtx_IOR (SImode, newop,
13656 gen_rtx_AND (SImode,
13657 gen_rtx_NOT (SImode, mask),
13658 m));
13659 break;
13662 default:
13663 gcc_unreachable ();
13666 if (GET_CODE (m) == NOT)
13668 rtx mask, xorm;
13670 mask = gen_reg_rtx (SImode);
13671 emit_move_insn (mask, GEN_INT (imask));
13672 emit_insn (gen_ashlsi3 (mask, mask, shift));
13674 xorm = gen_rtx_XOR (SImode, used_m, mask);
13675 /* Depending on the value of 'op', the XOR or the operation might
13676 be able to be simplified away. */
13677 newop = simplify_gen_binary (code, SImode, xorm, newop);
13679 op = newop;
13680 used_mode = SImode;
13681 before = gen_reg_rtx (used_mode);
13682 after = gen_reg_rtx (used_mode);
13684 else
13686 used_mode = mode;
13687 before = before_param;
13688 after = after_param;
13690 if (before == NULL_RTX)
13691 before = gen_reg_rtx (used_mode);
13692 if (after == NULL_RTX)
13693 after = gen_reg_rtx (used_mode);
13696 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
13697 && used_mode != mode)
13698 the_op = op; /* Computed above. */
13699 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
13700 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
13701 else
13702 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
13704 set_after = gen_rtx_SET (VOIDmode, after, the_op);
13705 set_before = gen_rtx_SET (VOIDmode, before, used_m);
13706 set_atomic = gen_rtx_SET (VOIDmode, used_m,
13707 gen_rtx_UNSPEC (used_mode,
13708 gen_rtvec (1, the_op),
13709 UNSPEC_SYNC_OP));
13710 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
13712 if ((code == PLUS || code == MINUS) && used_mode != mode)
13713 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
13714 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
13715 else
13716 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
13717 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
13719 /* Shift and mask the return values properly. */
13720 if (used_mode != mode && before_param)
13722 emit_insn (gen_lshrsi3 (before, before, shift));
13723 convert_move (before_param, before, 1);
13726 if (used_mode != mode && after_param)
13728 emit_insn (gen_lshrsi3 (after, after, shift));
13729 convert_move (after_param, after, 1);
13732 /* The previous sequence will end with a branch that's dependent on
13733 the conditional store, so placing an isync will ensure that no
13734 other instructions (especially, no load or store instructions)
13735 can start before the atomic operation completes. */
13736 if (sync_p)
13737 emit_insn (gen_isync ());
13740 /* A subroutine of the atomic operation splitters. Jump to LABEL if
13741 COND is true. Mark the jump as unlikely to be taken. */
13743 static void
13744 emit_unlikely_jump (rtx cond, rtx label)
13746 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
13747 rtx x;
13749 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
13750 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
13751 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
13754 /* A subroutine of the atomic operation splitters. Emit a load-locked
13755 instruction in MODE. */
13757 static void
13758 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
13760 rtx (*fn) (rtx, rtx) = NULL;
13761 if (mode == SImode)
13762 fn = gen_load_locked_si;
13763 else if (mode == DImode)
13764 fn = gen_load_locked_di;
13765 emit_insn (fn (reg, mem));
13768 /* A subroutine of the atomic operation splitters. Emit a store-conditional
13769 instruction in MODE. */
13771 static void
13772 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
13774 rtx (*fn) (rtx, rtx, rtx) = NULL;
13775 if (mode == SImode)
13776 fn = gen_store_conditional_si;
13777 else if (mode == DImode)
13778 fn = gen_store_conditional_di;
13780 /* Emit sync before stwcx. to address PPC405 Erratum. */
13781 if (PPC405_ERRATUM77)
13782 emit_insn (gen_memory_barrier ());
13784 emit_insn (fn (res, mem, val));
13787 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
13788 to perform. MEM is the memory on which to operate. VAL is the second
13789 operand of the binary operator. BEFORE and AFTER are optional locations to
13790 return the value of MEM either before of after the operation. SCRATCH is
13791 a scratch register. */
13793 void
13794 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
13795 rtx before, rtx after, rtx scratch)
13797 enum machine_mode mode = GET_MODE (mem);
13798 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13800 emit_insn (gen_memory_barrier ());
13802 label = gen_label_rtx ();
13803 emit_label (label);
13804 label = gen_rtx_LABEL_REF (VOIDmode, label);
13806 if (before == NULL_RTX)
13807 before = scratch;
13808 emit_load_locked (mode, before, mem);
13810 if (code == NOT)
13811 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
13812 else if (code == AND)
13813 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
13814 else
13815 x = gen_rtx_fmt_ee (code, mode, before, val);
13817 if (after != NULL_RTX)
13818 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
13819 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
13821 emit_store_conditional (mode, cond, mem, scratch);
13823 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13824 emit_unlikely_jump (x, label);
13826 emit_insn (gen_isync ());
13829 /* Expand an atomic compare and swap operation. MEM is the memory on which
13830 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
13831 value to be stored. SCRATCH is a scratch GPR. */
13833 void
13834 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
13835 rtx scratch)
13837 enum machine_mode mode = GET_MODE (mem);
13838 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13840 emit_insn (gen_memory_barrier ());
13842 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13843 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13844 emit_label (XEXP (label1, 0));
13846 emit_load_locked (mode, retval, mem);
13848 x = gen_rtx_COMPARE (CCmode, retval, oldval);
13849 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
13851 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13852 emit_unlikely_jump (x, label2);
13854 emit_move_insn (scratch, newval);
13855 emit_store_conditional (mode, cond, mem, scratch);
13857 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13858 emit_unlikely_jump (x, label1);
13860 emit_insn (gen_isync ());
13861 emit_label (XEXP (label2, 0));
13864 /* Expand an atomic test and set operation. MEM is the memory on which
13865 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
13867 void
13868 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
13870 enum machine_mode mode = GET_MODE (mem);
13871 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13873 emit_insn (gen_memory_barrier ());
13875 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13876 emit_label (XEXP (label, 0));
13878 emit_load_locked (mode, retval, mem);
13879 emit_move_insn (scratch, val);
13880 emit_store_conditional (mode, cond, mem, scratch);
13882 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13883 emit_unlikely_jump (x, label);
13885 emit_insn (gen_isync ());
13888 void
13889 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
13891 enum machine_mode mode = GET_MODE (mem);
13892 rtx addrSI, align, wdst, shift, mask;
13893 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
13894 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
13896 /* Shift amount for subword relative to aligned word. */
13897 addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0)));
13898 shift = gen_reg_rtx (SImode);
13899 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
13900 GEN_INT (shift_mask)));
13901 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
13903 /* Shift and mask old value into position within word. */
13904 oldval = convert_modes (SImode, mode, oldval, 1);
13905 oldval = expand_binop (SImode, and_optab,
13906 oldval, GEN_INT (imask), NULL_RTX,
13907 1, OPTAB_LIB_WIDEN);
13908 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
13910 /* Shift and mask new value into position within word. */
13911 newval = convert_modes (SImode, mode, newval, 1);
13912 newval = expand_binop (SImode, and_optab,
13913 newval, GEN_INT (imask), NULL_RTX,
13914 1, OPTAB_LIB_WIDEN);
13915 emit_insn (gen_ashlsi3 (newval, newval, shift));
13917 /* Mask for insertion. */
13918 mask = gen_reg_rtx (SImode);
13919 emit_move_insn (mask, GEN_INT (imask));
13920 emit_insn (gen_ashlsi3 (mask, mask, shift));
13922 /* Address of aligned word containing subword. */
13923 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
13924 NULL_RTX, 1, OPTAB_LIB_WIDEN);
13925 mem = change_address (mem, SImode, align);
13926 set_mem_align (mem, 32);
13927 MEM_VOLATILE_P (mem) = 1;
13929 wdst = gen_reg_rtx (SImode);
13930 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
13931 oldval, newval, mem));
13933 /* Shift the result back. */
13934 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
13936 emit_move_insn (dst, gen_lowpart (mode, wdst));
13939 void
13940 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
13941 rtx oldval, rtx newval, rtx mem,
13942 rtx scratch)
13944 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13946 emit_insn (gen_memory_barrier ());
13947 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13948 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13949 emit_label (XEXP (label1, 0));
13951 emit_load_locked (SImode, scratch, mem);
13953 /* Mask subword within loaded value for comparison with oldval.
13954 Use UNSPEC_AND to avoid clobber.*/
13955 emit_insn (gen_rtx_SET (SImode, dest,
13956 gen_rtx_UNSPEC (SImode,
13957 gen_rtvec (2, scratch, mask),
13958 UNSPEC_AND)));
13960 x = gen_rtx_COMPARE (CCmode, dest, oldval);
13961 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
13963 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13964 emit_unlikely_jump (x, label2);
13966 /* Clear subword within loaded value for insertion of new value. */
13967 emit_insn (gen_rtx_SET (SImode, scratch,
13968 gen_rtx_AND (SImode,
13969 gen_rtx_NOT (SImode, mask), scratch)));
13970 emit_insn (gen_iorsi3 (scratch, scratch, newval));
13971 emit_store_conditional (SImode, cond, mem, scratch);
13973 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13974 emit_unlikely_jump (x, label1);
13976 emit_insn (gen_isync ());
13977 emit_label (XEXP (label2, 0));
13981 /* Emit instructions to move SRC to DST. Called by splitters for
13982 multi-register moves. It will emit at most one instruction for
13983 each register that is accessed; that is, it won't emit li/lis pairs
13984 (or equivalent for 64-bit code). One of SRC or DST must be a hard
13985 register. */
13987 void
13988 rs6000_split_multireg_move (rtx dst, rtx src)
13990 /* The register number of the first register being moved. */
13991 int reg;
13992 /* The mode that is to be moved. */
13993 enum machine_mode mode;
13994 /* The mode that the move is being done in, and its size. */
13995 enum machine_mode reg_mode;
13996 int reg_mode_size;
13997 /* The number of registers that will be moved. */
13998 int nregs;
14000 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
14001 mode = GET_MODE (dst);
14002 nregs = hard_regno_nregs[reg][mode];
14003 if (FP_REGNO_P (reg))
14004 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
14005 else if (ALTIVEC_REGNO_P (reg))
14006 reg_mode = V16QImode;
14007 else if (TARGET_E500_DOUBLE && (mode == TFmode || mode == TDmode))
14008 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
14009 else
14010 reg_mode = word_mode;
14011 reg_mode_size = GET_MODE_SIZE (reg_mode);
14013 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
14015 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
14017 /* Move register range backwards, if we might have destructive
14018 overlap. */
14019 int i;
14020 for (i = nregs - 1; i >= 0; i--)
14021 emit_insn (gen_rtx_SET (VOIDmode,
14022 simplify_gen_subreg (reg_mode, dst, mode,
14023 i * reg_mode_size),
14024 simplify_gen_subreg (reg_mode, src, mode,
14025 i * reg_mode_size)));
14027 else
14029 int i;
14030 int j = -1;
14031 bool used_update = false;
14033 if (MEM_P (src) && INT_REGNO_P (reg))
14035 rtx breg;
14037 if (GET_CODE (XEXP (src, 0)) == PRE_INC
14038 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
14040 rtx delta_rtx;
14041 breg = XEXP (XEXP (src, 0), 0);
14042 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
14043 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
14044 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
14045 emit_insn (TARGET_32BIT
14046 ? gen_addsi3 (breg, breg, delta_rtx)
14047 : gen_adddi3 (breg, breg, delta_rtx));
14048 src = replace_equiv_address (src, breg);
14050 else if (! rs6000_offsettable_memref_p (src))
14052 rtx basereg;
14053 basereg = gen_rtx_REG (Pmode, reg);
14054 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
14055 src = replace_equiv_address (src, basereg);
14058 breg = XEXP (src, 0);
14059 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
14060 breg = XEXP (breg, 0);
14062 /* If the base register we are using to address memory is
14063 also a destination reg, then change that register last. */
14064 if (REG_P (breg)
14065 && REGNO (breg) >= REGNO (dst)
14066 && REGNO (breg) < REGNO (dst) + nregs)
14067 j = REGNO (breg) - REGNO (dst);
14070 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
14072 rtx breg;
14074 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
14075 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
14077 rtx delta_rtx;
14078 breg = XEXP (XEXP (dst, 0), 0);
14079 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
14080 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
14081 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
14083 /* We have to update the breg before doing the store.
14084 Use store with update, if available. */
14086 if (TARGET_UPDATE)
14088 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
14089 emit_insn (TARGET_32BIT
14090 ? (TARGET_POWERPC64
14091 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
14092 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
14093 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
14094 used_update = true;
14096 else
14097 emit_insn (TARGET_32BIT
14098 ? gen_addsi3 (breg, breg, delta_rtx)
14099 : gen_adddi3 (breg, breg, delta_rtx));
14100 dst = replace_equiv_address (dst, breg);
14102 else
14103 gcc_assert (rs6000_offsettable_memref_p (dst));
14106 for (i = 0; i < nregs; i++)
14108 /* Calculate index to next subword. */
14109 ++j;
14110 if (j == nregs)
14111 j = 0;
14113 /* If compiler already emitted move of first word by
14114 store with update, no need to do anything. */
14115 if (j == 0 && used_update)
14116 continue;
14118 emit_insn (gen_rtx_SET (VOIDmode,
14119 simplify_gen_subreg (reg_mode, dst, mode,
14120 j * reg_mode_size),
14121 simplify_gen_subreg (reg_mode, src, mode,
14122 j * reg_mode_size)));
14128 /* This page contains routines that are used to determine what the
14129 function prologue and epilogue code will do and write them out. */
14131 /* Return the first fixed-point register that is required to be
14132 saved. 32 if none. */
14135 first_reg_to_save (void)
14137 int first_reg;
14139 /* Find lowest numbered live register. */
14140 for (first_reg = 13; first_reg <= 31; first_reg++)
14141 if (df_regs_ever_live_p (first_reg)
14142 && (! call_used_regs[first_reg]
14143 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
14144 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14145 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
14146 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
14147 break;
14149 #if TARGET_MACHO
14150 if (flag_pic
14151 && crtl->uses_pic_offset_table
14152 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
14153 return RS6000_PIC_OFFSET_TABLE_REGNUM;
14154 #endif
14156 return first_reg;
14159 /* Similar, for FP regs. */
14162 first_fp_reg_to_save (void)
14164 int first_reg;
14166 /* Find lowest numbered live register. */
14167 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
14168 if (df_regs_ever_live_p (first_reg))
14169 break;
14171 return first_reg;
14174 /* Similar, for AltiVec regs. */
14176 static int
14177 first_altivec_reg_to_save (void)
14179 int i;
14181 /* Stack frame remains as is unless we are in AltiVec ABI. */
14182 if (! TARGET_ALTIVEC_ABI)
14183 return LAST_ALTIVEC_REGNO + 1;
14185 /* On Darwin, the unwind routines are compiled without
14186 TARGET_ALTIVEC, and use save_world to save/restore the
14187 altivec registers when necessary. */
14188 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
14189 && ! TARGET_ALTIVEC)
14190 return FIRST_ALTIVEC_REGNO + 20;
14192 /* Find lowest numbered live register. */
14193 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
14194 if (df_regs_ever_live_p (i))
14195 break;
14197 return i;
14200 /* Return a 32-bit mask of the AltiVec registers we need to set in
14201 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
14202 the 32-bit word is 0. */
14204 static unsigned int
14205 compute_vrsave_mask (void)
14207 unsigned int i, mask = 0;
14209 /* On Darwin, the unwind routines are compiled without
14210 TARGET_ALTIVEC, and use save_world to save/restore the
14211 call-saved altivec registers when necessary. */
14212 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
14213 && ! TARGET_ALTIVEC)
14214 mask |= 0xFFF;
14216 /* First, find out if we use _any_ altivec registers. */
14217 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
14218 if (df_regs_ever_live_p (i))
14219 mask |= ALTIVEC_REG_BIT (i);
14221 if (mask == 0)
14222 return mask;
14224 /* Next, remove the argument registers from the set. These must
14225 be in the VRSAVE mask set by the caller, so we don't need to add
14226 them in again. More importantly, the mask we compute here is
14227 used to generate CLOBBERs in the set_vrsave insn, and we do not
14228 wish the argument registers to die. */
14229 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
14230 mask &= ~ALTIVEC_REG_BIT (i);
14232 /* Similarly, remove the return value from the set. */
14234 bool yes = false;
14235 diddle_return_value (is_altivec_return_reg, &yes);
14236 if (yes)
14237 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
14240 return mask;
14243 /* For a very restricted set of circumstances, we can cut down the
14244 size of prologues/epilogues by calling our own save/restore-the-world
14245 routines. */
14247 static void
14248 compute_save_world_info (rs6000_stack_t *info_ptr)
14250 info_ptr->world_save_p = 1;
14251 info_ptr->world_save_p
14252 = (WORLD_SAVE_P (info_ptr)
14253 && DEFAULT_ABI == ABI_DARWIN
14254 && ! (cfun->calls_setjmp && flag_exceptions)
14255 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
14256 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
14257 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
14258 && info_ptr->cr_save_p);
14260 /* This will not work in conjunction with sibcalls. Make sure there
14261 are none. (This check is expensive, but seldom executed.) */
14262 if (WORLD_SAVE_P (info_ptr))
14264 rtx insn;
14265 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
14266 if ( GET_CODE (insn) == CALL_INSN
14267 && SIBLING_CALL_P (insn))
14269 info_ptr->world_save_p = 0;
14270 break;
14274 if (WORLD_SAVE_P (info_ptr))
14276 /* Even if we're not touching VRsave, make sure there's room on the
14277 stack for it, if it looks like we're calling SAVE_WORLD, which
14278 will attempt to save it. */
14279 info_ptr->vrsave_size = 4;
14281 /* If we are going to save the world, we need to save the link register too. */
14282 info_ptr->lr_save_p = 1;
14284 /* "Save" the VRsave register too if we're saving the world. */
14285 if (info_ptr->vrsave_mask == 0)
14286 info_ptr->vrsave_mask = compute_vrsave_mask ();
14288 /* Because the Darwin register save/restore routines only handle
14289 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
14290 check. */
14291 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
14292 && (info_ptr->first_altivec_reg_save
14293 >= FIRST_SAVED_ALTIVEC_REGNO));
14295 return;
14299 static void
14300 is_altivec_return_reg (rtx reg, void *xyes)
14302 bool *yes = (bool *) xyes;
14303 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
14304 *yes = true;
14308 /* Calculate the stack information for the current function. This is
14309 complicated by having two separate calling sequences, the AIX calling
14310 sequence and the V.4 calling sequence.
14312 AIX (and Darwin/Mac OS X) stack frames look like:
14313 32-bit 64-bit
14314 SP----> +---------------------------------------+
14315 | back chain to caller | 0 0
14316 +---------------------------------------+
14317 | saved CR | 4 8 (8-11)
14318 +---------------------------------------+
14319 | saved LR | 8 16
14320 +---------------------------------------+
14321 | reserved for compilers | 12 24
14322 +---------------------------------------+
14323 | reserved for binders | 16 32
14324 +---------------------------------------+
14325 | saved TOC pointer | 20 40
14326 +---------------------------------------+
14327 | Parameter save area (P) | 24 48
14328 +---------------------------------------+
14329 | Alloca space (A) | 24+P etc.
14330 +---------------------------------------+
14331 | Local variable space (L) | 24+P+A
14332 +---------------------------------------+
14333 | Float/int conversion temporary (X) | 24+P+A+L
14334 +---------------------------------------+
14335 | Save area for AltiVec registers (W) | 24+P+A+L+X
14336 +---------------------------------------+
14337 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
14338 +---------------------------------------+
14339 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
14340 +---------------------------------------+
14341 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
14342 +---------------------------------------+
14343 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
14344 +---------------------------------------+
14345 old SP->| back chain to caller's caller |
14346 +---------------------------------------+
14348 The required alignment for AIX configurations is two words (i.e., 8
14349 or 16 bytes).
14352 V.4 stack frames look like:
14354 SP----> +---------------------------------------+
14355 | back chain to caller | 0
14356 +---------------------------------------+
14357 | caller's saved LR | 4
14358 +---------------------------------------+
14359 | Parameter save area (P) | 8
14360 +---------------------------------------+
14361 | Alloca space (A) | 8+P
14362 +---------------------------------------+
14363 | Varargs save area (V) | 8+P+A
14364 +---------------------------------------+
14365 | Local variable space (L) | 8+P+A+V
14366 +---------------------------------------+
14367 | Float/int conversion temporary (X) | 8+P+A+V+L
14368 +---------------------------------------+
14369 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
14370 +---------------------------------------+
14371 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
14372 +---------------------------------------+
14373 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
14374 +---------------------------------------+
14375 | SPE: area for 64-bit GP registers |
14376 +---------------------------------------+
14377 | SPE alignment padding |
14378 +---------------------------------------+
14379 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
14380 +---------------------------------------+
14381 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
14382 +---------------------------------------+
14383 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
14384 +---------------------------------------+
14385 old SP->| back chain to caller's caller |
14386 +---------------------------------------+
14388 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
14389 given. (But note below and in sysv4.h that we require only 8 and
14390 may round up the size of our stack frame anyways. The historical
14391 reason is early versions of powerpc-linux which didn't properly
14392 align the stack at program startup. A happy side-effect is that
14393 -mno-eabi libraries can be used with -meabi programs.)
14395 The EABI configuration defaults to the V.4 layout. However,
14396 the stack alignment requirements may differ. If -mno-eabi is not
14397 given, the required stack alignment is 8 bytes; if -mno-eabi is
14398 given, the required alignment is 16 bytes. (But see V.4 comment
14399 above.) */
14401 #ifndef ABI_STACK_BOUNDARY
14402 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
14403 #endif
14405 static rs6000_stack_t *
14406 rs6000_stack_info (void)
14408 static rs6000_stack_t info;
14409 rs6000_stack_t *info_ptr = &info;
14410 int reg_size = TARGET_32BIT ? 4 : 8;
14411 int ehrd_size;
14412 int save_align;
14413 int first_gp;
14414 HOST_WIDE_INT non_fixed_size;
14416 memset (&info, 0, sizeof (info));
14418 if (TARGET_SPE)
14420 /* Cache value so we don't rescan instruction chain over and over. */
14421 if (cfun->machine->insn_chain_scanned_p == 0)
14422 cfun->machine->insn_chain_scanned_p
14423 = spe_func_has_64bit_regs_p () + 1;
14424 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
14427 /* Select which calling sequence. */
14428 info_ptr->abi = DEFAULT_ABI;
14430 /* Calculate which registers need to be saved & save area size. */
14431 info_ptr->first_gp_reg_save = first_reg_to_save ();
14432 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
14433 even if it currently looks like we won't. Reload may need it to
14434 get at a constant; if so, it will have already created a constant
14435 pool entry for it. */
14436 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
14437 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
14438 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
14439 && crtl->uses_const_pool
14440 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
14441 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
14442 else
14443 first_gp = info_ptr->first_gp_reg_save;
14445 info_ptr->gp_size = reg_size * (32 - first_gp);
14447 /* For the SPE, we have an additional upper 32-bits on each GPR.
14448 Ideally we should save the entire 64-bits only when the upper
14449 half is used in SIMD instructions. Since we only record
14450 registers live (not the size they are used in), this proves
14451 difficult because we'd have to traverse the instruction chain at
14452 the right time, taking reload into account. This is a real pain,
14453 so we opt to save the GPRs in 64-bits always if but one register
14454 gets used in 64-bits. Otherwise, all the registers in the frame
14455 get saved in 32-bits.
14457 So... since when we save all GPRs (except the SP) in 64-bits, the
14458 traditional GP save area will be empty. */
14459 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
14460 info_ptr->gp_size = 0;
14462 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
14463 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
14465 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
14466 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
14467 - info_ptr->first_altivec_reg_save);
14469 /* Does this function call anything? */
14470 info_ptr->calls_p = (! current_function_is_leaf
14471 || cfun->machine->ra_needs_full_frame);
14473 /* Determine if we need to save the link register. */
14474 if ((DEFAULT_ABI == ABI_AIX
14475 && crtl->profile
14476 && !TARGET_PROFILE_KERNEL)
14477 #ifdef TARGET_RELOCATABLE
14478 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
14479 #endif
14480 || (info_ptr->first_fp_reg_save != 64
14481 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
14482 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
14483 || info_ptr->calls_p
14484 || rs6000_ra_ever_killed ())
14486 info_ptr->lr_save_p = 1;
14487 df_set_regs_ever_live (LR_REGNO, true);
14490 /* Determine if we need to save the condition code registers. */
14491 if (df_regs_ever_live_p (CR2_REGNO)
14492 || df_regs_ever_live_p (CR3_REGNO)
14493 || df_regs_ever_live_p (CR4_REGNO))
14495 info_ptr->cr_save_p = 1;
14496 if (DEFAULT_ABI == ABI_V4)
14497 info_ptr->cr_size = reg_size;
14500 /* If the current function calls __builtin_eh_return, then we need
14501 to allocate stack space for registers that will hold data for
14502 the exception handler. */
14503 if (crtl->calls_eh_return)
14505 unsigned int i;
14506 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
14507 continue;
14509 /* SPE saves EH registers in 64-bits. */
14510 ehrd_size = i * (TARGET_SPE_ABI
14511 && info_ptr->spe_64bit_regs_used != 0
14512 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
14514 else
14515 ehrd_size = 0;
14517 /* Determine various sizes. */
14518 info_ptr->reg_size = reg_size;
14519 info_ptr->fixed_size = RS6000_SAVE_AREA;
14520 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
14521 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
14522 TARGET_ALTIVEC ? 16 : 8);
14523 if (FRAME_GROWS_DOWNWARD)
14524 info_ptr->vars_size
14525 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
14526 + info_ptr->parm_size,
14527 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
14528 - (info_ptr->fixed_size + info_ptr->vars_size
14529 + info_ptr->parm_size);
14531 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
14532 info_ptr->spe_gp_size = 8 * (32 - first_gp);
14533 else
14534 info_ptr->spe_gp_size = 0;
14536 if (TARGET_ALTIVEC_ABI)
14537 info_ptr->vrsave_mask = compute_vrsave_mask ();
14538 else
14539 info_ptr->vrsave_mask = 0;
14541 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
14542 info_ptr->vrsave_size = 4;
14543 else
14544 info_ptr->vrsave_size = 0;
14546 compute_save_world_info (info_ptr);
14548 /* Calculate the offsets. */
14549 switch (DEFAULT_ABI)
14551 case ABI_NONE:
14552 default:
14553 gcc_unreachable ();
14555 case ABI_AIX:
14556 case ABI_DARWIN:
14557 info_ptr->fp_save_offset = - info_ptr->fp_size;
14558 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
14560 if (TARGET_ALTIVEC_ABI)
14562 info_ptr->vrsave_save_offset
14563 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
14565 /* Align stack so vector save area is on a quadword boundary.
14566 The padding goes above the vectors. */
14567 if (info_ptr->altivec_size != 0)
14568 info_ptr->altivec_padding_size
14569 = info_ptr->vrsave_save_offset & 0xF;
14570 else
14571 info_ptr->altivec_padding_size = 0;
14573 info_ptr->altivec_save_offset
14574 = info_ptr->vrsave_save_offset
14575 - info_ptr->altivec_padding_size
14576 - info_ptr->altivec_size;
14577 gcc_assert (info_ptr->altivec_size == 0
14578 || info_ptr->altivec_save_offset % 16 == 0);
14580 /* Adjust for AltiVec case. */
14581 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
14583 else
14584 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
14585 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
14586 info_ptr->lr_save_offset = 2*reg_size;
14587 break;
14589 case ABI_V4:
14590 info_ptr->fp_save_offset = - info_ptr->fp_size;
14591 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
14592 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
14594 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
14596 /* Align stack so SPE GPR save area is aligned on a
14597 double-word boundary. */
14598 if (info_ptr->spe_gp_size != 0)
14599 info_ptr->spe_padding_size
14600 = 8 - (-info_ptr->cr_save_offset % 8);
14601 else
14602 info_ptr->spe_padding_size = 0;
14604 info_ptr->spe_gp_save_offset
14605 = info_ptr->cr_save_offset
14606 - info_ptr->spe_padding_size
14607 - info_ptr->spe_gp_size;
14609 /* Adjust for SPE case. */
14610 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
14612 else if (TARGET_ALTIVEC_ABI)
14614 info_ptr->vrsave_save_offset
14615 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
14617 /* Align stack so vector save area is on a quadword boundary. */
14618 if (info_ptr->altivec_size != 0)
14619 info_ptr->altivec_padding_size
14620 = 16 - (-info_ptr->vrsave_save_offset % 16);
14621 else
14622 info_ptr->altivec_padding_size = 0;
14624 info_ptr->altivec_save_offset
14625 = info_ptr->vrsave_save_offset
14626 - info_ptr->altivec_padding_size
14627 - info_ptr->altivec_size;
14629 /* Adjust for AltiVec case. */
14630 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
14632 else
14633 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
14634 info_ptr->ehrd_offset -= ehrd_size;
14635 info_ptr->lr_save_offset = reg_size;
14636 break;
14639 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
14640 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
14641 + info_ptr->gp_size
14642 + info_ptr->altivec_size
14643 + info_ptr->altivec_padding_size
14644 + info_ptr->spe_gp_size
14645 + info_ptr->spe_padding_size
14646 + ehrd_size
14647 + info_ptr->cr_size
14648 + info_ptr->vrsave_size,
14649 save_align);
14651 non_fixed_size = (info_ptr->vars_size
14652 + info_ptr->parm_size
14653 + info_ptr->save_size);
14655 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
14656 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
14658 /* Determine if we need to allocate any stack frame:
14660 For AIX we need to push the stack if a frame pointer is needed
14661 (because the stack might be dynamically adjusted), if we are
14662 debugging, if we make calls, or if the sum of fp_save, gp_save,
14663 and local variables are more than the space needed to save all
14664 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
14665 + 18*8 = 288 (GPR13 reserved).
14667 For V.4 we don't have the stack cushion that AIX uses, but assume
14668 that the debugger can handle stackless frames. */
14670 if (info_ptr->calls_p)
14671 info_ptr->push_p = 1;
14673 else if (DEFAULT_ABI == ABI_V4)
14674 info_ptr->push_p = non_fixed_size != 0;
14676 else if (frame_pointer_needed)
14677 info_ptr->push_p = 1;
14679 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
14680 info_ptr->push_p = 1;
14682 else
14683 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
14685 /* Zero offsets if we're not saving those registers. */
14686 if (info_ptr->fp_size == 0)
14687 info_ptr->fp_save_offset = 0;
14689 if (info_ptr->gp_size == 0)
14690 info_ptr->gp_save_offset = 0;
14692 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
14693 info_ptr->altivec_save_offset = 0;
14695 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
14696 info_ptr->vrsave_save_offset = 0;
14698 if (! TARGET_SPE_ABI
14699 || info_ptr->spe_64bit_regs_used == 0
14700 || info_ptr->spe_gp_size == 0)
14701 info_ptr->spe_gp_save_offset = 0;
14703 if (! info_ptr->lr_save_p)
14704 info_ptr->lr_save_offset = 0;
14706 if (! info_ptr->cr_save_p)
14707 info_ptr->cr_save_offset = 0;
14709 return info_ptr;
14712 /* Return true if the current function uses any GPRs in 64-bit SIMD
14713 mode. */
14715 static bool
14716 spe_func_has_64bit_regs_p (void)
14718 rtx insns, insn;
14720 /* Functions that save and restore all the call-saved registers will
14721 need to save/restore the registers in 64-bits. */
14722 if (crtl->calls_eh_return
14723 || cfun->calls_setjmp
14724 || crtl->has_nonlocal_goto)
14725 return true;
14727 insns = get_insns ();
14729 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
14731 if (INSN_P (insn))
14733 rtx i;
14735 /* FIXME: This should be implemented with attributes...
14737 (set_attr "spe64" "true")....then,
14738 if (get_spe64(insn)) return true;
14740 It's the only reliable way to do the stuff below. */
14742 i = PATTERN (insn);
14743 if (GET_CODE (i) == SET)
14745 enum machine_mode mode = GET_MODE (SET_SRC (i));
14747 if (SPE_VECTOR_MODE (mode))
14748 return true;
14749 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
14750 || mode == DDmode || mode == TDmode))
14751 return true;
14756 return false;
14759 static void
14760 debug_stack_info (rs6000_stack_t *info)
14762 const char *abi_string;
14764 if (! info)
14765 info = rs6000_stack_info ();
14767 fprintf (stderr, "\nStack information for function %s:\n",
14768 ((current_function_decl && DECL_NAME (current_function_decl))
14769 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
14770 : "<unknown>"));
14772 switch (info->abi)
14774 default: abi_string = "Unknown"; break;
14775 case ABI_NONE: abi_string = "NONE"; break;
14776 case ABI_AIX: abi_string = "AIX"; break;
14777 case ABI_DARWIN: abi_string = "Darwin"; break;
14778 case ABI_V4: abi_string = "V.4"; break;
14781 fprintf (stderr, "\tABI = %5s\n", abi_string);
14783 if (TARGET_ALTIVEC_ABI)
14784 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
14786 if (TARGET_SPE_ABI)
14787 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
14789 if (info->first_gp_reg_save != 32)
14790 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
14792 if (info->first_fp_reg_save != 64)
14793 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
14795 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
14796 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
14797 info->first_altivec_reg_save);
14799 if (info->lr_save_p)
14800 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
14802 if (info->cr_save_p)
14803 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
14805 if (info->vrsave_mask)
14806 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
14808 if (info->push_p)
14809 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
14811 if (info->calls_p)
14812 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
14814 if (info->gp_save_offset)
14815 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
14817 if (info->fp_save_offset)
14818 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
14820 if (info->altivec_save_offset)
14821 fprintf (stderr, "\taltivec_save_offset = %5d\n",
14822 info->altivec_save_offset);
14824 if (info->spe_gp_save_offset)
14825 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
14826 info->spe_gp_save_offset);
14828 if (info->vrsave_save_offset)
14829 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
14830 info->vrsave_save_offset);
14832 if (info->lr_save_offset)
14833 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
14835 if (info->cr_save_offset)
14836 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
14838 if (info->varargs_save_offset)
14839 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
14841 if (info->total_size)
14842 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
14843 info->total_size);
14845 if (info->vars_size)
14846 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
14847 info->vars_size);
14849 if (info->parm_size)
14850 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
14852 if (info->fixed_size)
14853 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
14855 if (info->gp_size)
14856 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
14858 if (info->spe_gp_size)
14859 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
14861 if (info->fp_size)
14862 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
14864 if (info->altivec_size)
14865 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
14867 if (info->vrsave_size)
14868 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
14870 if (info->altivec_padding_size)
14871 fprintf (stderr, "\taltivec_padding_size= %5d\n",
14872 info->altivec_padding_size);
14874 if (info->spe_padding_size)
14875 fprintf (stderr, "\tspe_padding_size = %5d\n",
14876 info->spe_padding_size);
14878 if (info->cr_size)
14879 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
14881 if (info->save_size)
14882 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
14884 if (info->reg_size != 4)
14885 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
14887 fprintf (stderr, "\n");
14891 rs6000_return_addr (int count, rtx frame)
14893 /* Currently we don't optimize very well between prolog and body
14894 code and for PIC code the code can be actually quite bad, so
14895 don't try to be too clever here. */
14896 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
14898 cfun->machine->ra_needs_full_frame = 1;
14900 return
14901 gen_rtx_MEM
14902 (Pmode,
14903 memory_address
14904 (Pmode,
14905 plus_constant (copy_to_reg
14906 (gen_rtx_MEM (Pmode,
14907 memory_address (Pmode, frame))),
14908 RETURN_ADDRESS_OFFSET)));
14911 cfun->machine->ra_need_lr = 1;
14912 return get_hard_reg_initial_val (Pmode, LR_REGNO);
14915 /* Say whether a function is a candidate for sibcall handling or not.
14916 We do not allow indirect calls to be optimized into sibling calls.
14917 Also, we can't do it if there are any vector parameters; there's
14918 nowhere to put the VRsave code so it works; note that functions with
14919 vector parameters are required to have a prototype, so the argument
14920 type info must be available here. (The tail recursion case can work
14921 with vector parameters, but there's no way to distinguish here.) */
14922 static bool
14923 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
14925 tree type;
14926 if (decl)
14928 if (TARGET_ALTIVEC_VRSAVE)
14930 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
14931 type; type = TREE_CHAIN (type))
14933 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
14934 return false;
14937 if (DEFAULT_ABI == ABI_DARWIN
14938 || ((*targetm.binds_local_p) (decl)
14939 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
14941 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
14943 if (!lookup_attribute ("longcall", attr_list)
14944 || lookup_attribute ("shortcall", attr_list))
14945 return true;
14948 return false;
14951 /* NULL if INSN insn is valid within a low-overhead loop.
14952 Otherwise return why doloop cannot be applied.
14953 PowerPC uses the COUNT register for branch on table instructions. */
14955 static const char *
14956 rs6000_invalid_within_doloop (const_rtx insn)
14958 if (CALL_P (insn))
14959 return "Function call in the loop.";
14961 if (JUMP_P (insn)
14962 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
14963 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
14964 return "Computed branch in the loop.";
14966 return NULL;
14969 static int
14970 rs6000_ra_ever_killed (void)
14972 rtx top;
14973 rtx reg;
14974 rtx insn;
14976 if (crtl->is_thunk)
14977 return 0;
14979 /* regs_ever_live has LR marked as used if any sibcalls are present,
14980 but this should not force saving and restoring in the
14981 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
14982 clobbers LR, so that is inappropriate. */
14984 /* Also, the prologue can generate a store into LR that
14985 doesn't really count, like this:
14987 move LR->R0
14988 bcl to set PIC register
14989 move LR->R31
14990 move R0->LR
14992 When we're called from the epilogue, we need to avoid counting
14993 this as a store. */
14995 push_topmost_sequence ();
14996 top = get_insns ();
14997 pop_topmost_sequence ();
14998 reg = gen_rtx_REG (Pmode, LR_REGNO);
15000 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
15002 if (INSN_P (insn))
15004 if (CALL_P (insn))
15006 if (!SIBLING_CALL_P (insn))
15007 return 1;
15009 else if (find_regno_note (insn, REG_INC, LR_REGNO))
15010 return 1;
15011 else if (set_of (reg, insn) != NULL_RTX
15012 && !prologue_epilogue_contains (insn))
15013 return 1;
15016 return 0;
15019 /* Emit instructions needed to load the TOC register.
15020 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
15021 a constant pool; or for SVR4 -fpic. */
15023 void
15024 rs6000_emit_load_toc_table (int fromprolog)
15026 rtx dest;
15027 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
15029 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
15031 char buf[30];
15032 rtx lab, tmp1, tmp2, got;
15034 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
15035 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
15036 if (flag_pic == 2)
15037 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
15038 else
15039 got = rs6000_got_sym ();
15040 tmp1 = tmp2 = dest;
15041 if (!fromprolog)
15043 tmp1 = gen_reg_rtx (Pmode);
15044 tmp2 = gen_reg_rtx (Pmode);
15046 emit_insn (gen_load_toc_v4_PIC_1 (lab));
15047 emit_move_insn (tmp1,
15048 gen_rtx_REG (Pmode, LR_REGNO));
15049 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
15050 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
15052 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
15054 emit_insn (gen_load_toc_v4_pic_si ());
15055 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
15057 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
15059 char buf[30];
15060 rtx temp0 = (fromprolog
15061 ? gen_rtx_REG (Pmode, 0)
15062 : gen_reg_rtx (Pmode));
15064 if (fromprolog)
15066 rtx symF, symL;
15068 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
15069 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
15071 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
15072 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
15074 emit_insn (gen_load_toc_v4_PIC_1 (symF));
15075 emit_move_insn (dest,
15076 gen_rtx_REG (Pmode, LR_REGNO));
15077 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
15079 else
15081 rtx tocsym;
15083 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
15084 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
15085 emit_move_insn (dest,
15086 gen_rtx_REG (Pmode, LR_REGNO));
15087 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
15089 emit_insn (gen_addsi3 (dest, temp0, dest));
15091 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
15093 /* This is for AIX code running in non-PIC ELF32. */
15094 char buf[30];
15095 rtx realsym;
15096 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
15097 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
15099 emit_insn (gen_elf_high (dest, realsym));
15100 emit_insn (gen_elf_low (dest, dest, realsym));
15102 else
15104 gcc_assert (DEFAULT_ABI == ABI_AIX);
15106 if (TARGET_32BIT)
15107 emit_insn (gen_load_toc_aix_si (dest));
15108 else
15109 emit_insn (gen_load_toc_aix_di (dest));
15113 /* Emit instructions to restore the link register after determining where
15114 its value has been stored. */
15116 void
15117 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
15119 rs6000_stack_t *info = rs6000_stack_info ();
15120 rtx operands[2];
15122 operands[0] = source;
15123 operands[1] = scratch;
15125 if (info->lr_save_p)
15127 rtx frame_rtx = stack_pointer_rtx;
15128 HOST_WIDE_INT sp_offset = 0;
15129 rtx tmp;
15131 if (frame_pointer_needed
15132 || cfun->calls_alloca
15133 || info->total_size > 32767)
15135 tmp = gen_frame_mem (Pmode, frame_rtx);
15136 emit_move_insn (operands[1], tmp);
15137 frame_rtx = operands[1];
15139 else if (info->push_p)
15140 sp_offset = info->total_size;
15142 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
15143 tmp = gen_frame_mem (Pmode, tmp);
15144 emit_move_insn (tmp, operands[0]);
15146 else
15147 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
15150 static GTY(()) alias_set_type set = -1;
15152 alias_set_type
15153 get_TOC_alias_set (void)
15155 if (set == -1)
15156 set = new_alias_set ();
15157 return set;
15160 /* This returns nonzero if the current function uses the TOC. This is
15161 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
15162 is generated by the ABI_V4 load_toc_* patterns. */
15163 #if TARGET_ELF
15164 static int
15165 uses_TOC (void)
15167 rtx insn;
15169 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
15170 if (INSN_P (insn))
15172 rtx pat = PATTERN (insn);
15173 int i;
15175 if (GET_CODE (pat) == PARALLEL)
15176 for (i = 0; i < XVECLEN (pat, 0); i++)
15178 rtx sub = XVECEXP (pat, 0, i);
15179 if (GET_CODE (sub) == USE)
15181 sub = XEXP (sub, 0);
15182 if (GET_CODE (sub) == UNSPEC
15183 && XINT (sub, 1) == UNSPEC_TOC)
15184 return 1;
15188 return 0;
15190 #endif
15193 create_TOC_reference (rtx symbol)
15195 if (!can_create_pseudo_p ())
15196 df_set_regs_ever_live (TOC_REGISTER, true);
15197 return gen_rtx_PLUS (Pmode,
15198 gen_rtx_REG (Pmode, TOC_REGISTER),
15199 gen_rtx_CONST (Pmode,
15200 gen_rtx_MINUS (Pmode, symbol,
15201 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
15204 /* If _Unwind_* has been called from within the same module,
15205 toc register is not guaranteed to be saved to 40(1) on function
15206 entry. Save it there in that case. */
15208 void
15209 rs6000_aix_emit_builtin_unwind_init (void)
15211 rtx mem;
15212 rtx stack_top = gen_reg_rtx (Pmode);
15213 rtx opcode_addr = gen_reg_rtx (Pmode);
15214 rtx opcode = gen_reg_rtx (SImode);
15215 rtx tocompare = gen_reg_rtx (SImode);
15216 rtx no_toc_save_needed = gen_label_rtx ();
15218 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
15219 emit_move_insn (stack_top, mem);
15221 mem = gen_frame_mem (Pmode,
15222 gen_rtx_PLUS (Pmode, stack_top,
15223 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
15224 emit_move_insn (opcode_addr, mem);
15225 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
15226 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
15227 : 0xE8410028, SImode));
15229 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
15230 SImode, NULL_RTX, NULL_RTX,
15231 no_toc_save_needed);
15233 mem = gen_frame_mem (Pmode,
15234 gen_rtx_PLUS (Pmode, stack_top,
15235 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
15236 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
15237 emit_label (no_toc_save_needed);
15240 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
15241 and the change to the stack pointer. */
15243 static void
15244 rs6000_emit_stack_tie (void)
15246 rtx mem = gen_frame_mem (BLKmode,
15247 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
15249 emit_insn (gen_stack_tie (mem));
15252 /* Emit the correct code for allocating stack space, as insns.
15253 If COPY_R12, make sure a copy of the old frame is left in r12.
15254 The generated code may use hard register 0 as a temporary. */
15256 static void
15257 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
15259 rtx insn;
15260 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
15261 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
15262 rtx todec = gen_int_mode (-size, Pmode);
15264 if (INTVAL (todec) != -size)
15266 warning (0, "stack frame too large");
15267 emit_insn (gen_trap ());
15268 return;
15271 if (crtl->limit_stack)
15273 if (REG_P (stack_limit_rtx)
15274 && REGNO (stack_limit_rtx) > 1
15275 && REGNO (stack_limit_rtx) <= 31)
15277 emit_insn (TARGET_32BIT
15278 ? gen_addsi3 (tmp_reg,
15279 stack_limit_rtx,
15280 GEN_INT (size))
15281 : gen_adddi3 (tmp_reg,
15282 stack_limit_rtx,
15283 GEN_INT (size)));
15285 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
15286 const0_rtx));
15288 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
15289 && TARGET_32BIT
15290 && DEFAULT_ABI == ABI_V4)
15292 rtx toload = gen_rtx_CONST (VOIDmode,
15293 gen_rtx_PLUS (Pmode,
15294 stack_limit_rtx,
15295 GEN_INT (size)));
15297 emit_insn (gen_elf_high (tmp_reg, toload));
15298 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
15299 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
15300 const0_rtx));
15302 else
15303 warning (0, "stack limit expression is not supported");
15306 if (copy_r12 || ! TARGET_UPDATE)
15307 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
15309 if (TARGET_UPDATE)
15311 if (size > 32767)
15313 /* Need a note here so that try_split doesn't get confused. */
15314 if (get_last_insn () == NULL_RTX)
15315 emit_note (NOTE_INSN_DELETED);
15316 insn = emit_move_insn (tmp_reg, todec);
15317 try_split (PATTERN (insn), insn, 0);
15318 todec = tmp_reg;
15321 insn = emit_insn (TARGET_32BIT
15322 ? gen_movsi_update (stack_reg, stack_reg,
15323 todec, stack_reg)
15324 : gen_movdi_di_update (stack_reg, stack_reg,
15325 todec, stack_reg));
15327 else
15329 insn = emit_insn (TARGET_32BIT
15330 ? gen_addsi3 (stack_reg, stack_reg, todec)
15331 : gen_adddi3 (stack_reg, stack_reg, todec));
15332 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
15333 gen_rtx_REG (Pmode, 12));
15336 RTX_FRAME_RELATED_P (insn) = 1;
15337 REG_NOTES (insn) =
15338 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15339 gen_rtx_SET (VOIDmode, stack_reg,
15340 gen_rtx_PLUS (Pmode, stack_reg,
15341 GEN_INT (-size))),
15342 REG_NOTES (insn));
15345 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
15346 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
15347 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
15348 deduce these equivalences by itself so it wasn't necessary to hold
15349 its hand so much. */
15351 static void
15352 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
15353 rtx reg2, rtx rreg)
15355 rtx real, temp;
15357 /* copy_rtx will not make unique copies of registers, so we need to
15358 ensure we don't have unwanted sharing here. */
15359 if (reg == reg2)
15360 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
15362 if (reg == rreg)
15363 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
15365 real = copy_rtx (PATTERN (insn));
15367 if (reg2 != NULL_RTX)
15368 real = replace_rtx (real, reg2, rreg);
15370 real = replace_rtx (real, reg,
15371 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
15372 STACK_POINTER_REGNUM),
15373 GEN_INT (val)));
15375 /* We expect that 'real' is either a SET or a PARALLEL containing
15376 SETs (and possibly other stuff). In a PARALLEL, all the SETs
15377 are important so they all have to be marked RTX_FRAME_RELATED_P. */
15379 if (GET_CODE (real) == SET)
15381 rtx set = real;
15383 temp = simplify_rtx (SET_SRC (set));
15384 if (temp)
15385 SET_SRC (set) = temp;
15386 temp = simplify_rtx (SET_DEST (set));
15387 if (temp)
15388 SET_DEST (set) = temp;
15389 if (GET_CODE (SET_DEST (set)) == MEM)
15391 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
15392 if (temp)
15393 XEXP (SET_DEST (set), 0) = temp;
15396 else
15398 int i;
15400 gcc_assert (GET_CODE (real) == PARALLEL);
15401 for (i = 0; i < XVECLEN (real, 0); i++)
15402 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
15404 rtx set = XVECEXP (real, 0, i);
15406 temp = simplify_rtx (SET_SRC (set));
15407 if (temp)
15408 SET_SRC (set) = temp;
15409 temp = simplify_rtx (SET_DEST (set));
15410 if (temp)
15411 SET_DEST (set) = temp;
15412 if (GET_CODE (SET_DEST (set)) == MEM)
15414 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
15415 if (temp)
15416 XEXP (SET_DEST (set), 0) = temp;
15418 RTX_FRAME_RELATED_P (set) = 1;
15422 RTX_FRAME_RELATED_P (insn) = 1;
15423 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15424 real,
15425 REG_NOTES (insn));
15428 /* Returns an insn that has a vrsave set operation with the
15429 appropriate CLOBBERs. */
15431 static rtx
15432 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
15434 int nclobs, i;
15435 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
15436 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
15438 clobs[0]
15439 = gen_rtx_SET (VOIDmode,
15440 vrsave,
15441 gen_rtx_UNSPEC_VOLATILE (SImode,
15442 gen_rtvec (2, reg, vrsave),
15443 UNSPECV_SET_VRSAVE));
15445 nclobs = 1;
15447 /* We need to clobber the registers in the mask so the scheduler
15448 does not move sets to VRSAVE before sets of AltiVec registers.
15450 However, if the function receives nonlocal gotos, reload will set
15451 all call saved registers live. We will end up with:
15453 (set (reg 999) (mem))
15454 (parallel [ (set (reg vrsave) (unspec blah))
15455 (clobber (reg 999))])
15457 The clobber will cause the store into reg 999 to be dead, and
15458 flow will attempt to delete an epilogue insn. In this case, we
15459 need an unspec use/set of the register. */
15461 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
15462 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
15464 if (!epiloguep || call_used_regs [i])
15465 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
15466 gen_rtx_REG (V4SImode, i));
15467 else
15469 rtx reg = gen_rtx_REG (V4SImode, i);
15471 clobs[nclobs++]
15472 = gen_rtx_SET (VOIDmode,
15473 reg,
15474 gen_rtx_UNSPEC (V4SImode,
15475 gen_rtvec (1, reg), 27));
15479 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
15481 for (i = 0; i < nclobs; ++i)
15482 XVECEXP (insn, 0, i) = clobs[i];
15484 return insn;
15487 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
15488 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
15490 static void
15491 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
15492 unsigned int regno, int offset, HOST_WIDE_INT total_size)
15494 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
15495 rtx replacea, replaceb;
15497 int_rtx = GEN_INT (offset);
15499 /* Some cases that need register indexed addressing. */
15500 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
15501 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode))
15502 || (TARGET_SPE_ABI
15503 && SPE_VECTOR_MODE (mode)
15504 && !SPE_CONST_OFFSET_OK (offset)))
15506 /* Whomever calls us must make sure r11 is available in the
15507 flow path of instructions in the prologue. */
15508 offset_rtx = gen_rtx_REG (Pmode, 11);
15509 emit_move_insn (offset_rtx, int_rtx);
15511 replacea = offset_rtx;
15512 replaceb = int_rtx;
15514 else
15516 offset_rtx = int_rtx;
15517 replacea = NULL_RTX;
15518 replaceb = NULL_RTX;
15521 reg = gen_rtx_REG (mode, regno);
15522 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
15523 mem = gen_frame_mem (mode, addr);
15525 insn = emit_move_insn (mem, reg);
15527 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
15530 /* Emit an offset memory reference suitable for a frame store, while
15531 converting to a valid addressing mode. */
15533 static rtx
15534 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
15536 rtx int_rtx, offset_rtx;
15538 int_rtx = GEN_INT (offset);
15540 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
15541 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode)))
15543 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
15544 emit_move_insn (offset_rtx, int_rtx);
15546 else
15547 offset_rtx = int_rtx;
15549 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
15552 /* Look for user-defined global regs. We should not save and restore these,
15553 and cannot use stmw/lmw if there are any in its range. */
15555 static bool
15556 no_global_regs_above (int first_greg)
15558 int i;
15559 for (i = 0; i < 32 - first_greg; i++)
15560 if (global_regs[first_greg + i])
15561 return false;
15562 return true;
15565 #ifndef TARGET_FIX_AND_CONTINUE
15566 #define TARGET_FIX_AND_CONTINUE 0
15567 #endif
15569 /* Determine whether the gp REG is really used. */
15571 static bool
15572 rs6000_reg_live_or_pic_offset_p (int reg)
15574 return ((df_regs_ever_live_p (reg)
15575 && (!call_used_regs[reg]
15576 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
15577 && TARGET_TOC && TARGET_MINIMAL_TOC)))
15578 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
15579 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
15580 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
15583 /* Emit function prologue as insns. */
15585 void
15586 rs6000_emit_prologue (void)
15588 rs6000_stack_t *info = rs6000_stack_info ();
15589 enum machine_mode reg_mode = Pmode;
15590 int reg_size = TARGET_32BIT ? 4 : 8;
15591 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
15592 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
15593 rtx frame_reg_rtx = sp_reg_rtx;
15594 rtx cr_save_rtx = NULL_RTX;
15595 rtx insn;
15596 int saving_FPRs_inline;
15597 int using_store_multiple;
15598 HOST_WIDE_INT sp_offset = 0;
15600 if (TARGET_FIX_AND_CONTINUE)
15602 /* gdb on darwin arranges to forward a function from the old
15603 address by modifying the first 5 instructions of the function
15604 to branch to the overriding function. This is necessary to
15605 permit function pointers that point to the old function to
15606 actually forward to the new function. */
15607 emit_insn (gen_nop ());
15608 emit_insn (gen_nop ());
15609 emit_insn (gen_nop ());
15610 emit_insn (gen_nop ());
15611 emit_insn (gen_nop ());
15614 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15616 reg_mode = V2SImode;
15617 reg_size = 8;
15620 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
15621 && (!TARGET_SPE_ABI
15622 || info->spe_64bit_regs_used == 0)
15623 && info->first_gp_reg_save < 31
15624 && no_global_regs_above (info->first_gp_reg_save));
15625 saving_FPRs_inline = (info->first_fp_reg_save == 64
15626 || FP_SAVE_INLINE (info->first_fp_reg_save)
15627 || crtl->calls_eh_return
15628 || cfun->machine->ra_need_lr);
15630 /* For V.4, update stack before we do any saving and set back pointer. */
15631 if (! WORLD_SAVE_P (info)
15632 && info->push_p
15633 && (DEFAULT_ABI == ABI_V4
15634 || crtl->calls_eh_return))
15636 if (info->total_size < 32767)
15637 sp_offset = info->total_size;
15638 else
15639 frame_reg_rtx = frame_ptr_rtx;
15640 rs6000_emit_allocate_stack (info->total_size,
15641 (frame_reg_rtx != sp_reg_rtx
15642 && (info->cr_save_p
15643 || info->lr_save_p
15644 || info->first_fp_reg_save < 64
15645 || info->first_gp_reg_save < 32
15646 )));
15647 if (frame_reg_rtx != sp_reg_rtx)
15648 rs6000_emit_stack_tie ();
15651 /* Handle world saves specially here. */
15652 if (WORLD_SAVE_P (info))
15654 int i, j, sz;
15655 rtx treg;
15656 rtvec p;
15657 rtx reg0;
15659 /* save_world expects lr in r0. */
15660 reg0 = gen_rtx_REG (Pmode, 0);
15661 if (info->lr_save_p)
15663 insn = emit_move_insn (reg0,
15664 gen_rtx_REG (Pmode, LR_REGNO));
15665 RTX_FRAME_RELATED_P (insn) = 1;
15668 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
15669 assumptions about the offsets of various bits of the stack
15670 frame. */
15671 gcc_assert (info->gp_save_offset == -220
15672 && info->fp_save_offset == -144
15673 && info->lr_save_offset == 8
15674 && info->cr_save_offset == 4
15675 && info->push_p
15676 && info->lr_save_p
15677 && (!crtl->calls_eh_return
15678 || info->ehrd_offset == -432)
15679 && info->vrsave_save_offset == -224
15680 && info->altivec_save_offset == -416);
15682 treg = gen_rtx_REG (SImode, 11);
15683 emit_move_insn (treg, GEN_INT (-info->total_size));
15685 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
15686 in R11. It also clobbers R12, so beware! */
15688 /* Preserve CR2 for save_world prologues */
15689 sz = 5;
15690 sz += 32 - info->first_gp_reg_save;
15691 sz += 64 - info->first_fp_reg_save;
15692 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
15693 p = rtvec_alloc (sz);
15694 j = 0;
15695 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
15696 gen_rtx_REG (SImode,
15697 LR_REGNO));
15698 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
15699 gen_rtx_SYMBOL_REF (Pmode,
15700 "*save_world"));
15701 /* We do floats first so that the instruction pattern matches
15702 properly. */
15703 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15705 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15706 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15707 GEN_INT (info->fp_save_offset
15708 + sp_offset + 8 * i));
15709 rtx mem = gen_frame_mem (DFmode, addr);
15711 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15713 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
15715 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
15716 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15717 GEN_INT (info->altivec_save_offset
15718 + sp_offset + 16 * i));
15719 rtx mem = gen_frame_mem (V4SImode, addr);
15721 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15723 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15725 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15726 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15727 GEN_INT (info->gp_save_offset
15728 + sp_offset + reg_size * i));
15729 rtx mem = gen_frame_mem (reg_mode, addr);
15731 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15735 /* CR register traditionally saved as CR2. */
15736 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
15737 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15738 GEN_INT (info->cr_save_offset
15739 + sp_offset));
15740 rtx mem = gen_frame_mem (reg_mode, addr);
15742 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15744 /* Explain about use of R0. */
15745 if (info->lr_save_p)
15747 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15748 GEN_INT (info->lr_save_offset
15749 + sp_offset));
15750 rtx mem = gen_frame_mem (reg_mode, addr);
15752 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
15754 /* Explain what happens to the stack pointer. */
15756 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
15757 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
15760 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15761 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15762 treg, GEN_INT (-info->total_size));
15763 sp_offset = info->total_size;
15766 /* If we use the link register, get it into r0. */
15767 if (!WORLD_SAVE_P (info) && info->lr_save_p)
15769 rtx addr, reg, mem;
15771 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
15772 gen_rtx_REG (Pmode, LR_REGNO));
15773 RTX_FRAME_RELATED_P (insn) = 1;
15775 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15776 GEN_INT (info->lr_save_offset + sp_offset));
15777 reg = gen_rtx_REG (Pmode, 0);
15778 mem = gen_rtx_MEM (Pmode, addr);
15779 /* This should not be of rs6000_sr_alias_set, because of
15780 __builtin_return_address. */
15782 insn = emit_move_insn (mem, reg);
15783 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15784 NULL_RTX, NULL_RTX);
15787 /* If we need to save CR, put it into r12. */
15788 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
15790 rtx set;
15792 cr_save_rtx = gen_rtx_REG (SImode, 12);
15793 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
15794 RTX_FRAME_RELATED_P (insn) = 1;
15795 /* Now, there's no way that dwarf2out_frame_debug_expr is going
15796 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
15797 But that's OK. All we have to do is specify that _one_ condition
15798 code register is saved in this stack slot. The thrower's epilogue
15799 will then restore all the call-saved registers.
15800 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
15801 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
15802 gen_rtx_REG (SImode, CR2_REGNO));
15803 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15804 set,
15805 REG_NOTES (insn));
15808 /* Do any required saving of fpr's. If only one or two to save, do
15809 it ourselves. Otherwise, call function. */
15810 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
15812 int i;
15813 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15814 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
15815 && ! call_used_regs[info->first_fp_reg_save+i]))
15816 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
15817 info->first_fp_reg_save + i,
15818 info->fp_save_offset + sp_offset + 8 * i,
15819 info->total_size);
15821 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
15823 int i;
15824 char rname[30];
15825 const char *alloc_rname;
15826 rtvec p;
15827 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
15829 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
15830 gen_rtx_REG (Pmode,
15831 LR_REGNO));
15832 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
15833 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
15834 alloc_rname = ggc_strdup (rname);
15835 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
15836 gen_rtx_SYMBOL_REF (Pmode,
15837 alloc_rname));
15838 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15840 rtx addr, reg, mem;
15841 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15842 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15843 GEN_INT (info->fp_save_offset
15844 + sp_offset + 8*i));
15845 mem = gen_frame_mem (DFmode, addr);
15847 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
15849 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15850 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15851 NULL_RTX, NULL_RTX);
15854 /* Save GPRs. This is done as a PARALLEL if we are using
15855 the store-multiple instructions. */
15856 if (!WORLD_SAVE_P (info) && using_store_multiple)
15858 rtvec p;
15859 int i;
15860 p = rtvec_alloc (32 - info->first_gp_reg_save);
15861 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15863 rtx addr, reg, mem;
15864 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15865 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15866 GEN_INT (info->gp_save_offset
15867 + sp_offset
15868 + reg_size * i));
15869 mem = gen_frame_mem (reg_mode, addr);
15871 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
15873 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15874 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15875 NULL_RTX, NULL_RTX);
15877 else if (!WORLD_SAVE_P (info)
15878 && TARGET_SPE_ABI
15879 && info->spe_64bit_regs_used != 0
15880 && info->first_gp_reg_save != 32)
15882 int i;
15883 rtx spe_save_area_ptr;
15884 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
15885 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
15886 && !call_used_regs[STATIC_CHAIN_REGNUM]);
15888 /* Determine whether we can address all of the registers that need
15889 to be saved with an offset from the stack pointer that fits in
15890 the small const field for SPE memory instructions. */
15891 int spe_regs_addressable_via_sp
15892 = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
15893 + (32 - info->first_gp_reg_save - 1) * reg_size);
15894 int spe_offset;
15896 if (spe_regs_addressable_via_sp)
15898 spe_save_area_ptr = frame_reg_rtx;
15899 spe_offset = info->spe_gp_save_offset + sp_offset;
15901 else
15903 /* Make r11 point to the start of the SPE save area. We need
15904 to be careful here if r11 is holding the static chain. If
15905 it is, then temporarily save it in r0. We would use r0 as
15906 our base register here, but using r0 as a base register in
15907 loads and stores means something different from what we
15908 would like. */
15909 if (using_static_chain_p)
15911 rtx r0 = gen_rtx_REG (Pmode, 0);
15913 gcc_assert (info->first_gp_reg_save > 11);
15915 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
15918 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
15919 emit_insn (gen_addsi3 (spe_save_area_ptr, frame_reg_rtx,
15920 GEN_INT (info->spe_gp_save_offset + sp_offset)));
15922 spe_offset = 0;
15925 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15926 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
15928 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15929 rtx offset, addr, mem;
15931 /* We're doing all this to ensure that the offset fits into
15932 the immediate offset of 'evstdd'. */
15933 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
15935 offset = GEN_INT (reg_size * i + spe_offset);
15936 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
15937 mem = gen_rtx_MEM (V2SImode, addr);
15939 insn = emit_move_insn (mem, reg);
15941 rs6000_frame_related (insn, spe_save_area_ptr,
15942 info->spe_gp_save_offset
15943 + sp_offset + reg_size * i,
15944 offset, const0_rtx);
15947 /* Move the static chain pointer back. */
15948 if (using_static_chain_p && !spe_regs_addressable_via_sp)
15949 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
15951 else if (!WORLD_SAVE_P (info))
15953 int i;
15954 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15955 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
15957 rtx addr, reg, mem;
15958 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15960 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15961 GEN_INT (info->gp_save_offset
15962 + sp_offset
15963 + reg_size * i));
15964 mem = gen_frame_mem (reg_mode, addr);
15966 insn = emit_move_insn (mem, reg);
15967 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15968 NULL_RTX, NULL_RTX);
15972 /* ??? There's no need to emit actual instructions here, but it's the
15973 easiest way to get the frame unwind information emitted. */
15974 if (crtl->calls_eh_return)
15976 unsigned int i, regno;
15978 /* In AIX ABI we need to pretend we save r2 here. */
15979 if (TARGET_AIX)
15981 rtx addr, reg, mem;
15983 reg = gen_rtx_REG (reg_mode, 2);
15984 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15985 GEN_INT (sp_offset + 5 * reg_size));
15986 mem = gen_frame_mem (reg_mode, addr);
15988 insn = emit_move_insn (mem, reg);
15989 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15990 NULL_RTX, NULL_RTX);
15991 PATTERN (insn) = gen_blockage ();
15994 for (i = 0; ; ++i)
15996 regno = EH_RETURN_DATA_REGNO (i);
15997 if (regno == INVALID_REGNUM)
15998 break;
16000 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
16001 info->ehrd_offset + sp_offset
16002 + reg_size * (int) i,
16003 info->total_size);
16007 /* Save CR if we use any that must be preserved. */
16008 if (!WORLD_SAVE_P (info) && info->cr_save_p)
16010 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16011 GEN_INT (info->cr_save_offset + sp_offset));
16012 rtx mem = gen_frame_mem (SImode, addr);
16013 /* See the large comment above about why CR2_REGNO is used. */
16014 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
16016 /* If r12 was used to hold the original sp, copy cr into r0 now
16017 that it's free. */
16018 if (REGNO (frame_reg_rtx) == 12)
16020 rtx set;
16022 cr_save_rtx = gen_rtx_REG (SImode, 0);
16023 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
16024 RTX_FRAME_RELATED_P (insn) = 1;
16025 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
16026 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
16027 set,
16028 REG_NOTES (insn));
16031 insn = emit_move_insn (mem, cr_save_rtx);
16033 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
16034 NULL_RTX, NULL_RTX);
16037 /* Update stack and set back pointer unless this is V.4,
16038 for which it was done previously. */
16039 if (!WORLD_SAVE_P (info) && info->push_p
16040 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
16042 if (info->total_size < 32767)
16043 sp_offset = info->total_size;
16044 else
16045 frame_reg_rtx = frame_ptr_rtx;
16046 rs6000_emit_allocate_stack (info->total_size,
16047 (frame_reg_rtx != sp_reg_rtx
16048 && ((info->altivec_size != 0)
16049 || (info->vrsave_mask != 0)
16050 )));
16051 if (frame_reg_rtx != sp_reg_rtx)
16052 rs6000_emit_stack_tie ();
16055 /* Set frame pointer, if needed. */
16056 if (frame_pointer_needed)
16058 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
16059 sp_reg_rtx);
16060 RTX_FRAME_RELATED_P (insn) = 1;
16063 /* Save AltiVec registers if needed. Save here because the red zone does
16064 not include AltiVec registers. */
16065 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
16067 int i;
16069 /* There should be a non inline version of this, for when we
16070 are saving lots of vector registers. */
16071 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
16072 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
16074 rtx areg, savereg, mem;
16075 int offset;
16077 offset = info->altivec_save_offset + sp_offset
16078 + 16 * (i - info->first_altivec_reg_save);
16080 savereg = gen_rtx_REG (V4SImode, i);
16082 areg = gen_rtx_REG (Pmode, 0);
16083 emit_move_insn (areg, GEN_INT (offset));
16085 /* AltiVec addressing mode is [reg+reg]. */
16086 mem = gen_frame_mem (V4SImode,
16087 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
16089 insn = emit_move_insn (mem, savereg);
16091 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
16092 areg, GEN_INT (offset));
16096 /* VRSAVE is a bit vector representing which AltiVec registers
16097 are used. The OS uses this to determine which vector
16098 registers to save on a context switch. We need to save
16099 VRSAVE on the stack frame, add whatever AltiVec registers we
16100 used in this function, and do the corresponding magic in the
16101 epilogue. */
16103 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
16104 && info->vrsave_mask != 0)
16106 rtx reg, mem, vrsave;
16107 int offset;
16109 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
16110 as frame_reg_rtx and r11 as the static chain pointer for
16111 nested functions. */
16112 reg = gen_rtx_REG (SImode, 0);
16113 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
16114 if (TARGET_MACHO)
16115 emit_insn (gen_get_vrsave_internal (reg));
16116 else
16117 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
16119 if (!WORLD_SAVE_P (info))
16121 /* Save VRSAVE. */
16122 offset = info->vrsave_save_offset + sp_offset;
16123 mem = gen_frame_mem (SImode,
16124 gen_rtx_PLUS (Pmode, frame_reg_rtx,
16125 GEN_INT (offset)));
16126 insn = emit_move_insn (mem, reg);
16129 /* Include the registers in the mask. */
16130 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
16132 insn = emit_insn (generate_set_vrsave (reg, info, 0));
16135 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
16136 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
16137 || (DEFAULT_ABI == ABI_V4
16138 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
16139 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
16141 /* If emit_load_toc_table will use the link register, we need to save
16142 it. We use R12 for this purpose because emit_load_toc_table
16143 can use register 0. This allows us to use a plain 'blr' to return
16144 from the procedure more often. */
16145 int save_LR_around_toc_setup = (TARGET_ELF
16146 && DEFAULT_ABI != ABI_AIX
16147 && flag_pic
16148 && ! info->lr_save_p
16149 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
16150 if (save_LR_around_toc_setup)
16152 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
16154 insn = emit_move_insn (frame_ptr_rtx, lr);
16155 RTX_FRAME_RELATED_P (insn) = 1;
16157 rs6000_emit_load_toc_table (TRUE);
16159 insn = emit_move_insn (lr, frame_ptr_rtx);
16160 RTX_FRAME_RELATED_P (insn) = 1;
16162 else
16163 rs6000_emit_load_toc_table (TRUE);
16166 #if TARGET_MACHO
16167 if (DEFAULT_ABI == ABI_DARWIN
16168 && flag_pic && crtl->uses_pic_offset_table)
16170 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
16171 rtx src = machopic_function_base_sym ();
16173 /* Save and restore LR locally around this call (in R0). */
16174 if (!info->lr_save_p)
16175 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
16177 emit_insn (gen_load_macho_picbase (src));
16179 emit_move_insn (gen_rtx_REG (Pmode,
16180 RS6000_PIC_OFFSET_TABLE_REGNUM),
16181 lr);
16183 if (!info->lr_save_p)
16184 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
16186 #endif
16189 /* Write function prologue. */
16191 static void
16192 rs6000_output_function_prologue (FILE *file,
16193 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
16195 rs6000_stack_t *info = rs6000_stack_info ();
16197 if (TARGET_DEBUG_STACK)
16198 debug_stack_info (info);
16200 /* Write .extern for any function we will call to save and restore
16201 fp values. */
16202 if (info->first_fp_reg_save < 64
16203 && !FP_SAVE_INLINE (info->first_fp_reg_save))
16204 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
16205 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
16206 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
16207 RESTORE_FP_SUFFIX);
16209 /* Write .extern for AIX common mode routines, if needed. */
16210 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
16212 fputs ("\t.extern __mulh\n", file);
16213 fputs ("\t.extern __mull\n", file);
16214 fputs ("\t.extern __divss\n", file);
16215 fputs ("\t.extern __divus\n", file);
16216 fputs ("\t.extern __quoss\n", file);
16217 fputs ("\t.extern __quous\n", file);
16218 common_mode_defined = 1;
16221 if (! HAVE_prologue)
16223 start_sequence ();
16225 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
16226 the "toplevel" insn chain. */
16227 emit_note (NOTE_INSN_DELETED);
16228 rs6000_emit_prologue ();
16229 emit_note (NOTE_INSN_DELETED);
16231 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16233 rtx insn;
16234 unsigned addr = 0;
16235 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
16237 INSN_ADDRESSES_NEW (insn, addr);
16238 addr += 4;
16242 if (TARGET_DEBUG_STACK)
16243 debug_rtx_list (get_insns (), 100);
16244 final (get_insns (), file, FALSE);
16245 end_sequence ();
16248 rs6000_pic_labelno++;
16251 /* Non-zero if vmx regs are restored before the frame pop, zero if
16252 we restore after the pop when possible. */
16253 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
16255 /* Emit function epilogue as insns.
16257 At present, dwarf2out_frame_debug_expr doesn't understand
16258 register restores, so we don't bother setting RTX_FRAME_RELATED_P
16259 anywhere in the epilogue. Most of the insns below would in any case
16260 need special notes to explain where r11 is in relation to the stack. */
16262 void
16263 rs6000_emit_epilogue (int sibcall)
16265 rs6000_stack_t *info;
16266 int restoring_FPRs_inline;
16267 int using_load_multiple;
16268 int using_mtcr_multiple;
16269 int use_backchain_to_restore_sp;
16270 int sp_offset = 0;
16271 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
16272 rtx frame_reg_rtx = sp_reg_rtx;
16273 enum machine_mode reg_mode = Pmode;
16274 int reg_size = TARGET_32BIT ? 4 : 8;
16275 int i;
16277 info = rs6000_stack_info ();
16279 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
16281 reg_mode = V2SImode;
16282 reg_size = 8;
16285 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
16286 && (!TARGET_SPE_ABI
16287 || info->spe_64bit_regs_used == 0)
16288 && info->first_gp_reg_save < 31
16289 && no_global_regs_above (info->first_gp_reg_save));
16290 restoring_FPRs_inline = (sibcall
16291 || crtl->calls_eh_return
16292 || info->first_fp_reg_save == 64
16293 || FP_SAVE_INLINE (info->first_fp_reg_save));
16294 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
16295 || rs6000_cpu == PROCESSOR_PPC603
16296 || rs6000_cpu == PROCESSOR_PPC750
16297 || optimize_size);
16298 /* Restore via the backchain when we have a large frame, since this
16299 is more efficient than an addis, addi pair. The second condition
16300 here will not trigger at the moment; We don't actually need a
16301 frame pointer for alloca, but the generic parts of the compiler
16302 give us one anyway. */
16303 use_backchain_to_restore_sp = (info->total_size > 32767
16304 || (cfun->calls_alloca
16305 && !frame_pointer_needed));
16307 if (WORLD_SAVE_P (info))
16309 int i, j;
16310 char rname[30];
16311 const char *alloc_rname;
16312 rtvec p;
16314 /* eh_rest_world_r10 will return to the location saved in the LR
16315 stack slot (which is not likely to be our caller.)
16316 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
16317 rest_world is similar, except any R10 parameter is ignored.
16318 The exception-handling stuff that was here in 2.95 is no
16319 longer necessary. */
16321 p = rtvec_alloc (9
16323 + 32 - info->first_gp_reg_save
16324 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
16325 + 63 + 1 - info->first_fp_reg_save);
16327 strcpy (rname, ((crtl->calls_eh_return) ?
16328 "*eh_rest_world_r10" : "*rest_world"));
16329 alloc_rname = ggc_strdup (rname);
16331 j = 0;
16332 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
16333 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
16334 gen_rtx_REG (Pmode,
16335 LR_REGNO));
16336 RTVEC_ELT (p, j++)
16337 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
16338 /* The instruction pattern requires a clobber here;
16339 it is shared with the restVEC helper. */
16340 RTVEC_ELT (p, j++)
16341 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
16344 /* CR register traditionally saved as CR2. */
16345 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
16346 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16347 GEN_INT (info->cr_save_offset));
16348 rtx mem = gen_frame_mem (reg_mode, addr);
16350 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
16353 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16355 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
16356 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16357 GEN_INT (info->gp_save_offset
16358 + reg_size * i));
16359 rtx mem = gen_frame_mem (reg_mode, addr);
16361 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
16363 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
16365 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
16366 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16367 GEN_INT (info->altivec_save_offset
16368 + 16 * i));
16369 rtx mem = gen_frame_mem (V4SImode, addr);
16371 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
16373 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
16375 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
16376 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16377 GEN_INT (info->fp_save_offset
16378 + 8 * i));
16379 rtx mem = gen_frame_mem (DFmode, addr);
16381 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
16383 RTVEC_ELT (p, j++)
16384 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
16385 RTVEC_ELT (p, j++)
16386 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
16387 RTVEC_ELT (p, j++)
16388 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
16389 RTVEC_ELT (p, j++)
16390 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
16391 RTVEC_ELT (p, j++)
16392 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
16393 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
16395 return;
16398 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
16399 if (info->push_p)
16400 sp_offset = info->total_size;
16402 /* Restore AltiVec registers if we must do so before adjusting the
16403 stack. */
16404 if (TARGET_ALTIVEC_ABI
16405 && info->altivec_size != 0
16406 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16407 || (DEFAULT_ABI != ABI_V4
16408 && info->altivec_save_offset < (TARGET_32BIT ? -220 : -288))))
16410 int i;
16412 if (use_backchain_to_restore_sp)
16414 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16415 emit_move_insn (frame_reg_rtx,
16416 gen_rtx_MEM (Pmode, sp_reg_rtx));
16417 sp_offset = 0;
16419 else if (frame_pointer_needed)
16420 frame_reg_rtx = hard_frame_pointer_rtx;
16422 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
16423 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
16425 rtx addr, areg, mem;
16427 areg = gen_rtx_REG (Pmode, 0);
16428 emit_move_insn
16429 (areg, GEN_INT (info->altivec_save_offset
16430 + sp_offset
16431 + 16 * (i - info->first_altivec_reg_save)));
16433 /* AltiVec addressing mode is [reg+reg]. */
16434 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
16435 mem = gen_frame_mem (V4SImode, addr);
16437 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
16441 /* Restore VRSAVE if we must do so before adjusting the stack. */
16442 if (TARGET_ALTIVEC
16443 && TARGET_ALTIVEC_VRSAVE
16444 && info->vrsave_mask != 0
16445 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16446 || (DEFAULT_ABI != ABI_V4
16447 && info->vrsave_save_offset < (TARGET_32BIT ? -220 : -288))))
16449 rtx addr, mem, reg;
16451 if (frame_reg_rtx == sp_reg_rtx)
16453 if (use_backchain_to_restore_sp)
16455 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16456 emit_move_insn (frame_reg_rtx,
16457 gen_rtx_MEM (Pmode, sp_reg_rtx));
16458 sp_offset = 0;
16460 else if (frame_pointer_needed)
16461 frame_reg_rtx = hard_frame_pointer_rtx;
16464 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16465 GEN_INT (info->vrsave_save_offset + sp_offset));
16466 mem = gen_frame_mem (SImode, addr);
16467 reg = gen_rtx_REG (SImode, 12);
16468 emit_move_insn (reg, mem);
16470 emit_insn (generate_set_vrsave (reg, info, 1));
16473 /* If we have a large stack frame, restore the old stack pointer
16474 using the backchain. */
16475 if (use_backchain_to_restore_sp)
16477 if (frame_reg_rtx == sp_reg_rtx)
16479 /* Under V.4, don't reset the stack pointer until after we're done
16480 loading the saved registers. */
16481 if (DEFAULT_ABI == ABI_V4)
16482 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16484 emit_move_insn (frame_reg_rtx,
16485 gen_rtx_MEM (Pmode, sp_reg_rtx));
16486 sp_offset = 0;
16488 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16489 && DEFAULT_ABI == ABI_V4)
16490 /* frame_reg_rtx has been set up by the altivec restore. */
16492 else
16494 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
16495 frame_reg_rtx = sp_reg_rtx;
16498 /* If we have a frame pointer, we can restore the old stack pointer
16499 from it. */
16500 else if (frame_pointer_needed)
16502 frame_reg_rtx = sp_reg_rtx;
16503 if (DEFAULT_ABI == ABI_V4)
16504 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16506 emit_insn (TARGET_32BIT
16507 ? gen_addsi3 (frame_reg_rtx, hard_frame_pointer_rtx,
16508 GEN_INT (info->total_size))
16509 : gen_adddi3 (frame_reg_rtx, hard_frame_pointer_rtx,
16510 GEN_INT (info->total_size)));
16511 sp_offset = 0;
16513 else if (info->push_p
16514 && DEFAULT_ABI != ABI_V4
16515 && !crtl->calls_eh_return)
16517 emit_insn (TARGET_32BIT
16518 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
16519 GEN_INT (info->total_size))
16520 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
16521 GEN_INT (info->total_size)));
16522 sp_offset = 0;
16525 /* Restore AltiVec registers if we have not done so already. */
16526 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16527 && TARGET_ALTIVEC_ABI
16528 && info->altivec_size != 0
16529 && (DEFAULT_ABI == ABI_V4
16530 || info->altivec_save_offset >= (TARGET_32BIT ? -220 : -288)))
16532 int i;
16534 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
16535 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
16537 rtx addr, areg, mem;
16539 areg = gen_rtx_REG (Pmode, 0);
16540 emit_move_insn
16541 (areg, GEN_INT (info->altivec_save_offset
16542 + sp_offset
16543 + 16 * (i - info->first_altivec_reg_save)));
16545 /* AltiVec addressing mode is [reg+reg]. */
16546 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
16547 mem = gen_frame_mem (V4SImode, addr);
16549 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
16553 /* Restore VRSAVE if we have not done so already. */
16554 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16555 && TARGET_ALTIVEC
16556 && TARGET_ALTIVEC_VRSAVE
16557 && info->vrsave_mask != 0
16558 && (DEFAULT_ABI == ABI_V4
16559 || info->vrsave_save_offset >= (TARGET_32BIT ? -220 : -288)))
16561 rtx addr, mem, reg;
16563 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16564 GEN_INT (info->vrsave_save_offset + sp_offset));
16565 mem = gen_frame_mem (SImode, addr);
16566 reg = gen_rtx_REG (SImode, 12);
16567 emit_move_insn (reg, mem);
16569 emit_insn (generate_set_vrsave (reg, info, 1));
16572 /* Get the old lr if we saved it. */
16573 if (info->lr_save_p)
16575 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
16576 info->lr_save_offset + sp_offset);
16578 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
16581 /* Get the old cr if we saved it. */
16582 if (info->cr_save_p)
16584 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16585 GEN_INT (info->cr_save_offset + sp_offset));
16586 rtx mem = gen_frame_mem (SImode, addr);
16588 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
16591 /* Set LR here to try to overlap restores below. */
16592 if (info->lr_save_p)
16593 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
16594 gen_rtx_REG (Pmode, 0));
16596 /* Load exception handler data registers, if needed. */
16597 if (crtl->calls_eh_return)
16599 unsigned int i, regno;
16601 if (TARGET_AIX)
16603 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16604 GEN_INT (sp_offset + 5 * reg_size));
16605 rtx mem = gen_frame_mem (reg_mode, addr);
16607 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
16610 for (i = 0; ; ++i)
16612 rtx mem;
16614 regno = EH_RETURN_DATA_REGNO (i);
16615 if (regno == INVALID_REGNUM)
16616 break;
16618 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
16619 info->ehrd_offset + sp_offset
16620 + reg_size * (int) i);
16622 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
16626 /* Restore GPRs. This is done as a PARALLEL if we are using
16627 the load-multiple instructions. */
16628 if (using_load_multiple)
16630 rtvec p;
16631 p = rtvec_alloc (32 - info->first_gp_reg_save);
16632 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16634 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16635 GEN_INT (info->gp_save_offset
16636 + sp_offset
16637 + reg_size * i));
16638 rtx mem = gen_frame_mem (reg_mode, addr);
16640 RTVEC_ELT (p, i) =
16641 gen_rtx_SET (VOIDmode,
16642 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
16643 mem);
16645 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
16647 else if (TARGET_SPE_ABI
16648 && info->spe_64bit_regs_used != 0
16649 && info->first_gp_reg_save != 32)
16651 /* Determine whether we can address all of the registers that need
16652 to be saved with an offset from the stack pointer that fits in
16653 the small const field for SPE memory instructions. */
16654 int spe_regs_addressable_via_sp
16655 = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
16656 + (32 - info->first_gp_reg_save - 1) * reg_size);
16657 int spe_offset;
16659 if (spe_regs_addressable_via_sp)
16660 spe_offset = info->spe_gp_save_offset + sp_offset;
16661 else
16663 rtx old_frame_reg_rtx = frame_reg_rtx;
16664 /* Make r11 point to the start of the SPE save area. We worried about
16665 not clobbering it when we were saving registers in the prologue.
16666 There's no need to worry here because the static chain is passed
16667 anew to every function. */
16668 if (frame_reg_rtx == sp_reg_rtx)
16669 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16670 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
16671 GEN_INT (info->spe_gp_save_offset + sp_offset)));
16672 /* Keep the invariant that frame_reg_rtx + sp_offset points
16673 at the top of the stack frame. */
16674 sp_offset = -info->spe_gp_save_offset;
16676 spe_offset = 0;
16679 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16680 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
16682 rtx offset, addr, mem;
16684 /* We're doing all this to ensure that the immediate offset
16685 fits into the immediate field of 'evldd'. */
16686 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
16688 offset = GEN_INT (spe_offset + reg_size * i);
16689 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
16690 mem = gen_rtx_MEM (V2SImode, addr);
16692 emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
16693 mem);
16696 else
16697 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16698 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
16700 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16701 GEN_INT (info->gp_save_offset
16702 + sp_offset
16703 + reg_size * i));
16704 rtx mem = gen_frame_mem (reg_mode, addr);
16706 emit_move_insn (gen_rtx_REG (reg_mode,
16707 info->first_gp_reg_save + i), mem);
16710 /* Restore fpr's if we need to do it without calling a function. */
16711 if (restoring_FPRs_inline)
16712 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
16713 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
16714 && ! call_used_regs[info->first_fp_reg_save+i]))
16716 rtx addr, mem;
16717 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16718 GEN_INT (info->fp_save_offset
16719 + sp_offset
16720 + 8 * i));
16721 mem = gen_frame_mem (DFmode, addr);
16723 emit_move_insn (gen_rtx_REG (DFmode,
16724 info->first_fp_reg_save + i),
16725 mem);
16728 /* If we saved cr, restore it here. Just those that were used. */
16729 if (info->cr_save_p)
16731 rtx r12_rtx = gen_rtx_REG (SImode, 12);
16732 int count = 0;
16734 if (using_mtcr_multiple)
16736 for (i = 0; i < 8; i++)
16737 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
16738 count++;
16739 gcc_assert (count);
16742 if (using_mtcr_multiple && count > 1)
16744 rtvec p;
16745 int ndx;
16747 p = rtvec_alloc (count);
16749 ndx = 0;
16750 for (i = 0; i < 8; i++)
16751 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
16753 rtvec r = rtvec_alloc (2);
16754 RTVEC_ELT (r, 0) = r12_rtx;
16755 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
16756 RTVEC_ELT (p, ndx) =
16757 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
16758 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
16759 ndx++;
16761 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
16762 gcc_assert (ndx == count);
16764 else
16765 for (i = 0; i < 8; i++)
16766 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
16768 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
16769 CR0_REGNO+i),
16770 r12_rtx));
16774 /* If this is V.4, unwind the stack pointer after all of the loads
16775 have been done. */
16776 if (frame_reg_rtx != sp_reg_rtx)
16778 /* This blockage is needed so that sched doesn't decide to move
16779 the sp change before the register restores. */
16780 rs6000_emit_stack_tie ();
16781 if (sp_offset != 0)
16782 emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
16783 GEN_INT (sp_offset)));
16784 else
16785 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
16787 else if (sp_offset != 0)
16788 emit_insn (TARGET_32BIT
16789 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
16790 GEN_INT (sp_offset))
16791 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
16792 GEN_INT (sp_offset)));
16794 if (crtl->calls_eh_return)
16796 rtx sa = EH_RETURN_STACKADJ_RTX;
16797 emit_insn (TARGET_32BIT
16798 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
16799 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
16802 if (!sibcall)
16804 rtvec p;
16805 if (! restoring_FPRs_inline)
16806 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
16807 else
16808 p = rtvec_alloc (2);
16810 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
16811 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
16812 gen_rtx_REG (Pmode,
16813 LR_REGNO));
16815 /* If we have to restore more than two FP registers, branch to the
16816 restore function. It will return to our caller. */
16817 if (! restoring_FPRs_inline)
16819 int i;
16820 char rname[30];
16821 const char *alloc_rname;
16823 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
16824 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
16825 alloc_rname = ggc_strdup (rname);
16826 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
16827 gen_rtx_SYMBOL_REF (Pmode,
16828 alloc_rname));
16830 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
16832 rtx addr, mem;
16833 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
16834 GEN_INT (info->fp_save_offset + 8*i));
16835 mem = gen_frame_mem (DFmode, addr);
16837 RTVEC_ELT (p, i+3) =
16838 gen_rtx_SET (VOIDmode,
16839 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
16840 mem);
16844 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
16848 /* Write function epilogue. */
16850 static void
16851 rs6000_output_function_epilogue (FILE *file,
16852 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
16854 if (! HAVE_epilogue)
16856 rtx insn = get_last_insn ();
16857 /* If the last insn was a BARRIER, we don't have to write anything except
16858 the trace table. */
16859 if (GET_CODE (insn) == NOTE)
16860 insn = prev_nonnote_insn (insn);
16861 if (insn == 0 || GET_CODE (insn) != BARRIER)
16863 /* This is slightly ugly, but at least we don't have two
16864 copies of the epilogue-emitting code. */
16865 start_sequence ();
16867 /* A NOTE_INSN_DELETED is supposed to be at the start
16868 and end of the "toplevel" insn chain. */
16869 emit_note (NOTE_INSN_DELETED);
16870 rs6000_emit_epilogue (FALSE);
16871 emit_note (NOTE_INSN_DELETED);
16873 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16875 rtx insn;
16876 unsigned addr = 0;
16877 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
16879 INSN_ADDRESSES_NEW (insn, addr);
16880 addr += 4;
16884 if (TARGET_DEBUG_STACK)
16885 debug_rtx_list (get_insns (), 100);
16886 final (get_insns (), file, FALSE);
16887 end_sequence ();
16891 #if TARGET_MACHO
16892 macho_branch_islands ();
16893 /* Mach-O doesn't support labels at the end of objects, so if
16894 it looks like we might want one, insert a NOP. */
16896 rtx insn = get_last_insn ();
16897 while (insn
16898 && NOTE_P (insn)
16899 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
16900 insn = PREV_INSN (insn);
16901 if (insn
16902 && (LABEL_P (insn)
16903 || (NOTE_P (insn)
16904 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
16905 fputs ("\tnop\n", file);
16907 #endif
16909 /* Output a traceback table here. See /usr/include/sys/debug.h for info
16910 on its format.
16912 We don't output a traceback table if -finhibit-size-directive was
16913 used. The documentation for -finhibit-size-directive reads
16914 ``don't output a @code{.size} assembler directive, or anything
16915 else that would cause trouble if the function is split in the
16916 middle, and the two halves are placed at locations far apart in
16917 memory.'' The traceback table has this property, since it
16918 includes the offset from the start of the function to the
16919 traceback table itself.
16921 System V.4 Powerpc's (and the embedded ABI derived from it) use a
16922 different traceback table. */
16923 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
16924 && rs6000_traceback != traceback_none && !crtl->is_thunk)
16926 const char *fname = NULL;
16927 const char *language_string = lang_hooks.name;
16928 int fixed_parms = 0, float_parms = 0, parm_info = 0;
16929 int i;
16930 int optional_tbtab;
16931 rs6000_stack_t *info = rs6000_stack_info ();
16933 if (rs6000_traceback == traceback_full)
16934 optional_tbtab = 1;
16935 else if (rs6000_traceback == traceback_part)
16936 optional_tbtab = 0;
16937 else
16938 optional_tbtab = !optimize_size && !TARGET_ELF;
16940 if (optional_tbtab)
16942 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
16943 while (*fname == '.') /* V.4 encodes . in the name */
16944 fname++;
16946 /* Need label immediately before tbtab, so we can compute
16947 its offset from the function start. */
16948 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
16949 ASM_OUTPUT_LABEL (file, fname);
16952 /* The .tbtab pseudo-op can only be used for the first eight
16953 expressions, since it can't handle the possibly variable
16954 length fields that follow. However, if you omit the optional
16955 fields, the assembler outputs zeros for all optional fields
16956 anyways, giving each variable length field is minimum length
16957 (as defined in sys/debug.h). Thus we can not use the .tbtab
16958 pseudo-op at all. */
16960 /* An all-zero word flags the start of the tbtab, for debuggers
16961 that have to find it by searching forward from the entry
16962 point or from the current pc. */
16963 fputs ("\t.long 0\n", file);
16965 /* Tbtab format type. Use format type 0. */
16966 fputs ("\t.byte 0,", file);
16968 /* Language type. Unfortunately, there does not seem to be any
16969 official way to discover the language being compiled, so we
16970 use language_string.
16971 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
16972 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
16973 a number, so for now use 9. */
16974 if (! strcmp (language_string, "GNU C"))
16975 i = 0;
16976 else if (! strcmp (language_string, "GNU F77")
16977 || ! strcmp (language_string, "GNU Fortran"))
16978 i = 1;
16979 else if (! strcmp (language_string, "GNU Pascal"))
16980 i = 2;
16981 else if (! strcmp (language_string, "GNU Ada"))
16982 i = 3;
16983 else if (! strcmp (language_string, "GNU C++")
16984 || ! strcmp (language_string, "GNU Objective-C++"))
16985 i = 9;
16986 else if (! strcmp (language_string, "GNU Java"))
16987 i = 13;
16988 else if (! strcmp (language_string, "GNU Objective-C"))
16989 i = 14;
16990 else
16991 gcc_unreachable ();
16992 fprintf (file, "%d,", i);
16994 /* 8 single bit fields: global linkage (not set for C extern linkage,
16995 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
16996 from start of procedure stored in tbtab, internal function, function
16997 has controlled storage, function has no toc, function uses fp,
16998 function logs/aborts fp operations. */
16999 /* Assume that fp operations are used if any fp reg must be saved. */
17000 fprintf (file, "%d,",
17001 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
17003 /* 6 bitfields: function is interrupt handler, name present in
17004 proc table, function calls alloca, on condition directives
17005 (controls stack walks, 3 bits), saves condition reg, saves
17006 link reg. */
17007 /* The `function calls alloca' bit seems to be set whenever reg 31 is
17008 set up as a frame pointer, even when there is no alloca call. */
17009 fprintf (file, "%d,",
17010 ((optional_tbtab << 6)
17011 | ((optional_tbtab & frame_pointer_needed) << 5)
17012 | (info->cr_save_p << 1)
17013 | (info->lr_save_p)));
17015 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
17016 (6 bits). */
17017 fprintf (file, "%d,",
17018 (info->push_p << 7) | (64 - info->first_fp_reg_save));
17020 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
17021 fprintf (file, "%d,", (32 - first_reg_to_save ()));
17023 if (optional_tbtab)
17025 /* Compute the parameter info from the function decl argument
17026 list. */
17027 tree decl;
17028 int next_parm_info_bit = 31;
17030 for (decl = DECL_ARGUMENTS (current_function_decl);
17031 decl; decl = TREE_CHAIN (decl))
17033 rtx parameter = DECL_INCOMING_RTL (decl);
17034 enum machine_mode mode = GET_MODE (parameter);
17036 if (GET_CODE (parameter) == REG)
17038 if (SCALAR_FLOAT_MODE_P (mode))
17040 int bits;
17042 float_parms++;
17044 switch (mode)
17046 case SFmode:
17047 case SDmode:
17048 bits = 0x2;
17049 break;
17051 case DFmode:
17052 case DDmode:
17053 case TFmode:
17054 case TDmode:
17055 bits = 0x3;
17056 break;
17058 default:
17059 gcc_unreachable ();
17062 /* If only one bit will fit, don't or in this entry. */
17063 if (next_parm_info_bit > 0)
17064 parm_info |= (bits << (next_parm_info_bit - 1));
17065 next_parm_info_bit -= 2;
17067 else
17069 fixed_parms += ((GET_MODE_SIZE (mode)
17070 + (UNITS_PER_WORD - 1))
17071 / UNITS_PER_WORD);
17072 next_parm_info_bit -= 1;
17078 /* Number of fixed point parameters. */
17079 /* This is actually the number of words of fixed point parameters; thus
17080 an 8 byte struct counts as 2; and thus the maximum value is 8. */
17081 fprintf (file, "%d,", fixed_parms);
17083 /* 2 bitfields: number of floating point parameters (7 bits), parameters
17084 all on stack. */
17085 /* This is actually the number of fp registers that hold parameters;
17086 and thus the maximum value is 13. */
17087 /* Set parameters on stack bit if parameters are not in their original
17088 registers, regardless of whether they are on the stack? Xlc
17089 seems to set the bit when not optimizing. */
17090 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
17092 if (! optional_tbtab)
17093 return;
17095 /* Optional fields follow. Some are variable length. */
17097 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
17098 11 double float. */
17099 /* There is an entry for each parameter in a register, in the order that
17100 they occur in the parameter list. Any intervening arguments on the
17101 stack are ignored. If the list overflows a long (max possible length
17102 34 bits) then completely leave off all elements that don't fit. */
17103 /* Only emit this long if there was at least one parameter. */
17104 if (fixed_parms || float_parms)
17105 fprintf (file, "\t.long %d\n", parm_info);
17107 /* Offset from start of code to tb table. */
17108 fputs ("\t.long ", file);
17109 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
17110 if (TARGET_AIX)
17111 RS6000_OUTPUT_BASENAME (file, fname);
17112 else
17113 assemble_name (file, fname);
17114 putc ('-', file);
17115 rs6000_output_function_entry (file, fname);
17116 putc ('\n', file);
17118 /* Interrupt handler mask. */
17119 /* Omit this long, since we never set the interrupt handler bit
17120 above. */
17122 /* Number of CTL (controlled storage) anchors. */
17123 /* Omit this long, since the has_ctl bit is never set above. */
17125 /* Displacement into stack of each CTL anchor. */
17126 /* Omit this list of longs, because there are no CTL anchors. */
17128 /* Length of function name. */
17129 if (*fname == '*')
17130 ++fname;
17131 fprintf (file, "\t.short %d\n", (int) strlen (fname));
17133 /* Function name. */
17134 assemble_string (fname, strlen (fname));
17136 /* Register for alloca automatic storage; this is always reg 31.
17137 Only emit this if the alloca bit was set above. */
17138 if (frame_pointer_needed)
17139 fputs ("\t.byte 31\n", file);
17141 fputs ("\t.align 2\n", file);
17145 /* A C compound statement that outputs the assembler code for a thunk
17146 function, used to implement C++ virtual function calls with
17147 multiple inheritance. The thunk acts as a wrapper around a virtual
17148 function, adjusting the implicit object parameter before handing
17149 control off to the real function.
17151 First, emit code to add the integer DELTA to the location that
17152 contains the incoming first argument. Assume that this argument
17153 contains a pointer, and is the one used to pass the `this' pointer
17154 in C++. This is the incoming argument *before* the function
17155 prologue, e.g. `%o0' on a sparc. The addition must preserve the
17156 values of all other incoming arguments.
17158 After the addition, emit code to jump to FUNCTION, which is a
17159 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
17160 not touch the return address. Hence returning from FUNCTION will
17161 return to whoever called the current `thunk'.
17163 The effect must be as if FUNCTION had been called directly with the
17164 adjusted first argument. This macro is responsible for emitting
17165 all of the code for a thunk function; output_function_prologue()
17166 and output_function_epilogue() are not invoked.
17168 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
17169 been extracted from it.) It might possibly be useful on some
17170 targets, but probably not.
17172 If you do not define this macro, the target-independent code in the
17173 C++ frontend will generate a less efficient heavyweight thunk that
17174 calls FUNCTION instead of jumping to it. The generic approach does
17175 not support varargs. */
17177 static void
17178 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
17179 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
17180 tree function)
17182 rtx this, insn, funexp;
17184 reload_completed = 1;
17185 epilogue_completed = 1;
17187 /* Mark the end of the (empty) prologue. */
17188 emit_note (NOTE_INSN_PROLOGUE_END);
17190 /* Find the "this" pointer. If the function returns a structure,
17191 the structure return pointer is in r3. */
17192 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
17193 this = gen_rtx_REG (Pmode, 4);
17194 else
17195 this = gen_rtx_REG (Pmode, 3);
17197 /* Apply the constant offset, if required. */
17198 if (delta)
17200 rtx delta_rtx = GEN_INT (delta);
17201 emit_insn (TARGET_32BIT
17202 ? gen_addsi3 (this, this, delta_rtx)
17203 : gen_adddi3 (this, this, delta_rtx));
17206 /* Apply the offset from the vtable, if required. */
17207 if (vcall_offset)
17209 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
17210 rtx tmp = gen_rtx_REG (Pmode, 12);
17212 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
17213 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
17215 emit_insn (TARGET_32BIT
17216 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
17217 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
17218 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
17220 else
17222 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
17224 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
17226 emit_insn (TARGET_32BIT
17227 ? gen_addsi3 (this, this, tmp)
17228 : gen_adddi3 (this, this, tmp));
17231 /* Generate a tail call to the target function. */
17232 if (!TREE_USED (function))
17234 assemble_external (function);
17235 TREE_USED (function) = 1;
17237 funexp = XEXP (DECL_RTL (function), 0);
17238 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
17240 #if TARGET_MACHO
17241 if (MACHOPIC_INDIRECT)
17242 funexp = machopic_indirect_call_target (funexp);
17243 #endif
17245 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
17246 generate sibcall RTL explicitly. */
17247 insn = emit_call_insn (
17248 gen_rtx_PARALLEL (VOIDmode,
17249 gen_rtvec (4,
17250 gen_rtx_CALL (VOIDmode,
17251 funexp, const0_rtx),
17252 gen_rtx_USE (VOIDmode, const0_rtx),
17253 gen_rtx_USE (VOIDmode,
17254 gen_rtx_REG (SImode,
17255 LR_REGNO)),
17256 gen_rtx_RETURN (VOIDmode))));
17257 SIBLING_CALL_P (insn) = 1;
17258 emit_barrier ();
17260 /* Run just enough of rest_of_compilation to get the insns emitted.
17261 There's not really enough bulk here to make other passes such as
17262 instruction scheduling worth while. Note that use_thunk calls
17263 assemble_start_function and assemble_end_function. */
17264 insn = get_insns ();
17265 insn_locators_alloc ();
17266 shorten_branches (insn);
17267 final_start_function (insn, file, 1);
17268 final (insn, file, 1);
17269 final_end_function ();
17270 free_after_compilation (cfun);
17272 reload_completed = 0;
17273 epilogue_completed = 0;
17276 /* A quick summary of the various types of 'constant-pool tables'
17277 under PowerPC:
17279 Target Flags Name One table per
17280 AIX (none) AIX TOC object file
17281 AIX -mfull-toc AIX TOC object file
17282 AIX -mminimal-toc AIX minimal TOC translation unit
17283 SVR4/EABI (none) SVR4 SDATA object file
17284 SVR4/EABI -fpic SVR4 pic object file
17285 SVR4/EABI -fPIC SVR4 PIC translation unit
17286 SVR4/EABI -mrelocatable EABI TOC function
17287 SVR4/EABI -maix AIX TOC object file
17288 SVR4/EABI -maix -mminimal-toc
17289 AIX minimal TOC translation unit
17291 Name Reg. Set by entries contains:
17292 made by addrs? fp? sum?
17294 AIX TOC 2 crt0 as Y option option
17295 AIX minimal TOC 30 prolog gcc Y Y option
17296 SVR4 SDATA 13 crt0 gcc N Y N
17297 SVR4 pic 30 prolog ld Y not yet N
17298 SVR4 PIC 30 prolog gcc Y option option
17299 EABI TOC 30 prolog gcc Y option option
17303 /* Hash functions for the hash table. */
17305 static unsigned
17306 rs6000_hash_constant (rtx k)
17308 enum rtx_code code = GET_CODE (k);
17309 enum machine_mode mode = GET_MODE (k);
17310 unsigned result = (code << 3) ^ mode;
17311 const char *format;
17312 int flen, fidx;
17314 format = GET_RTX_FORMAT (code);
17315 flen = strlen (format);
17316 fidx = 0;
17318 switch (code)
17320 case LABEL_REF:
17321 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
17323 case CONST_DOUBLE:
17324 if (mode != VOIDmode)
17325 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
17326 flen = 2;
17327 break;
17329 case CODE_LABEL:
17330 fidx = 3;
17331 break;
17333 default:
17334 break;
17337 for (; fidx < flen; fidx++)
17338 switch (format[fidx])
17340 case 's':
17342 unsigned i, len;
17343 const char *str = XSTR (k, fidx);
17344 len = strlen (str);
17345 result = result * 613 + len;
17346 for (i = 0; i < len; i++)
17347 result = result * 613 + (unsigned) str[i];
17348 break;
17350 case 'u':
17351 case 'e':
17352 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
17353 break;
17354 case 'i':
17355 case 'n':
17356 result = result * 613 + (unsigned) XINT (k, fidx);
17357 break;
17358 case 'w':
17359 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
17360 result = result * 613 + (unsigned) XWINT (k, fidx);
17361 else
17363 size_t i;
17364 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
17365 result = result * 613 + (unsigned) (XWINT (k, fidx)
17366 >> CHAR_BIT * i);
17368 break;
17369 case '0':
17370 break;
17371 default:
17372 gcc_unreachable ();
17375 return result;
17378 static unsigned
17379 toc_hash_function (const void *hash_entry)
17381 const struct toc_hash_struct *thc =
17382 (const struct toc_hash_struct *) hash_entry;
17383 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
17386 /* Compare H1 and H2 for equivalence. */
17388 static int
17389 toc_hash_eq (const void *h1, const void *h2)
17391 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
17392 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
17394 if (((const struct toc_hash_struct *) h1)->key_mode
17395 != ((const struct toc_hash_struct *) h2)->key_mode)
17396 return 0;
17398 return rtx_equal_p (r1, r2);
17401 /* These are the names given by the C++ front-end to vtables, and
17402 vtable-like objects. Ideally, this logic should not be here;
17403 instead, there should be some programmatic way of inquiring as
17404 to whether or not an object is a vtable. */
17406 #define VTABLE_NAME_P(NAME) \
17407 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
17408 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
17409 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
17410 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
17411 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
17413 void
17414 rs6000_output_symbol_ref (FILE *file, rtx x)
17416 /* Currently C++ toc references to vtables can be emitted before it
17417 is decided whether the vtable is public or private. If this is
17418 the case, then the linker will eventually complain that there is
17419 a reference to an unknown section. Thus, for vtables only,
17420 we emit the TOC reference to reference the symbol and not the
17421 section. */
17422 const char *name = XSTR (x, 0);
17424 if (VTABLE_NAME_P (name))
17426 RS6000_OUTPUT_BASENAME (file, name);
17428 else
17429 assemble_name (file, name);
17432 /* Output a TOC entry. We derive the entry name from what is being
17433 written. */
17435 void
17436 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
17438 char buf[256];
17439 const char *name = buf;
17440 const char *real_name;
17441 rtx base = x;
17442 HOST_WIDE_INT offset = 0;
17444 gcc_assert (!TARGET_NO_TOC);
17446 /* When the linker won't eliminate them, don't output duplicate
17447 TOC entries (this happens on AIX if there is any kind of TOC,
17448 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
17449 CODE_LABELs. */
17450 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
17452 struct toc_hash_struct *h;
17453 void * * found;
17455 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
17456 time because GGC is not initialized at that point. */
17457 if (toc_hash_table == NULL)
17458 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
17459 toc_hash_eq, NULL);
17461 h = ggc_alloc (sizeof (*h));
17462 h->key = x;
17463 h->key_mode = mode;
17464 h->labelno = labelno;
17466 found = htab_find_slot (toc_hash_table, h, 1);
17467 if (*found == NULL)
17468 *found = h;
17469 else /* This is indeed a duplicate.
17470 Set this label equal to that label. */
17472 fputs ("\t.set ", file);
17473 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
17474 fprintf (file, "%d,", labelno);
17475 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
17476 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
17477 found)->labelno));
17478 return;
17482 /* If we're going to put a double constant in the TOC, make sure it's
17483 aligned properly when strict alignment is on. */
17484 if (GET_CODE (x) == CONST_DOUBLE
17485 && STRICT_ALIGNMENT
17486 && GET_MODE_BITSIZE (mode) >= 64
17487 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
17488 ASM_OUTPUT_ALIGN (file, 3);
17491 (*targetm.asm_out.internal_label) (file, "LC", labelno);
17493 /* Handle FP constants specially. Note that if we have a minimal
17494 TOC, things we put here aren't actually in the TOC, so we can allow
17495 FP constants. */
17496 if (GET_CODE (x) == CONST_DOUBLE &&
17497 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
17499 REAL_VALUE_TYPE rv;
17500 long k[4];
17502 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
17503 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17504 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
17505 else
17506 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
17508 if (TARGET_64BIT)
17510 if (TARGET_MINIMAL_TOC)
17511 fputs (DOUBLE_INT_ASM_OP, file);
17512 else
17513 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17514 k[0] & 0xffffffff, k[1] & 0xffffffff,
17515 k[2] & 0xffffffff, k[3] & 0xffffffff);
17516 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
17517 k[0] & 0xffffffff, k[1] & 0xffffffff,
17518 k[2] & 0xffffffff, k[3] & 0xffffffff);
17519 return;
17521 else
17523 if (TARGET_MINIMAL_TOC)
17524 fputs ("\t.long ", file);
17525 else
17526 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17527 k[0] & 0xffffffff, k[1] & 0xffffffff,
17528 k[2] & 0xffffffff, k[3] & 0xffffffff);
17529 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
17530 k[0] & 0xffffffff, k[1] & 0xffffffff,
17531 k[2] & 0xffffffff, k[3] & 0xffffffff);
17532 return;
17535 else if (GET_CODE (x) == CONST_DOUBLE &&
17536 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
17538 REAL_VALUE_TYPE rv;
17539 long k[2];
17541 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
17543 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17544 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
17545 else
17546 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
17548 if (TARGET_64BIT)
17550 if (TARGET_MINIMAL_TOC)
17551 fputs (DOUBLE_INT_ASM_OP, file);
17552 else
17553 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
17554 k[0] & 0xffffffff, k[1] & 0xffffffff);
17555 fprintf (file, "0x%lx%08lx\n",
17556 k[0] & 0xffffffff, k[1] & 0xffffffff);
17557 return;
17559 else
17561 if (TARGET_MINIMAL_TOC)
17562 fputs ("\t.long ", file);
17563 else
17564 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
17565 k[0] & 0xffffffff, k[1] & 0xffffffff);
17566 fprintf (file, "0x%lx,0x%lx\n",
17567 k[0] & 0xffffffff, k[1] & 0xffffffff);
17568 return;
17571 else if (GET_CODE (x) == CONST_DOUBLE &&
17572 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
17574 REAL_VALUE_TYPE rv;
17575 long l;
17577 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
17578 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17579 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
17580 else
17581 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
17583 if (TARGET_64BIT)
17585 if (TARGET_MINIMAL_TOC)
17586 fputs (DOUBLE_INT_ASM_OP, file);
17587 else
17588 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
17589 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
17590 return;
17592 else
17594 if (TARGET_MINIMAL_TOC)
17595 fputs ("\t.long ", file);
17596 else
17597 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
17598 fprintf (file, "0x%lx\n", l & 0xffffffff);
17599 return;
17602 else if (GET_MODE (x) == VOIDmode
17603 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
17605 unsigned HOST_WIDE_INT low;
17606 HOST_WIDE_INT high;
17608 if (GET_CODE (x) == CONST_DOUBLE)
17610 low = CONST_DOUBLE_LOW (x);
17611 high = CONST_DOUBLE_HIGH (x);
17613 else
17614 #if HOST_BITS_PER_WIDE_INT == 32
17616 low = INTVAL (x);
17617 high = (low & 0x80000000) ? ~0 : 0;
17619 #else
17621 low = INTVAL (x) & 0xffffffff;
17622 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
17624 #endif
17626 /* TOC entries are always Pmode-sized, but since this
17627 is a bigendian machine then if we're putting smaller
17628 integer constants in the TOC we have to pad them.
17629 (This is still a win over putting the constants in
17630 a separate constant pool, because then we'd have
17631 to have both a TOC entry _and_ the actual constant.)
17633 For a 32-bit target, CONST_INT values are loaded and shifted
17634 entirely within `low' and can be stored in one TOC entry. */
17636 /* It would be easy to make this work, but it doesn't now. */
17637 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
17639 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
17641 #if HOST_BITS_PER_WIDE_INT == 32
17642 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
17643 POINTER_SIZE, &low, &high, 0);
17644 #else
17645 low |= high << 32;
17646 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
17647 high = (HOST_WIDE_INT) low >> 32;
17648 low &= 0xffffffff;
17649 #endif
17652 if (TARGET_64BIT)
17654 if (TARGET_MINIMAL_TOC)
17655 fputs (DOUBLE_INT_ASM_OP, file);
17656 else
17657 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
17658 (long) high & 0xffffffff, (long) low & 0xffffffff);
17659 fprintf (file, "0x%lx%08lx\n",
17660 (long) high & 0xffffffff, (long) low & 0xffffffff);
17661 return;
17663 else
17665 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
17667 if (TARGET_MINIMAL_TOC)
17668 fputs ("\t.long ", file);
17669 else
17670 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
17671 (long) high & 0xffffffff, (long) low & 0xffffffff);
17672 fprintf (file, "0x%lx,0x%lx\n",
17673 (long) high & 0xffffffff, (long) low & 0xffffffff);
17675 else
17677 if (TARGET_MINIMAL_TOC)
17678 fputs ("\t.long ", file);
17679 else
17680 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
17681 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
17683 return;
17687 if (GET_CODE (x) == CONST)
17689 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
17691 base = XEXP (XEXP (x, 0), 0);
17692 offset = INTVAL (XEXP (XEXP (x, 0), 1));
17695 switch (GET_CODE (base))
17697 case SYMBOL_REF:
17698 name = XSTR (base, 0);
17699 break;
17701 case LABEL_REF:
17702 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
17703 CODE_LABEL_NUMBER (XEXP (base, 0)));
17704 break;
17706 case CODE_LABEL:
17707 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
17708 break;
17710 default:
17711 gcc_unreachable ();
17714 real_name = (*targetm.strip_name_encoding) (name);
17715 if (TARGET_MINIMAL_TOC)
17716 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
17717 else
17719 fprintf (file, "\t.tc %s", real_name);
17721 if (offset < 0)
17722 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
17723 else if (offset)
17724 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
17726 fputs ("[TC],", file);
17729 /* Currently C++ toc references to vtables can be emitted before it
17730 is decided whether the vtable is public or private. If this is
17731 the case, then the linker will eventually complain that there is
17732 a TOC reference to an unknown section. Thus, for vtables only,
17733 we emit the TOC reference to reference the symbol and not the
17734 section. */
17735 if (VTABLE_NAME_P (name))
17737 RS6000_OUTPUT_BASENAME (file, name);
17738 if (offset < 0)
17739 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
17740 else if (offset > 0)
17741 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
17743 else
17744 output_addr_const (file, x);
17745 putc ('\n', file);
17748 /* Output an assembler pseudo-op to write an ASCII string of N characters
17749 starting at P to FILE.
17751 On the RS/6000, we have to do this using the .byte operation and
17752 write out special characters outside the quoted string.
17753 Also, the assembler is broken; very long strings are truncated,
17754 so we must artificially break them up early. */
17756 void
17757 output_ascii (FILE *file, const char *p, int n)
17759 char c;
17760 int i, count_string;
17761 const char *for_string = "\t.byte \"";
17762 const char *for_decimal = "\t.byte ";
17763 const char *to_close = NULL;
17765 count_string = 0;
17766 for (i = 0; i < n; i++)
17768 c = *p++;
17769 if (c >= ' ' && c < 0177)
17771 if (for_string)
17772 fputs (for_string, file);
17773 putc (c, file);
17775 /* Write two quotes to get one. */
17776 if (c == '"')
17778 putc (c, file);
17779 ++count_string;
17782 for_string = NULL;
17783 for_decimal = "\"\n\t.byte ";
17784 to_close = "\"\n";
17785 ++count_string;
17787 if (count_string >= 512)
17789 fputs (to_close, file);
17791 for_string = "\t.byte \"";
17792 for_decimal = "\t.byte ";
17793 to_close = NULL;
17794 count_string = 0;
17797 else
17799 if (for_decimal)
17800 fputs (for_decimal, file);
17801 fprintf (file, "%d", c);
17803 for_string = "\n\t.byte \"";
17804 for_decimal = ", ";
17805 to_close = "\n";
17806 count_string = 0;
17810 /* Now close the string if we have written one. Then end the line. */
17811 if (to_close)
17812 fputs (to_close, file);
17815 /* Generate a unique section name for FILENAME for a section type
17816 represented by SECTION_DESC. Output goes into BUF.
17818 SECTION_DESC can be any string, as long as it is different for each
17819 possible section type.
17821 We name the section in the same manner as xlc. The name begins with an
17822 underscore followed by the filename (after stripping any leading directory
17823 names) with the last period replaced by the string SECTION_DESC. If
17824 FILENAME does not contain a period, SECTION_DESC is appended to the end of
17825 the name. */
17827 void
17828 rs6000_gen_section_name (char **buf, const char *filename,
17829 const char *section_desc)
17831 const char *q, *after_last_slash, *last_period = 0;
17832 char *p;
17833 int len;
17835 after_last_slash = filename;
17836 for (q = filename; *q; q++)
17838 if (*q == '/')
17839 after_last_slash = q + 1;
17840 else if (*q == '.')
17841 last_period = q;
17844 len = strlen (after_last_slash) + strlen (section_desc) + 2;
17845 *buf = (char *) xmalloc (len);
17847 p = *buf;
17848 *p++ = '_';
17850 for (q = after_last_slash; *q; q++)
17852 if (q == last_period)
17854 strcpy (p, section_desc);
17855 p += strlen (section_desc);
17856 break;
17859 else if (ISALNUM (*q))
17860 *p++ = *q;
17863 if (last_period == 0)
17864 strcpy (p, section_desc);
17865 else
17866 *p = '\0';
17869 /* Emit profile function. */
17871 void
17872 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
17874 /* Non-standard profiling for kernels, which just saves LR then calls
17875 _mcount without worrying about arg saves. The idea is to change
17876 the function prologue as little as possible as it isn't easy to
17877 account for arg save/restore code added just for _mcount. */
17878 if (TARGET_PROFILE_KERNEL)
17879 return;
17881 if (DEFAULT_ABI == ABI_AIX)
17883 #ifndef NO_PROFILE_COUNTERS
17884 # define NO_PROFILE_COUNTERS 0
17885 #endif
17886 if (NO_PROFILE_COUNTERS)
17887 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
17888 else
17890 char buf[30];
17891 const char *label_name;
17892 rtx fun;
17894 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
17895 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
17896 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
17898 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
17899 fun, Pmode);
17902 else if (DEFAULT_ABI == ABI_DARWIN)
17904 const char *mcount_name = RS6000_MCOUNT;
17905 int caller_addr_regno = LR_REGNO;
17907 /* Be conservative and always set this, at least for now. */
17908 crtl->uses_pic_offset_table = 1;
17910 #if TARGET_MACHO
17911 /* For PIC code, set up a stub and collect the caller's address
17912 from r0, which is where the prologue puts it. */
17913 if (MACHOPIC_INDIRECT
17914 && crtl->uses_pic_offset_table)
17915 caller_addr_regno = 0;
17916 #endif
17917 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
17918 0, VOIDmode, 1,
17919 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
17923 /* Write function profiler code. */
17925 void
17926 output_function_profiler (FILE *file, int labelno)
17928 char buf[100];
17930 switch (DEFAULT_ABI)
17932 default:
17933 gcc_unreachable ();
17935 case ABI_V4:
17936 if (!TARGET_32BIT)
17938 warning (0, "no profiling of 64-bit code for this ABI");
17939 return;
17941 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
17942 fprintf (file, "\tmflr %s\n", reg_names[0]);
17943 if (NO_PROFILE_COUNTERS)
17945 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17946 reg_names[0], reg_names[1]);
17948 else if (TARGET_SECURE_PLT && flag_pic)
17950 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
17951 reg_names[0], reg_names[1]);
17952 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
17953 asm_fprintf (file, "\t{cau|addis} %s,%s,",
17954 reg_names[12], reg_names[12]);
17955 assemble_name (file, buf);
17956 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
17957 assemble_name (file, buf);
17958 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
17960 else if (flag_pic == 1)
17962 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
17963 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17964 reg_names[0], reg_names[1]);
17965 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
17966 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
17967 assemble_name (file, buf);
17968 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
17970 else if (flag_pic > 1)
17972 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17973 reg_names[0], reg_names[1]);
17974 /* Now, we need to get the address of the label. */
17975 fputs ("\tbcl 20,31,1f\n\t.long ", file);
17976 assemble_name (file, buf);
17977 fputs ("-.\n1:", file);
17978 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
17979 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
17980 reg_names[0], reg_names[11]);
17981 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
17982 reg_names[0], reg_names[0], reg_names[11]);
17984 else
17986 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
17987 assemble_name (file, buf);
17988 fputs ("@ha\n", file);
17989 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17990 reg_names[0], reg_names[1]);
17991 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
17992 assemble_name (file, buf);
17993 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
17996 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
17997 fprintf (file, "\tbl %s%s\n",
17998 RS6000_MCOUNT, flag_pic ? "@plt" : "");
17999 break;
18001 case ABI_AIX:
18002 case ABI_DARWIN:
18003 if (!TARGET_PROFILE_KERNEL)
18005 /* Don't do anything, done in output_profile_hook (). */
18007 else
18009 gcc_assert (!TARGET_32BIT);
18011 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
18012 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
18014 if (cfun->static_chain_decl != NULL)
18016 asm_fprintf (file, "\tstd %s,24(%s)\n",
18017 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
18018 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
18019 asm_fprintf (file, "\tld %s,24(%s)\n",
18020 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
18022 else
18023 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
18025 break;
18031 /* The following variable value is the last issued insn. */
18033 static rtx last_scheduled_insn;
18035 /* The following variable helps to balance issuing of load and
18036 store instructions */
18038 static int load_store_pendulum;
18040 /* Power4 load update and store update instructions are cracked into a
18041 load or store and an integer insn which are executed in the same cycle.
18042 Branches have their own dispatch slot which does not count against the
18043 GCC issue rate, but it changes the program flow so there are no other
18044 instructions to issue in this cycle. */
18046 static int
18047 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
18048 int verbose ATTRIBUTE_UNUSED,
18049 rtx insn, int more)
18051 last_scheduled_insn = insn;
18052 if (GET_CODE (PATTERN (insn)) == USE
18053 || GET_CODE (PATTERN (insn)) == CLOBBER)
18055 cached_can_issue_more = more;
18056 return cached_can_issue_more;
18059 if (insn_terminates_group_p (insn, current_group))
18061 cached_can_issue_more = 0;
18062 return cached_can_issue_more;
18065 /* If no reservation, but reach here */
18066 if (recog_memoized (insn) < 0)
18067 return more;
18069 if (rs6000_sched_groups)
18071 if (is_microcoded_insn (insn))
18072 cached_can_issue_more = 0;
18073 else if (is_cracked_insn (insn))
18074 cached_can_issue_more = more > 2 ? more - 2 : 0;
18075 else
18076 cached_can_issue_more = more - 1;
18078 return cached_can_issue_more;
18081 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
18082 return 0;
18084 cached_can_issue_more = more - 1;
18085 return cached_can_issue_more;
18088 /* Adjust the cost of a scheduling dependency. Return the new cost of
18089 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
18091 static int
18092 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
18094 enum attr_type attr_type;
18096 if (! recog_memoized (insn))
18097 return 0;
18099 switch (REG_NOTE_KIND (link))
18101 case REG_DEP_TRUE:
18103 /* Data dependency; DEP_INSN writes a register that INSN reads
18104 some cycles later. */
18106 /* Separate a load from a narrower, dependent store. */
18107 if (rs6000_sched_groups
18108 && GET_CODE (PATTERN (insn)) == SET
18109 && GET_CODE (PATTERN (dep_insn)) == SET
18110 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
18111 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
18112 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
18113 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
18114 return cost + 14;
18116 attr_type = get_attr_type (insn);
18118 switch (attr_type)
18120 case TYPE_JMPREG:
18121 /* Tell the first scheduling pass about the latency between
18122 a mtctr and bctr (and mtlr and br/blr). The first
18123 scheduling pass will not know about this latency since
18124 the mtctr instruction, which has the latency associated
18125 to it, will be generated by reload. */
18126 return TARGET_POWER ? 5 : 4;
18127 case TYPE_BRANCH:
18128 /* Leave some extra cycles between a compare and its
18129 dependent branch, to inhibit expensive mispredicts. */
18130 if ((rs6000_cpu_attr == CPU_PPC603
18131 || rs6000_cpu_attr == CPU_PPC604
18132 || rs6000_cpu_attr == CPU_PPC604E
18133 || rs6000_cpu_attr == CPU_PPC620
18134 || rs6000_cpu_attr == CPU_PPC630
18135 || rs6000_cpu_attr == CPU_PPC750
18136 || rs6000_cpu_attr == CPU_PPC7400
18137 || rs6000_cpu_attr == CPU_PPC7450
18138 || rs6000_cpu_attr == CPU_POWER4
18139 || rs6000_cpu_attr == CPU_POWER5
18140 || rs6000_cpu_attr == CPU_CELL)
18141 && recog_memoized (dep_insn)
18142 && (INSN_CODE (dep_insn) >= 0))
18144 switch (get_attr_type (dep_insn))
18146 case TYPE_CMP:
18147 case TYPE_COMPARE:
18148 case TYPE_DELAYED_COMPARE:
18149 case TYPE_IMUL_COMPARE:
18150 case TYPE_LMUL_COMPARE:
18151 case TYPE_FPCOMPARE:
18152 case TYPE_CR_LOGICAL:
18153 case TYPE_DELAYED_CR:
18154 return cost + 2;
18155 default:
18156 break;
18158 break;
18160 case TYPE_STORE:
18161 case TYPE_STORE_U:
18162 case TYPE_STORE_UX:
18163 case TYPE_FPSTORE:
18164 case TYPE_FPSTORE_U:
18165 case TYPE_FPSTORE_UX:
18166 if ((rs6000_cpu == PROCESSOR_POWER6)
18167 && recog_memoized (dep_insn)
18168 && (INSN_CODE (dep_insn) >= 0))
18171 if (GET_CODE (PATTERN (insn)) != SET)
18172 /* If this happens, we have to extend this to schedule
18173 optimally. Return default for now. */
18174 return cost;
18176 /* Adjust the cost for the case where the value written
18177 by a fixed point operation is used as the address
18178 gen value on a store. */
18179 switch (get_attr_type (dep_insn))
18181 case TYPE_LOAD:
18182 case TYPE_LOAD_U:
18183 case TYPE_LOAD_UX:
18184 case TYPE_CNTLZ:
18186 if (! store_data_bypass_p (dep_insn, insn))
18187 return 4;
18188 break;
18190 case TYPE_LOAD_EXT:
18191 case TYPE_LOAD_EXT_U:
18192 case TYPE_LOAD_EXT_UX:
18193 case TYPE_VAR_SHIFT_ROTATE:
18194 case TYPE_VAR_DELAYED_COMPARE:
18196 if (! store_data_bypass_p (dep_insn, insn))
18197 return 6;
18198 break;
18200 case TYPE_INTEGER:
18201 case TYPE_COMPARE:
18202 case TYPE_FAST_COMPARE:
18203 case TYPE_EXTS:
18204 case TYPE_SHIFT:
18205 case TYPE_INSERT_WORD:
18206 case TYPE_INSERT_DWORD:
18207 case TYPE_FPLOAD_U:
18208 case TYPE_FPLOAD_UX:
18209 case TYPE_STORE_U:
18210 case TYPE_STORE_UX:
18211 case TYPE_FPSTORE_U:
18212 case TYPE_FPSTORE_UX:
18214 if (! store_data_bypass_p (dep_insn, insn))
18215 return 3;
18216 break;
18218 case TYPE_IMUL:
18219 case TYPE_IMUL2:
18220 case TYPE_IMUL3:
18221 case TYPE_LMUL:
18222 case TYPE_IMUL_COMPARE:
18223 case TYPE_LMUL_COMPARE:
18225 if (! store_data_bypass_p (dep_insn, insn))
18226 return 17;
18227 break;
18229 case TYPE_IDIV:
18231 if (! store_data_bypass_p (dep_insn, insn))
18232 return 45;
18233 break;
18235 case TYPE_LDIV:
18237 if (! store_data_bypass_p (dep_insn, insn))
18238 return 57;
18239 break;
18241 default:
18242 break;
18245 break;
18247 case TYPE_LOAD:
18248 case TYPE_LOAD_U:
18249 case TYPE_LOAD_UX:
18250 case TYPE_LOAD_EXT:
18251 case TYPE_LOAD_EXT_U:
18252 case TYPE_LOAD_EXT_UX:
18253 if ((rs6000_cpu == PROCESSOR_POWER6)
18254 && recog_memoized (dep_insn)
18255 && (INSN_CODE (dep_insn) >= 0))
18258 /* Adjust the cost for the case where the value written
18259 by a fixed point instruction is used within the address
18260 gen portion of a subsequent load(u)(x) */
18261 switch (get_attr_type (dep_insn))
18263 case TYPE_LOAD:
18264 case TYPE_LOAD_U:
18265 case TYPE_LOAD_UX:
18266 case TYPE_CNTLZ:
18268 if (set_to_load_agen (dep_insn, insn))
18269 return 4;
18270 break;
18272 case TYPE_LOAD_EXT:
18273 case TYPE_LOAD_EXT_U:
18274 case TYPE_LOAD_EXT_UX:
18275 case TYPE_VAR_SHIFT_ROTATE:
18276 case TYPE_VAR_DELAYED_COMPARE:
18278 if (set_to_load_agen (dep_insn, insn))
18279 return 6;
18280 break;
18282 case TYPE_INTEGER:
18283 case TYPE_COMPARE:
18284 case TYPE_FAST_COMPARE:
18285 case TYPE_EXTS:
18286 case TYPE_SHIFT:
18287 case TYPE_INSERT_WORD:
18288 case TYPE_INSERT_DWORD:
18289 case TYPE_FPLOAD_U:
18290 case TYPE_FPLOAD_UX:
18291 case TYPE_STORE_U:
18292 case TYPE_STORE_UX:
18293 case TYPE_FPSTORE_U:
18294 case TYPE_FPSTORE_UX:
18296 if (set_to_load_agen (dep_insn, insn))
18297 return 3;
18298 break;
18300 case TYPE_IMUL:
18301 case TYPE_IMUL2:
18302 case TYPE_IMUL3:
18303 case TYPE_LMUL:
18304 case TYPE_IMUL_COMPARE:
18305 case TYPE_LMUL_COMPARE:
18307 if (set_to_load_agen (dep_insn, insn))
18308 return 17;
18309 break;
18311 case TYPE_IDIV:
18313 if (set_to_load_agen (dep_insn, insn))
18314 return 45;
18315 break;
18317 case TYPE_LDIV:
18319 if (set_to_load_agen (dep_insn, insn))
18320 return 57;
18321 break;
18323 default:
18324 break;
18327 break;
18329 case TYPE_FPLOAD:
18330 if ((rs6000_cpu == PROCESSOR_POWER6)
18331 && recog_memoized (dep_insn)
18332 && (INSN_CODE (dep_insn) >= 0)
18333 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
18334 return 2;
18336 default:
18337 break;
18340 /* Fall out to return default cost. */
18342 break;
18344 case REG_DEP_OUTPUT:
18345 /* Output dependency; DEP_INSN writes a register that INSN writes some
18346 cycles later. */
18347 if ((rs6000_cpu == PROCESSOR_POWER6)
18348 && recog_memoized (dep_insn)
18349 && (INSN_CODE (dep_insn) >= 0))
18351 attr_type = get_attr_type (insn);
18353 switch (attr_type)
18355 case TYPE_FP:
18356 if (get_attr_type (dep_insn) == TYPE_FP)
18357 return 1;
18358 break;
18359 case TYPE_FPLOAD:
18360 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
18361 return 2;
18362 break;
18363 default:
18364 break;
18367 case REG_DEP_ANTI:
18368 /* Anti dependency; DEP_INSN reads a register that INSN writes some
18369 cycles later. */
18370 return 0;
18372 default:
18373 gcc_unreachable ();
18376 return cost;
18379 /* The function returns a true if INSN is microcoded.
18380 Return false otherwise. */
18382 static bool
18383 is_microcoded_insn (rtx insn)
18385 if (!insn || !INSN_P (insn)
18386 || GET_CODE (PATTERN (insn)) == USE
18387 || GET_CODE (PATTERN (insn)) == CLOBBER)
18388 return false;
18390 if (rs6000_cpu_attr == CPU_CELL)
18391 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
18393 if (rs6000_sched_groups)
18395 enum attr_type type = get_attr_type (insn);
18396 if (type == TYPE_LOAD_EXT_U
18397 || type == TYPE_LOAD_EXT_UX
18398 || type == TYPE_LOAD_UX
18399 || type == TYPE_STORE_UX
18400 || type == TYPE_MFCR)
18401 return true;
18404 return false;
18407 /* The function returns true if INSN is cracked into 2 instructions
18408 by the processor (and therefore occupies 2 issue slots). */
18410 static bool
18411 is_cracked_insn (rtx insn)
18413 if (!insn || !INSN_P (insn)
18414 || GET_CODE (PATTERN (insn)) == USE
18415 || GET_CODE (PATTERN (insn)) == CLOBBER)
18416 return false;
18418 if (rs6000_sched_groups)
18420 enum attr_type type = get_attr_type (insn);
18421 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
18422 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
18423 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
18424 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
18425 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
18426 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
18427 || type == TYPE_IDIV || type == TYPE_LDIV
18428 || type == TYPE_INSERT_WORD)
18429 return true;
18432 return false;
18435 /* The function returns true if INSN can be issued only from
18436 the branch slot. */
18438 static bool
18439 is_branch_slot_insn (rtx insn)
18441 if (!insn || !INSN_P (insn)
18442 || GET_CODE (PATTERN (insn)) == USE
18443 || GET_CODE (PATTERN (insn)) == CLOBBER)
18444 return false;
18446 if (rs6000_sched_groups)
18448 enum attr_type type = get_attr_type (insn);
18449 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
18450 return true;
18451 return false;
18454 return false;
18457 /* The function returns true if out_inst sets a value that is
18458 used in the address generation computation of in_insn */
18459 static bool
18460 set_to_load_agen (rtx out_insn, rtx in_insn)
18462 rtx out_set, in_set;
18464 /* For performance reasons, only handle the simple case where
18465 both loads are a single_set. */
18466 out_set = single_set (out_insn);
18467 if (out_set)
18469 in_set = single_set (in_insn);
18470 if (in_set)
18471 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
18474 return false;
18477 /* The function returns true if the target storage location of
18478 out_insn is adjacent to the target storage location of in_insn */
18479 /* Return 1 if memory locations are adjacent. */
18481 static bool
18482 adjacent_mem_locations (rtx insn1, rtx insn2)
18485 rtx a = get_store_dest (PATTERN (insn1));
18486 rtx b = get_store_dest (PATTERN (insn2));
18488 if ((GET_CODE (XEXP (a, 0)) == REG
18489 || (GET_CODE (XEXP (a, 0)) == PLUS
18490 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
18491 && (GET_CODE (XEXP (b, 0)) == REG
18492 || (GET_CODE (XEXP (b, 0)) == PLUS
18493 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
18495 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
18496 rtx reg0, reg1;
18498 if (GET_CODE (XEXP (a, 0)) == PLUS)
18500 reg0 = XEXP (XEXP (a, 0), 0);
18501 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
18503 else
18504 reg0 = XEXP (a, 0);
18506 if (GET_CODE (XEXP (b, 0)) == PLUS)
18508 reg1 = XEXP (XEXP (b, 0), 0);
18509 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
18511 else
18512 reg1 = XEXP (b, 0);
18514 val_diff = val1 - val0;
18516 return ((REGNO (reg0) == REGNO (reg1))
18517 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
18518 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
18521 return false;
18524 /* A C statement (sans semicolon) to update the integer scheduling
18525 priority INSN_PRIORITY (INSN). Increase the priority to execute the
18526 INSN earlier, reduce the priority to execute INSN later. Do not
18527 define this macro if you do not need to adjust the scheduling
18528 priorities of insns. */
18530 static int
18531 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
18533 /* On machines (like the 750) which have asymmetric integer units,
18534 where one integer unit can do multiply and divides and the other
18535 can't, reduce the priority of multiply/divide so it is scheduled
18536 before other integer operations. */
18538 #if 0
18539 if (! INSN_P (insn))
18540 return priority;
18542 if (GET_CODE (PATTERN (insn)) == USE)
18543 return priority;
18545 switch (rs6000_cpu_attr) {
18546 case CPU_PPC750:
18547 switch (get_attr_type (insn))
18549 default:
18550 break;
18552 case TYPE_IMUL:
18553 case TYPE_IDIV:
18554 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
18555 priority, priority);
18556 if (priority >= 0 && priority < 0x01000000)
18557 priority >>= 3;
18558 break;
18561 #endif
18563 if (insn_must_be_first_in_group (insn)
18564 && reload_completed
18565 && current_sched_info->sched_max_insns_priority
18566 && rs6000_sched_restricted_insns_priority)
18569 /* Prioritize insns that can be dispatched only in the first
18570 dispatch slot. */
18571 if (rs6000_sched_restricted_insns_priority == 1)
18572 /* Attach highest priority to insn. This means that in
18573 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
18574 precede 'priority' (critical path) considerations. */
18575 return current_sched_info->sched_max_insns_priority;
18576 else if (rs6000_sched_restricted_insns_priority == 2)
18577 /* Increase priority of insn by a minimal amount. This means that in
18578 haifa-sched.c:ready_sort(), only 'priority' (critical path)
18579 considerations precede dispatch-slot restriction considerations. */
18580 return (priority + 1);
18583 if (rs6000_cpu == PROCESSOR_POWER6
18584 && ((load_store_pendulum == -2 && is_load_insn (insn))
18585 || (load_store_pendulum == 2 && is_store_insn (insn))))
18586 /* Attach highest priority to insn if the scheduler has just issued two
18587 stores and this instruction is a load, or two loads and this instruction
18588 is a store. Power6 wants loads and stores scheduled alternately
18589 when possible */
18590 return current_sched_info->sched_max_insns_priority;
18592 return priority;
18595 /* Return true if the instruction is nonpipelined on the Cell. */
18596 static bool
18597 is_nonpipeline_insn (rtx insn)
18599 enum attr_type type;
18600 if (!insn || !INSN_P (insn)
18601 || GET_CODE (PATTERN (insn)) == USE
18602 || GET_CODE (PATTERN (insn)) == CLOBBER)
18603 return false;
18605 type = get_attr_type (insn);
18606 if (type == TYPE_IMUL
18607 || type == TYPE_IMUL2
18608 || type == TYPE_IMUL3
18609 || type == TYPE_LMUL
18610 || type == TYPE_IDIV
18611 || type == TYPE_LDIV
18612 || type == TYPE_SDIV
18613 || type == TYPE_DDIV
18614 || type == TYPE_SSQRT
18615 || type == TYPE_DSQRT
18616 || type == TYPE_MFCR
18617 || type == TYPE_MFCRF
18618 || type == TYPE_MFJMPR)
18620 return true;
18622 return false;
18626 /* Return how many instructions the machine can issue per cycle. */
18628 static int
18629 rs6000_issue_rate (void)
18631 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
18632 if (!reload_completed)
18633 return 1;
18635 switch (rs6000_cpu_attr) {
18636 case CPU_RIOS1: /* ? */
18637 case CPU_RS64A:
18638 case CPU_PPC601: /* ? */
18639 case CPU_PPC7450:
18640 return 3;
18641 case CPU_PPC440:
18642 case CPU_PPC603:
18643 case CPU_PPC750:
18644 case CPU_PPC7400:
18645 case CPU_PPC8540:
18646 case CPU_CELL:
18647 case CPU_PPCE300C2:
18648 case CPU_PPCE300C3:
18649 return 2;
18650 case CPU_RIOS2:
18651 case CPU_PPC604:
18652 case CPU_PPC604E:
18653 case CPU_PPC620:
18654 case CPU_PPC630:
18655 return 4;
18656 case CPU_POWER4:
18657 case CPU_POWER5:
18658 case CPU_POWER6:
18659 return 5;
18660 default:
18661 return 1;
18665 /* Return how many instructions to look ahead for better insn
18666 scheduling. */
18668 static int
18669 rs6000_use_sched_lookahead (void)
18671 if (rs6000_cpu_attr == CPU_PPC8540)
18672 return 4;
18673 if (rs6000_cpu_attr == CPU_CELL)
18674 return (reload_completed ? 8 : 0);
18675 return 0;
18678 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
18679 static int
18680 rs6000_use_sched_lookahead_guard (rtx insn)
18682 if (rs6000_cpu_attr != CPU_CELL)
18683 return 1;
18685 if (insn == NULL_RTX || !INSN_P (insn))
18686 abort ();
18688 if (!reload_completed
18689 || is_nonpipeline_insn (insn)
18690 || is_microcoded_insn (insn))
18691 return 0;
18693 return 1;
18696 /* Determine is PAT refers to memory. */
18698 static bool
18699 is_mem_ref (rtx pat)
18701 const char * fmt;
18702 int i, j;
18703 bool ret = false;
18705 /* stack_tie does not produce any real memory traffic. */
18706 if (GET_CODE (pat) == UNSPEC
18707 && XINT (pat, 1) == UNSPEC_TIE)
18708 return false;
18710 if (GET_CODE (pat) == MEM)
18711 return true;
18713 /* Recursively process the pattern. */
18714 fmt = GET_RTX_FORMAT (GET_CODE (pat));
18716 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
18718 if (fmt[i] == 'e')
18719 ret |= is_mem_ref (XEXP (pat, i));
18720 else if (fmt[i] == 'E')
18721 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
18722 ret |= is_mem_ref (XVECEXP (pat, i, j));
18725 return ret;
18728 /* Determine if PAT is a PATTERN of a load insn. */
18730 static bool
18731 is_load_insn1 (rtx pat)
18733 if (!pat || pat == NULL_RTX)
18734 return false;
18736 if (GET_CODE (pat) == SET)
18737 return is_mem_ref (SET_SRC (pat));
18739 if (GET_CODE (pat) == PARALLEL)
18741 int i;
18743 for (i = 0; i < XVECLEN (pat, 0); i++)
18744 if (is_load_insn1 (XVECEXP (pat, 0, i)))
18745 return true;
18748 return false;
18751 /* Determine if INSN loads from memory. */
18753 static bool
18754 is_load_insn (rtx insn)
18756 if (!insn || !INSN_P (insn))
18757 return false;
18759 if (GET_CODE (insn) == CALL_INSN)
18760 return false;
18762 return is_load_insn1 (PATTERN (insn));
18765 /* Determine if PAT is a PATTERN of a store insn. */
18767 static bool
18768 is_store_insn1 (rtx pat)
18770 if (!pat || pat == NULL_RTX)
18771 return false;
18773 if (GET_CODE (pat) == SET)
18774 return is_mem_ref (SET_DEST (pat));
18776 if (GET_CODE (pat) == PARALLEL)
18778 int i;
18780 for (i = 0; i < XVECLEN (pat, 0); i++)
18781 if (is_store_insn1 (XVECEXP (pat, 0, i)))
18782 return true;
18785 return false;
18788 /* Determine if INSN stores to memory. */
18790 static bool
18791 is_store_insn (rtx insn)
18793 if (!insn || !INSN_P (insn))
18794 return false;
18796 return is_store_insn1 (PATTERN (insn));
18799 /* Return the dest of a store insn. */
18801 static rtx
18802 get_store_dest (rtx pat)
18804 gcc_assert (is_store_insn1 (pat));
18806 if (GET_CODE (pat) == SET)
18807 return SET_DEST (pat);
18808 else if (GET_CODE (pat) == PARALLEL)
18810 int i;
18812 for (i = 0; i < XVECLEN (pat, 0); i++)
18814 rtx inner_pat = XVECEXP (pat, 0, i);
18815 if (GET_CODE (inner_pat) == SET
18816 && is_mem_ref (SET_DEST (inner_pat)))
18817 return inner_pat;
18820 /* We shouldn't get here, because we should have either a simple
18821 store insn or a store with update which are covered above. */
18822 gcc_unreachable();
18825 /* Returns whether the dependence between INSN and NEXT is considered
18826 costly by the given target. */
18828 static bool
18829 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
18831 rtx insn;
18832 rtx next;
18834 /* If the flag is not enabled - no dependence is considered costly;
18835 allow all dependent insns in the same group.
18836 This is the most aggressive option. */
18837 if (rs6000_sched_costly_dep == no_dep_costly)
18838 return false;
18840 /* If the flag is set to 1 - a dependence is always considered costly;
18841 do not allow dependent instructions in the same group.
18842 This is the most conservative option. */
18843 if (rs6000_sched_costly_dep == all_deps_costly)
18844 return true;
18846 insn = DEP_PRO (dep);
18847 next = DEP_CON (dep);
18849 if (rs6000_sched_costly_dep == store_to_load_dep_costly
18850 && is_load_insn (next)
18851 && is_store_insn (insn))
18852 /* Prevent load after store in the same group. */
18853 return true;
18855 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
18856 && is_load_insn (next)
18857 && is_store_insn (insn)
18858 && DEP_TYPE (dep) == REG_DEP_TRUE)
18859 /* Prevent load after store in the same group if it is a true
18860 dependence. */
18861 return true;
18863 /* The flag is set to X; dependences with latency >= X are considered costly,
18864 and will not be scheduled in the same group. */
18865 if (rs6000_sched_costly_dep <= max_dep_latency
18866 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
18867 return true;
18869 return false;
18872 /* Return the next insn after INSN that is found before TAIL is reached,
18873 skipping any "non-active" insns - insns that will not actually occupy
18874 an issue slot. Return NULL_RTX if such an insn is not found. */
18876 static rtx
18877 get_next_active_insn (rtx insn, rtx tail)
18879 if (insn == NULL_RTX || insn == tail)
18880 return NULL_RTX;
18882 while (1)
18884 insn = NEXT_INSN (insn);
18885 if (insn == NULL_RTX || insn == tail)
18886 return NULL_RTX;
18888 if (CALL_P (insn)
18889 || JUMP_P (insn)
18890 || (NONJUMP_INSN_P (insn)
18891 && GET_CODE (PATTERN (insn)) != USE
18892 && GET_CODE (PATTERN (insn)) != CLOBBER
18893 && INSN_CODE (insn) != CODE_FOR_stack_tie))
18894 break;
18896 return insn;
18899 /* We are about to begin issuing insns for this clock cycle. */
18901 static int
18902 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
18903 rtx *ready ATTRIBUTE_UNUSED,
18904 int *pn_ready ATTRIBUTE_UNUSED,
18905 int clock_var ATTRIBUTE_UNUSED)
18907 int n_ready = *pn_ready;
18909 if (sched_verbose)
18910 fprintf (dump, "// rs6000_sched_reorder :\n");
18912 /* Reorder the ready list, if the second to last ready insn
18913 is a nonepipeline insn. */
18914 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
18916 if (is_nonpipeline_insn (ready[n_ready - 1])
18917 && (recog_memoized (ready[n_ready - 2]) > 0))
18918 /* Simply swap first two insns. */
18920 rtx tmp = ready[n_ready - 1];
18921 ready[n_ready - 1] = ready[n_ready - 2];
18922 ready[n_ready - 2] = tmp;
18926 if (rs6000_cpu == PROCESSOR_POWER6)
18927 load_store_pendulum = 0;
18929 return rs6000_issue_rate ();
18932 /* Like rs6000_sched_reorder, but called after issuing each insn. */
18934 static int
18935 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
18936 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
18938 if (sched_verbose)
18939 fprintf (dump, "// rs6000_sched_reorder2 :\n");
18941 /* For Power6, we need to handle some special cases to try and keep the
18942 store queue from overflowing and triggering expensive flushes.
18944 This code monitors how load and store instructions are being issued
18945 and skews the ready list one way or the other to increase the likelihood
18946 that a desired instruction is issued at the proper time.
18948 A couple of things are done. First, we maintain a "load_store_pendulum"
18949 to track the current state of load/store issue.
18951 - If the pendulum is at zero, then no loads or stores have been
18952 issued in the current cycle so we do nothing.
18954 - If the pendulum is 1, then a single load has been issued in this
18955 cycle and we attempt to locate another load in the ready list to
18956 issue with it.
18958 - If the pendulum is -2, then two stores have already been
18959 issued in this cycle, so we increase the priority of the first load
18960 in the ready list to increase it's likelihood of being chosen first
18961 in the next cycle.
18963 - If the pendulum is -1, then a single store has been issued in this
18964 cycle and we attempt to locate another store in the ready list to
18965 issue with it, preferring a store to an adjacent memory location to
18966 facilitate store pairing in the store queue.
18968 - If the pendulum is 2, then two loads have already been
18969 issued in this cycle, so we increase the priority of the first store
18970 in the ready list to increase it's likelihood of being chosen first
18971 in the next cycle.
18973 - If the pendulum < -2 or > 2, then do nothing.
18975 Note: This code covers the most common scenarios. There exist non
18976 load/store instructions which make use of the LSU and which
18977 would need to be accounted for to strictly model the behavior
18978 of the machine. Those instructions are currently unaccounted
18979 for to help minimize compile time overhead of this code.
18981 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
18983 int pos;
18984 int i;
18985 rtx tmp;
18987 if (is_store_insn (last_scheduled_insn))
18988 /* Issuing a store, swing the load_store_pendulum to the left */
18989 load_store_pendulum--;
18990 else if (is_load_insn (last_scheduled_insn))
18991 /* Issuing a load, swing the load_store_pendulum to the right */
18992 load_store_pendulum++;
18993 else
18994 return cached_can_issue_more;
18996 /* If the pendulum is balanced, or there is only one instruction on
18997 the ready list, then all is well, so return. */
18998 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
18999 return cached_can_issue_more;
19001 if (load_store_pendulum == 1)
19003 /* A load has been issued in this cycle. Scan the ready list
19004 for another load to issue with it */
19005 pos = *pn_ready-1;
19007 while (pos >= 0)
19009 if (is_load_insn (ready[pos]))
19011 /* Found a load. Move it to the head of the ready list,
19012 and adjust it's priority so that it is more likely to
19013 stay there */
19014 tmp = ready[pos];
19015 for (i=pos; i<*pn_ready-1; i++)
19016 ready[i] = ready[i + 1];
19017 ready[*pn_ready-1] = tmp;
19018 if INSN_PRIORITY_KNOWN (tmp)
19019 INSN_PRIORITY (tmp)++;
19020 break;
19022 pos--;
19025 else if (load_store_pendulum == -2)
19027 /* Two stores have been issued in this cycle. Increase the
19028 priority of the first load in the ready list to favor it for
19029 issuing in the next cycle. */
19030 pos = *pn_ready-1;
19032 while (pos >= 0)
19034 if (is_load_insn (ready[pos])
19035 && INSN_PRIORITY_KNOWN (ready[pos]))
19037 INSN_PRIORITY (ready[pos])++;
19039 /* Adjust the pendulum to account for the fact that a load
19040 was found and increased in priority. This is to prevent
19041 increasing the priority of multiple loads */
19042 load_store_pendulum--;
19044 break;
19046 pos--;
19049 else if (load_store_pendulum == -1)
19051 /* A store has been issued in this cycle. Scan the ready list for
19052 another store to issue with it, preferring a store to an adjacent
19053 memory location */
19054 int first_store_pos = -1;
19056 pos = *pn_ready-1;
19058 while (pos >= 0)
19060 if (is_store_insn (ready[pos]))
19062 /* Maintain the index of the first store found on the
19063 list */
19064 if (first_store_pos == -1)
19065 first_store_pos = pos;
19067 if (is_store_insn (last_scheduled_insn)
19068 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
19070 /* Found an adjacent store. Move it to the head of the
19071 ready list, and adjust it's priority so that it is
19072 more likely to stay there */
19073 tmp = ready[pos];
19074 for (i=pos; i<*pn_ready-1; i++)
19075 ready[i] = ready[i + 1];
19076 ready[*pn_ready-1] = tmp;
19077 if INSN_PRIORITY_KNOWN (tmp)
19078 INSN_PRIORITY (tmp)++;
19079 first_store_pos = -1;
19081 break;
19084 pos--;
19087 if (first_store_pos >= 0)
19089 /* An adjacent store wasn't found, but a non-adjacent store was,
19090 so move the non-adjacent store to the front of the ready
19091 list, and adjust its priority so that it is more likely to
19092 stay there. */
19093 tmp = ready[first_store_pos];
19094 for (i=first_store_pos; i<*pn_ready-1; i++)
19095 ready[i] = ready[i + 1];
19096 ready[*pn_ready-1] = tmp;
19097 if INSN_PRIORITY_KNOWN (tmp)
19098 INSN_PRIORITY (tmp)++;
19101 else if (load_store_pendulum == 2)
19103 /* Two loads have been issued in this cycle. Increase the priority
19104 of the first store in the ready list to favor it for issuing in
19105 the next cycle. */
19106 pos = *pn_ready-1;
19108 while (pos >= 0)
19110 if (is_store_insn (ready[pos])
19111 && INSN_PRIORITY_KNOWN (ready[pos]))
19113 INSN_PRIORITY (ready[pos])++;
19115 /* Adjust the pendulum to account for the fact that a store
19116 was found and increased in priority. This is to prevent
19117 increasing the priority of multiple stores */
19118 load_store_pendulum++;
19120 break;
19122 pos--;
19127 return cached_can_issue_more;
19130 /* Return whether the presence of INSN causes a dispatch group termination
19131 of group WHICH_GROUP.
19133 If WHICH_GROUP == current_group, this function will return true if INSN
19134 causes the termination of the current group (i.e, the dispatch group to
19135 which INSN belongs). This means that INSN will be the last insn in the
19136 group it belongs to.
19138 If WHICH_GROUP == previous_group, this function will return true if INSN
19139 causes the termination of the previous group (i.e, the dispatch group that
19140 precedes the group to which INSN belongs). This means that INSN will be
19141 the first insn in the group it belongs to). */
19143 static bool
19144 insn_terminates_group_p (rtx insn, enum group_termination which_group)
19146 bool first, last;
19148 if (! insn)
19149 return false;
19151 first = insn_must_be_first_in_group (insn);
19152 last = insn_must_be_last_in_group (insn);
19154 if (first && last)
19155 return true;
19157 if (which_group == current_group)
19158 return last;
19159 else if (which_group == previous_group)
19160 return first;
19162 return false;
19166 static bool
19167 insn_must_be_first_in_group (rtx insn)
19169 enum attr_type type;
19171 if (!insn
19172 || insn == NULL_RTX
19173 || GET_CODE (insn) == NOTE
19174 || GET_CODE (PATTERN (insn)) == USE
19175 || GET_CODE (PATTERN (insn)) == CLOBBER)
19176 return false;
19178 switch (rs6000_cpu)
19180 case PROCESSOR_POWER5:
19181 if (is_cracked_insn (insn))
19182 return true;
19183 case PROCESSOR_POWER4:
19184 if (is_microcoded_insn (insn))
19185 return true;
19187 if (!rs6000_sched_groups)
19188 return false;
19190 type = get_attr_type (insn);
19192 switch (type)
19194 case TYPE_MFCR:
19195 case TYPE_MFCRF:
19196 case TYPE_MTCR:
19197 case TYPE_DELAYED_CR:
19198 case TYPE_CR_LOGICAL:
19199 case TYPE_MTJMPR:
19200 case TYPE_MFJMPR:
19201 case TYPE_IDIV:
19202 case TYPE_LDIV:
19203 case TYPE_LOAD_L:
19204 case TYPE_STORE_C:
19205 case TYPE_ISYNC:
19206 case TYPE_SYNC:
19207 return true;
19208 default:
19209 break;
19211 break;
19212 case PROCESSOR_POWER6:
19213 type = get_attr_type (insn);
19215 switch (type)
19217 case TYPE_INSERT_DWORD:
19218 case TYPE_EXTS:
19219 case TYPE_CNTLZ:
19220 case TYPE_SHIFT:
19221 case TYPE_VAR_SHIFT_ROTATE:
19222 case TYPE_TRAP:
19223 case TYPE_IMUL:
19224 case TYPE_IMUL2:
19225 case TYPE_IMUL3:
19226 case TYPE_LMUL:
19227 case TYPE_IDIV:
19228 case TYPE_INSERT_WORD:
19229 case TYPE_DELAYED_COMPARE:
19230 case TYPE_IMUL_COMPARE:
19231 case TYPE_LMUL_COMPARE:
19232 case TYPE_FPCOMPARE:
19233 case TYPE_MFCR:
19234 case TYPE_MTCR:
19235 case TYPE_MFJMPR:
19236 case TYPE_MTJMPR:
19237 case TYPE_ISYNC:
19238 case TYPE_SYNC:
19239 case TYPE_LOAD_L:
19240 case TYPE_STORE_C:
19241 case TYPE_LOAD_U:
19242 case TYPE_LOAD_UX:
19243 case TYPE_LOAD_EXT_UX:
19244 case TYPE_STORE_U:
19245 case TYPE_STORE_UX:
19246 case TYPE_FPLOAD_U:
19247 case TYPE_FPLOAD_UX:
19248 case TYPE_FPSTORE_U:
19249 case TYPE_FPSTORE_UX:
19250 return true;
19251 default:
19252 break;
19254 break;
19255 default:
19256 break;
19259 return false;
19262 static bool
19263 insn_must_be_last_in_group (rtx insn)
19265 enum attr_type type;
19267 if (!insn
19268 || insn == NULL_RTX
19269 || GET_CODE (insn) == NOTE
19270 || GET_CODE (PATTERN (insn)) == USE
19271 || GET_CODE (PATTERN (insn)) == CLOBBER)
19272 return false;
19274 switch (rs6000_cpu) {
19275 case PROCESSOR_POWER4:
19276 case PROCESSOR_POWER5:
19277 if (is_microcoded_insn (insn))
19278 return true;
19280 if (is_branch_slot_insn (insn))
19281 return true;
19283 break;
19284 case PROCESSOR_POWER6:
19285 type = get_attr_type (insn);
19287 switch (type)
19289 case TYPE_EXTS:
19290 case TYPE_CNTLZ:
19291 case TYPE_SHIFT:
19292 case TYPE_VAR_SHIFT_ROTATE:
19293 case TYPE_TRAP:
19294 case TYPE_IMUL:
19295 case TYPE_IMUL2:
19296 case TYPE_IMUL3:
19297 case TYPE_LMUL:
19298 case TYPE_IDIV:
19299 case TYPE_DELAYED_COMPARE:
19300 case TYPE_IMUL_COMPARE:
19301 case TYPE_LMUL_COMPARE:
19302 case TYPE_FPCOMPARE:
19303 case TYPE_MFCR:
19304 case TYPE_MTCR:
19305 case TYPE_MFJMPR:
19306 case TYPE_MTJMPR:
19307 case TYPE_ISYNC:
19308 case TYPE_SYNC:
19309 case TYPE_LOAD_L:
19310 case TYPE_STORE_C:
19311 return true;
19312 default:
19313 break;
19315 break;
19316 default:
19317 break;
19320 return false;
19323 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
19324 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
19326 static bool
19327 is_costly_group (rtx *group_insns, rtx next_insn)
19329 int i;
19330 int issue_rate = rs6000_issue_rate ();
19332 for (i = 0; i < issue_rate; i++)
19334 sd_iterator_def sd_it;
19335 dep_t dep;
19336 rtx insn = group_insns[i];
19338 if (!insn)
19339 continue;
19341 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
19343 rtx next = DEP_CON (dep);
19345 if (next == next_insn
19346 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
19347 return true;
19351 return false;
19354 /* Utility of the function redefine_groups.
19355 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
19356 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
19357 to keep it "far" (in a separate group) from GROUP_INSNS, following
19358 one of the following schemes, depending on the value of the flag
19359 -minsert_sched_nops = X:
19360 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
19361 in order to force NEXT_INSN into a separate group.
19362 (2) X < sched_finish_regroup_exact: insert exactly X nops.
19363 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
19364 insertion (has a group just ended, how many vacant issue slots remain in the
19365 last group, and how many dispatch groups were encountered so far). */
19367 static int
19368 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
19369 rtx next_insn, bool *group_end, int can_issue_more,
19370 int *group_count)
19372 rtx nop;
19373 bool force;
19374 int issue_rate = rs6000_issue_rate ();
19375 bool end = *group_end;
19376 int i;
19378 if (next_insn == NULL_RTX)
19379 return can_issue_more;
19381 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
19382 return can_issue_more;
19384 force = is_costly_group (group_insns, next_insn);
19385 if (!force)
19386 return can_issue_more;
19388 if (sched_verbose > 6)
19389 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
19390 *group_count ,can_issue_more);
19392 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
19394 if (*group_end)
19395 can_issue_more = 0;
19397 /* Since only a branch can be issued in the last issue_slot, it is
19398 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
19399 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
19400 in this case the last nop will start a new group and the branch
19401 will be forced to the new group. */
19402 if (can_issue_more && !is_branch_slot_insn (next_insn))
19403 can_issue_more--;
19405 while (can_issue_more > 0)
19407 nop = gen_nop ();
19408 emit_insn_before (nop, next_insn);
19409 can_issue_more--;
19412 *group_end = true;
19413 return 0;
19416 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
19418 int n_nops = rs6000_sched_insert_nops;
19420 /* Nops can't be issued from the branch slot, so the effective
19421 issue_rate for nops is 'issue_rate - 1'. */
19422 if (can_issue_more == 0)
19423 can_issue_more = issue_rate;
19424 can_issue_more--;
19425 if (can_issue_more == 0)
19427 can_issue_more = issue_rate - 1;
19428 (*group_count)++;
19429 end = true;
19430 for (i = 0; i < issue_rate; i++)
19432 group_insns[i] = 0;
19436 while (n_nops > 0)
19438 nop = gen_nop ();
19439 emit_insn_before (nop, next_insn);
19440 if (can_issue_more == issue_rate - 1) /* new group begins */
19441 end = false;
19442 can_issue_more--;
19443 if (can_issue_more == 0)
19445 can_issue_more = issue_rate - 1;
19446 (*group_count)++;
19447 end = true;
19448 for (i = 0; i < issue_rate; i++)
19450 group_insns[i] = 0;
19453 n_nops--;
19456 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
19457 can_issue_more++;
19459 /* Is next_insn going to start a new group? */
19460 *group_end
19461 = (end
19462 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
19463 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
19464 || (can_issue_more < issue_rate &&
19465 insn_terminates_group_p (next_insn, previous_group)));
19466 if (*group_end && end)
19467 (*group_count)--;
19469 if (sched_verbose > 6)
19470 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
19471 *group_count, can_issue_more);
19472 return can_issue_more;
19475 return can_issue_more;
19478 /* This function tries to synch the dispatch groups that the compiler "sees"
19479 with the dispatch groups that the processor dispatcher is expected to
19480 form in practice. It tries to achieve this synchronization by forcing the
19481 estimated processor grouping on the compiler (as opposed to the function
19482 'pad_goups' which tries to force the scheduler's grouping on the processor).
19484 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
19485 examines the (estimated) dispatch groups that will be formed by the processor
19486 dispatcher. It marks these group boundaries to reflect the estimated
19487 processor grouping, overriding the grouping that the scheduler had marked.
19488 Depending on the value of the flag '-minsert-sched-nops' this function can
19489 force certain insns into separate groups or force a certain distance between
19490 them by inserting nops, for example, if there exists a "costly dependence"
19491 between the insns.
19493 The function estimates the group boundaries that the processor will form as
19494 follows: It keeps track of how many vacant issue slots are available after
19495 each insn. A subsequent insn will start a new group if one of the following
19496 4 cases applies:
19497 - no more vacant issue slots remain in the current dispatch group.
19498 - only the last issue slot, which is the branch slot, is vacant, but the next
19499 insn is not a branch.
19500 - only the last 2 or less issue slots, including the branch slot, are vacant,
19501 which means that a cracked insn (which occupies two issue slots) can't be
19502 issued in this group.
19503 - less than 'issue_rate' slots are vacant, and the next insn always needs to
19504 start a new group. */
19506 static int
19507 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
19509 rtx insn, next_insn;
19510 int issue_rate;
19511 int can_issue_more;
19512 int slot, i;
19513 bool group_end;
19514 int group_count = 0;
19515 rtx *group_insns;
19517 /* Initialize. */
19518 issue_rate = rs6000_issue_rate ();
19519 group_insns = alloca (issue_rate * sizeof (rtx));
19520 for (i = 0; i < issue_rate; i++)
19522 group_insns[i] = 0;
19524 can_issue_more = issue_rate;
19525 slot = 0;
19526 insn = get_next_active_insn (prev_head_insn, tail);
19527 group_end = false;
19529 while (insn != NULL_RTX)
19531 slot = (issue_rate - can_issue_more);
19532 group_insns[slot] = insn;
19533 can_issue_more =
19534 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
19535 if (insn_terminates_group_p (insn, current_group))
19536 can_issue_more = 0;
19538 next_insn = get_next_active_insn (insn, tail);
19539 if (next_insn == NULL_RTX)
19540 return group_count + 1;
19542 /* Is next_insn going to start a new group? */
19543 group_end
19544 = (can_issue_more == 0
19545 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
19546 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
19547 || (can_issue_more < issue_rate &&
19548 insn_terminates_group_p (next_insn, previous_group)));
19550 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
19551 next_insn, &group_end, can_issue_more,
19552 &group_count);
19554 if (group_end)
19556 group_count++;
19557 can_issue_more = 0;
19558 for (i = 0; i < issue_rate; i++)
19560 group_insns[i] = 0;
19564 if (GET_MODE (next_insn) == TImode && can_issue_more)
19565 PUT_MODE (next_insn, VOIDmode);
19566 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
19567 PUT_MODE (next_insn, TImode);
19569 insn = next_insn;
19570 if (can_issue_more == 0)
19571 can_issue_more = issue_rate;
19572 } /* while */
19574 return group_count;
19577 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
19578 dispatch group boundaries that the scheduler had marked. Pad with nops
19579 any dispatch groups which have vacant issue slots, in order to force the
19580 scheduler's grouping on the processor dispatcher. The function
19581 returns the number of dispatch groups found. */
19583 static int
19584 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
19586 rtx insn, next_insn;
19587 rtx nop;
19588 int issue_rate;
19589 int can_issue_more;
19590 int group_end;
19591 int group_count = 0;
19593 /* Initialize issue_rate. */
19594 issue_rate = rs6000_issue_rate ();
19595 can_issue_more = issue_rate;
19597 insn = get_next_active_insn (prev_head_insn, tail);
19598 next_insn = get_next_active_insn (insn, tail);
19600 while (insn != NULL_RTX)
19602 can_issue_more =
19603 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
19605 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
19607 if (next_insn == NULL_RTX)
19608 break;
19610 if (group_end)
19612 /* If the scheduler had marked group termination at this location
19613 (between insn and next_indn), and neither insn nor next_insn will
19614 force group termination, pad the group with nops to force group
19615 termination. */
19616 if (can_issue_more
19617 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
19618 && !insn_terminates_group_p (insn, current_group)
19619 && !insn_terminates_group_p (next_insn, previous_group))
19621 if (!is_branch_slot_insn (next_insn))
19622 can_issue_more--;
19624 while (can_issue_more)
19626 nop = gen_nop ();
19627 emit_insn_before (nop, next_insn);
19628 can_issue_more--;
19632 can_issue_more = issue_rate;
19633 group_count++;
19636 insn = next_insn;
19637 next_insn = get_next_active_insn (insn, tail);
19640 return group_count;
19643 /* We're beginning a new block. Initialize data structures as necessary. */
19645 static void
19646 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
19647 int sched_verbose ATTRIBUTE_UNUSED,
19648 int max_ready ATTRIBUTE_UNUSED)
19650 last_scheduled_insn = NULL_RTX;
19651 load_store_pendulum = 0;
19654 /* The following function is called at the end of scheduling BB.
19655 After reload, it inserts nops at insn group bundling. */
19657 static void
19658 rs6000_sched_finish (FILE *dump, int sched_verbose)
19660 int n_groups;
19662 if (sched_verbose)
19663 fprintf (dump, "=== Finishing schedule.\n");
19665 if (reload_completed && rs6000_sched_groups)
19667 if (rs6000_sched_insert_nops == sched_finish_none)
19668 return;
19670 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
19671 n_groups = pad_groups (dump, sched_verbose,
19672 current_sched_info->prev_head,
19673 current_sched_info->next_tail);
19674 else
19675 n_groups = redefine_groups (dump, sched_verbose,
19676 current_sched_info->prev_head,
19677 current_sched_info->next_tail);
19679 if (sched_verbose >= 6)
19681 fprintf (dump, "ngroups = %d\n", n_groups);
19682 print_rtl (dump, current_sched_info->prev_head);
19683 fprintf (dump, "Done finish_sched\n");
19688 /* Length in units of the trampoline for entering a nested function. */
19691 rs6000_trampoline_size (void)
19693 int ret = 0;
19695 switch (DEFAULT_ABI)
19697 default:
19698 gcc_unreachable ();
19700 case ABI_AIX:
19701 ret = (TARGET_32BIT) ? 12 : 24;
19702 break;
19704 case ABI_DARWIN:
19705 case ABI_V4:
19706 ret = (TARGET_32BIT) ? 40 : 48;
19707 break;
19710 return ret;
19713 /* Emit RTL insns to initialize the variable parts of a trampoline.
19714 FNADDR is an RTX for the address of the function's pure code.
19715 CXT is an RTX for the static chain value for the function. */
19717 void
19718 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
19720 int regsize = (TARGET_32BIT) ? 4 : 8;
19721 rtx ctx_reg = force_reg (Pmode, cxt);
19723 switch (DEFAULT_ABI)
19725 default:
19726 gcc_unreachable ();
19728 /* Macros to shorten the code expansions below. */
19729 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
19730 #define MEM_PLUS(addr,offset) \
19731 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
19733 /* Under AIX, just build the 3 word function descriptor */
19734 case ABI_AIX:
19736 rtx fn_reg = gen_reg_rtx (Pmode);
19737 rtx toc_reg = gen_reg_rtx (Pmode);
19738 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
19739 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
19740 emit_move_insn (MEM_DEREF (addr), fn_reg);
19741 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
19742 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
19744 break;
19746 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
19747 case ABI_DARWIN:
19748 case ABI_V4:
19749 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
19750 FALSE, VOIDmode, 4,
19751 addr, Pmode,
19752 GEN_INT (rs6000_trampoline_size ()), SImode,
19753 fnaddr, Pmode,
19754 ctx_reg, Pmode);
19755 break;
19758 return;
19762 /* Table of valid machine attributes. */
19764 const struct attribute_spec rs6000_attribute_table[] =
19766 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
19767 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
19768 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
19769 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
19770 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
19771 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
19772 #ifdef SUBTARGET_ATTRIBUTE_TABLE
19773 SUBTARGET_ATTRIBUTE_TABLE,
19774 #endif
19775 { NULL, 0, 0, false, false, false, NULL }
19778 /* Handle the "altivec" attribute. The attribute may have
19779 arguments as follows:
19781 __attribute__((altivec(vector__)))
19782 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
19783 __attribute__((altivec(bool__))) (always followed by 'unsigned')
19785 and may appear more than once (e.g., 'vector bool char') in a
19786 given declaration. */
19788 static tree
19789 rs6000_handle_altivec_attribute (tree *node,
19790 tree name ATTRIBUTE_UNUSED,
19791 tree args,
19792 int flags ATTRIBUTE_UNUSED,
19793 bool *no_add_attrs)
19795 tree type = *node, result = NULL_TREE;
19796 enum machine_mode mode;
19797 int unsigned_p;
19798 char altivec_type
19799 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
19800 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
19801 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
19802 : '?');
19804 while (POINTER_TYPE_P (type)
19805 || TREE_CODE (type) == FUNCTION_TYPE
19806 || TREE_CODE (type) == METHOD_TYPE
19807 || TREE_CODE (type) == ARRAY_TYPE)
19808 type = TREE_TYPE (type);
19810 mode = TYPE_MODE (type);
19812 /* Check for invalid AltiVec type qualifiers. */
19813 if (type == long_unsigned_type_node || type == long_integer_type_node)
19815 if (TARGET_64BIT)
19816 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
19817 else if (rs6000_warn_altivec_long)
19818 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
19820 else if (type == long_long_unsigned_type_node
19821 || type == long_long_integer_type_node)
19822 error ("use of %<long long%> in AltiVec types is invalid");
19823 else if (type == double_type_node)
19824 error ("use of %<double%> in AltiVec types is invalid");
19825 else if (type == long_double_type_node)
19826 error ("use of %<long double%> in AltiVec types is invalid");
19827 else if (type == boolean_type_node)
19828 error ("use of boolean types in AltiVec types is invalid");
19829 else if (TREE_CODE (type) == COMPLEX_TYPE)
19830 error ("use of %<complex%> in AltiVec types is invalid");
19831 else if (DECIMAL_FLOAT_MODE_P (mode))
19832 error ("use of decimal floating point types in AltiVec types is invalid");
19834 switch (altivec_type)
19836 case 'v':
19837 unsigned_p = TYPE_UNSIGNED (type);
19838 switch (mode)
19840 case SImode:
19841 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
19842 break;
19843 case HImode:
19844 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
19845 break;
19846 case QImode:
19847 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
19848 break;
19849 case SFmode: result = V4SF_type_node; break;
19850 /* If the user says 'vector int bool', we may be handed the 'bool'
19851 attribute _before_ the 'vector' attribute, and so select the
19852 proper type in the 'b' case below. */
19853 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
19854 result = type;
19855 default: break;
19857 break;
19858 case 'b':
19859 switch (mode)
19861 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
19862 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
19863 case QImode: case V16QImode: result = bool_V16QI_type_node;
19864 default: break;
19866 break;
19867 case 'p':
19868 switch (mode)
19870 case V8HImode: result = pixel_V8HI_type_node;
19871 default: break;
19873 default: break;
19876 if (result && result != type && TYPE_READONLY (type))
19877 result = build_qualified_type (result, TYPE_QUAL_CONST);
19879 *no_add_attrs = true; /* No need to hang on to the attribute. */
19881 if (result)
19882 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
19884 return NULL_TREE;
19887 /* AltiVec defines four built-in scalar types that serve as vector
19888 elements; we must teach the compiler how to mangle them. */
19890 static const char *
19891 rs6000_mangle_type (const_tree type)
19893 type = TYPE_MAIN_VARIANT (type);
19895 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
19896 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
19897 return NULL;
19899 if (type == bool_char_type_node) return "U6__boolc";
19900 if (type == bool_short_type_node) return "U6__bools";
19901 if (type == pixel_type_node) return "u7__pixel";
19902 if (type == bool_int_type_node) return "U6__booli";
19904 /* Mangle IBM extended float long double as `g' (__float128) on
19905 powerpc*-linux where long-double-64 previously was the default. */
19906 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
19907 && TARGET_ELF
19908 && TARGET_LONG_DOUBLE_128
19909 && !TARGET_IEEEQUAD)
19910 return "g";
19912 /* For all other types, use normal C++ mangling. */
19913 return NULL;
19916 /* Handle a "longcall" or "shortcall" attribute; arguments as in
19917 struct attribute_spec.handler. */
19919 static tree
19920 rs6000_handle_longcall_attribute (tree *node, tree name,
19921 tree args ATTRIBUTE_UNUSED,
19922 int flags ATTRIBUTE_UNUSED,
19923 bool *no_add_attrs)
19925 if (TREE_CODE (*node) != FUNCTION_TYPE
19926 && TREE_CODE (*node) != FIELD_DECL
19927 && TREE_CODE (*node) != TYPE_DECL)
19929 warning (OPT_Wattributes, "%qs attribute only applies to functions",
19930 IDENTIFIER_POINTER (name));
19931 *no_add_attrs = true;
19934 return NULL_TREE;
19937 /* Set longcall attributes on all functions declared when
19938 rs6000_default_long_calls is true. */
19939 static void
19940 rs6000_set_default_type_attributes (tree type)
19942 if (rs6000_default_long_calls
19943 && (TREE_CODE (type) == FUNCTION_TYPE
19944 || TREE_CODE (type) == METHOD_TYPE))
19945 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
19946 NULL_TREE,
19947 TYPE_ATTRIBUTES (type));
19949 #if TARGET_MACHO
19950 darwin_set_default_type_attributes (type);
19951 #endif
19954 /* Return a reference suitable for calling a function with the
19955 longcall attribute. */
19958 rs6000_longcall_ref (rtx call_ref)
19960 const char *call_name;
19961 tree node;
19963 if (GET_CODE (call_ref) != SYMBOL_REF)
19964 return call_ref;
19966 /* System V adds '.' to the internal name, so skip them. */
19967 call_name = XSTR (call_ref, 0);
19968 if (*call_name == '.')
19970 while (*call_name == '.')
19971 call_name++;
19973 node = get_identifier (call_name);
19974 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
19977 return force_reg (Pmode, call_ref);
19980 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
19981 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
19982 #endif
19984 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
19985 struct attribute_spec.handler. */
19986 static tree
19987 rs6000_handle_struct_attribute (tree *node, tree name,
19988 tree args ATTRIBUTE_UNUSED,
19989 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
19991 tree *type = NULL;
19992 if (DECL_P (*node))
19994 if (TREE_CODE (*node) == TYPE_DECL)
19995 type = &TREE_TYPE (*node);
19997 else
19998 type = node;
20000 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
20001 || TREE_CODE (*type) == UNION_TYPE)))
20003 warning (OPT_Wattributes, "%qs attribute ignored", IDENTIFIER_POINTER (name));
20004 *no_add_attrs = true;
20007 else if ((is_attribute_p ("ms_struct", name)
20008 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
20009 || ((is_attribute_p ("gcc_struct", name)
20010 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
20012 warning (OPT_Wattributes, "%qs incompatible attribute ignored",
20013 IDENTIFIER_POINTER (name));
20014 *no_add_attrs = true;
20017 return NULL_TREE;
20020 static bool
20021 rs6000_ms_bitfield_layout_p (const_tree record_type)
20023 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
20024 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
20025 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
20028 #ifdef USING_ELFOS_H
20030 /* A get_unnamed_section callback, used for switching to toc_section. */
20032 static void
20033 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
20035 if (DEFAULT_ABI == ABI_AIX
20036 && TARGET_MINIMAL_TOC
20037 && !TARGET_RELOCATABLE)
20039 if (!toc_initialized)
20041 toc_initialized = 1;
20042 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
20043 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
20044 fprintf (asm_out_file, "\t.tc ");
20045 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
20046 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
20047 fprintf (asm_out_file, "\n");
20049 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20050 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
20051 fprintf (asm_out_file, " = .+32768\n");
20053 else
20054 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20056 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
20057 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
20058 else
20060 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20061 if (!toc_initialized)
20063 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
20064 fprintf (asm_out_file, " = .+32768\n");
20065 toc_initialized = 1;
20070 /* Implement TARGET_ASM_INIT_SECTIONS. */
20072 static void
20073 rs6000_elf_asm_init_sections (void)
20075 toc_section
20076 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
20078 sdata2_section
20079 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
20080 SDATA2_SECTION_ASM_OP);
20083 /* Implement TARGET_SELECT_RTX_SECTION. */
20085 static section *
20086 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
20087 unsigned HOST_WIDE_INT align)
20089 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
20090 return toc_section;
20091 else
20092 return default_elf_select_rtx_section (mode, x, align);
20095 /* For a SYMBOL_REF, set generic flags and then perform some
20096 target-specific processing.
20098 When the AIX ABI is requested on a non-AIX system, replace the
20099 function name with the real name (with a leading .) rather than the
20100 function descriptor name. This saves a lot of overriding code to
20101 read the prefixes. */
20103 static void
20104 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
20106 default_encode_section_info (decl, rtl, first);
20108 if (first
20109 && TREE_CODE (decl) == FUNCTION_DECL
20110 && !TARGET_AIX
20111 && DEFAULT_ABI == ABI_AIX)
20113 rtx sym_ref = XEXP (rtl, 0);
20114 size_t len = strlen (XSTR (sym_ref, 0));
20115 char *str = alloca (len + 2);
20116 str[0] = '.';
20117 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
20118 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
20122 static inline bool
20123 compare_section_name (const char *section, const char *template)
20125 int len;
20127 len = strlen (template);
20128 return (strncmp (section, template, len) == 0
20129 && (section[len] == 0 || section[len] == '.'));
20132 bool
20133 rs6000_elf_in_small_data_p (const_tree decl)
20135 if (rs6000_sdata == SDATA_NONE)
20136 return false;
20138 /* We want to merge strings, so we never consider them small data. */
20139 if (TREE_CODE (decl) == STRING_CST)
20140 return false;
20142 /* Functions are never in the small data area. */
20143 if (TREE_CODE (decl) == FUNCTION_DECL)
20144 return false;
20146 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
20148 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
20149 if (compare_section_name (section, ".sdata")
20150 || compare_section_name (section, ".sdata2")
20151 || compare_section_name (section, ".gnu.linkonce.s")
20152 || compare_section_name (section, ".sbss")
20153 || compare_section_name (section, ".sbss2")
20154 || compare_section_name (section, ".gnu.linkonce.sb")
20155 || strcmp (section, ".PPC.EMB.sdata0") == 0
20156 || strcmp (section, ".PPC.EMB.sbss0") == 0)
20157 return true;
20159 else
20161 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
20163 if (size > 0
20164 && (unsigned HOST_WIDE_INT) size <= g_switch_value
20165 /* If it's not public, and we're not going to reference it there,
20166 there's no need to put it in the small data section. */
20167 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
20168 return true;
20171 return false;
20174 #endif /* USING_ELFOS_H */
20176 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
20178 static bool
20179 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
20181 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
20184 /* Return a REG that occurs in ADDR with coefficient 1.
20185 ADDR can be effectively incremented by incrementing REG.
20187 r0 is special and we must not select it as an address
20188 register by this routine since our caller will try to
20189 increment the returned register via an "la" instruction. */
20192 find_addr_reg (rtx addr)
20194 while (GET_CODE (addr) == PLUS)
20196 if (GET_CODE (XEXP (addr, 0)) == REG
20197 && REGNO (XEXP (addr, 0)) != 0)
20198 addr = XEXP (addr, 0);
20199 else if (GET_CODE (XEXP (addr, 1)) == REG
20200 && REGNO (XEXP (addr, 1)) != 0)
20201 addr = XEXP (addr, 1);
20202 else if (CONSTANT_P (XEXP (addr, 0)))
20203 addr = XEXP (addr, 1);
20204 else if (CONSTANT_P (XEXP (addr, 1)))
20205 addr = XEXP (addr, 0);
20206 else
20207 gcc_unreachable ();
20209 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
20210 return addr;
20213 void
20214 rs6000_fatal_bad_address (rtx op)
20216 fatal_insn ("bad address", op);
20219 #if TARGET_MACHO
20221 static tree branch_island_list = 0;
20223 /* Remember to generate a branch island for far calls to the given
20224 function. */
20226 static void
20227 add_compiler_branch_island (tree label_name, tree function_name,
20228 int line_number)
20230 tree branch_island = build_tree_list (function_name, label_name);
20231 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
20232 TREE_CHAIN (branch_island) = branch_island_list;
20233 branch_island_list = branch_island;
20236 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
20237 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
20238 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
20239 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
20241 /* Generate far-jump branch islands for everything on the
20242 branch_island_list. Invoked immediately after the last instruction
20243 of the epilogue has been emitted; the branch-islands must be
20244 appended to, and contiguous with, the function body. Mach-O stubs
20245 are generated in machopic_output_stub(). */
20247 static void
20248 macho_branch_islands (void)
20250 char tmp_buf[512];
20251 tree branch_island;
20253 for (branch_island = branch_island_list;
20254 branch_island;
20255 branch_island = TREE_CHAIN (branch_island))
20257 const char *label =
20258 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
20259 const char *name =
20260 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
20261 char name_buf[512];
20262 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
20263 if (name[0] == '*' || name[0] == '&')
20264 strcpy (name_buf, name+1);
20265 else
20267 name_buf[0] = '_';
20268 strcpy (name_buf+1, name);
20270 strcpy (tmp_buf, "\n");
20271 strcat (tmp_buf, label);
20272 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20273 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
20274 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
20275 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20276 if (flag_pic)
20278 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
20279 strcat (tmp_buf, label);
20280 strcat (tmp_buf, "_pic\n");
20281 strcat (tmp_buf, label);
20282 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
20284 strcat (tmp_buf, "\taddis r11,r11,ha16(");
20285 strcat (tmp_buf, name_buf);
20286 strcat (tmp_buf, " - ");
20287 strcat (tmp_buf, label);
20288 strcat (tmp_buf, "_pic)\n");
20290 strcat (tmp_buf, "\tmtlr r0\n");
20292 strcat (tmp_buf, "\taddi r12,r11,lo16(");
20293 strcat (tmp_buf, name_buf);
20294 strcat (tmp_buf, " - ");
20295 strcat (tmp_buf, label);
20296 strcat (tmp_buf, "_pic)\n");
20298 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
20300 else
20302 strcat (tmp_buf, ":\nlis r12,hi16(");
20303 strcat (tmp_buf, name_buf);
20304 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
20305 strcat (tmp_buf, name_buf);
20306 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
20308 output_asm_insn (tmp_buf, 0);
20309 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20310 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
20311 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
20312 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20315 branch_island_list = 0;
20318 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
20319 already there or not. */
20321 static int
20322 no_previous_def (tree function_name)
20324 tree branch_island;
20325 for (branch_island = branch_island_list;
20326 branch_island;
20327 branch_island = TREE_CHAIN (branch_island))
20328 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
20329 return 0;
20330 return 1;
20333 /* GET_PREV_LABEL gets the label name from the previous definition of
20334 the function. */
20336 static tree
20337 get_prev_label (tree function_name)
20339 tree branch_island;
20340 for (branch_island = branch_island_list;
20341 branch_island;
20342 branch_island = TREE_CHAIN (branch_island))
20343 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
20344 return BRANCH_ISLAND_LABEL_NAME (branch_island);
20345 return 0;
20348 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
20349 #define DARWIN_LINKER_GENERATES_ISLANDS 0
20350 #endif
20352 /* KEXTs still need branch islands. */
20353 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
20354 || flag_mkernel || flag_apple_kext)
20356 /* INSN is either a function call or a millicode call. It may have an
20357 unconditional jump in its delay slot.
20359 CALL_DEST is the routine we are calling. */
20361 char *
20362 output_call (rtx insn, rtx *operands, int dest_operand_number,
20363 int cookie_operand_number)
20365 static char buf[256];
20366 if (DARWIN_GENERATE_ISLANDS
20367 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
20368 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
20370 tree labelname;
20371 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
20373 if (no_previous_def (funname))
20375 rtx label_rtx = gen_label_rtx ();
20376 char *label_buf, temp_buf[256];
20377 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
20378 CODE_LABEL_NUMBER (label_rtx));
20379 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
20380 labelname = get_identifier (label_buf);
20381 add_compiler_branch_island (labelname, funname, insn_line (insn));
20383 else
20384 labelname = get_prev_label (funname);
20386 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
20387 instruction will reach 'foo', otherwise link as 'bl L42'".
20388 "L42" should be a 'branch island', that will do a far jump to
20389 'foo'. Branch islands are generated in
20390 macho_branch_islands(). */
20391 sprintf (buf, "jbsr %%z%d,%.246s",
20392 dest_operand_number, IDENTIFIER_POINTER (labelname));
20394 else
20395 sprintf (buf, "bl %%z%d", dest_operand_number);
20396 return buf;
20399 /* Generate PIC and indirect symbol stubs. */
20401 void
20402 machopic_output_stub (FILE *file, const char *symb, const char *stub)
20404 unsigned int length;
20405 char *symbol_name, *lazy_ptr_name;
20406 char *local_label_0;
20407 static int label = 0;
20409 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
20410 symb = (*targetm.strip_name_encoding) (symb);
20413 length = strlen (symb);
20414 symbol_name = alloca (length + 32);
20415 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
20417 lazy_ptr_name = alloca (length + 32);
20418 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
20420 if (flag_pic == 2)
20421 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
20422 else
20423 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
20425 if (flag_pic == 2)
20427 fprintf (file, "\t.align 5\n");
20429 fprintf (file, "%s:\n", stub);
20430 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
20432 label++;
20433 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
20434 sprintf (local_label_0, "\"L%011d$spb\"", label);
20436 fprintf (file, "\tmflr r0\n");
20437 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
20438 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
20439 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
20440 lazy_ptr_name, local_label_0);
20441 fprintf (file, "\tmtlr r0\n");
20442 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
20443 (TARGET_64BIT ? "ldu" : "lwzu"),
20444 lazy_ptr_name, local_label_0);
20445 fprintf (file, "\tmtctr r12\n");
20446 fprintf (file, "\tbctr\n");
20448 else
20450 fprintf (file, "\t.align 4\n");
20452 fprintf (file, "%s:\n", stub);
20453 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
20455 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
20456 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
20457 (TARGET_64BIT ? "ldu" : "lwzu"),
20458 lazy_ptr_name);
20459 fprintf (file, "\tmtctr r12\n");
20460 fprintf (file, "\tbctr\n");
20463 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
20464 fprintf (file, "%s:\n", lazy_ptr_name);
20465 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
20466 fprintf (file, "%sdyld_stub_binding_helper\n",
20467 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
20470 /* Legitimize PIC addresses. If the address is already
20471 position-independent, we return ORIG. Newly generated
20472 position-independent addresses go into a reg. This is REG if non
20473 zero, otherwise we allocate register(s) as necessary. */
20475 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
20478 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
20479 rtx reg)
20481 rtx base, offset;
20483 if (reg == NULL && ! reload_in_progress && ! reload_completed)
20484 reg = gen_reg_rtx (Pmode);
20486 if (GET_CODE (orig) == CONST)
20488 rtx reg_temp;
20490 if (GET_CODE (XEXP (orig, 0)) == PLUS
20491 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
20492 return orig;
20494 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
20496 /* Use a different reg for the intermediate value, as
20497 it will be marked UNCHANGING. */
20498 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
20499 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
20500 Pmode, reg_temp);
20501 offset =
20502 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
20503 Pmode, reg);
20505 if (GET_CODE (offset) == CONST_INT)
20507 if (SMALL_INT (offset))
20508 return plus_constant (base, INTVAL (offset));
20509 else if (! reload_in_progress && ! reload_completed)
20510 offset = force_reg (Pmode, offset);
20511 else
20513 rtx mem = force_const_mem (Pmode, orig);
20514 return machopic_legitimize_pic_address (mem, Pmode, reg);
20517 return gen_rtx_PLUS (Pmode, base, offset);
20520 /* Fall back on generic machopic code. */
20521 return machopic_legitimize_pic_address (orig, mode, reg);
20524 /* Output a .machine directive for the Darwin assembler, and call
20525 the generic start_file routine. */
20527 static void
20528 rs6000_darwin_file_start (void)
20530 static const struct
20532 const char *arg;
20533 const char *name;
20534 int if_set;
20535 } mapping[] = {
20536 { "ppc64", "ppc64", MASK_64BIT },
20537 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
20538 { "power4", "ppc970", 0 },
20539 { "G5", "ppc970", 0 },
20540 { "7450", "ppc7450", 0 },
20541 { "7400", "ppc7400", MASK_ALTIVEC },
20542 { "G4", "ppc7400", 0 },
20543 { "750", "ppc750", 0 },
20544 { "740", "ppc750", 0 },
20545 { "G3", "ppc750", 0 },
20546 { "604e", "ppc604e", 0 },
20547 { "604", "ppc604", 0 },
20548 { "603e", "ppc603", 0 },
20549 { "603", "ppc603", 0 },
20550 { "601", "ppc601", 0 },
20551 { NULL, "ppc", 0 } };
20552 const char *cpu_id = "";
20553 size_t i;
20555 rs6000_file_start ();
20556 darwin_file_start ();
20558 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
20559 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
20560 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
20561 && rs6000_select[i].string[0] != '\0')
20562 cpu_id = rs6000_select[i].string;
20564 /* Look through the mapping array. Pick the first name that either
20565 matches the argument, has a bit set in IF_SET that is also set
20566 in the target flags, or has a NULL name. */
20568 i = 0;
20569 while (mapping[i].arg != NULL
20570 && strcmp (mapping[i].arg, cpu_id) != 0
20571 && (mapping[i].if_set & target_flags) == 0)
20572 i++;
20574 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
20577 #endif /* TARGET_MACHO */
20579 #if TARGET_ELF
20580 static int
20581 rs6000_elf_reloc_rw_mask (void)
20583 if (flag_pic)
20584 return 3;
20585 else if (DEFAULT_ABI == ABI_AIX)
20586 return 2;
20587 else
20588 return 0;
20591 /* Record an element in the table of global constructors. SYMBOL is
20592 a SYMBOL_REF of the function to be called; PRIORITY is a number
20593 between 0 and MAX_INIT_PRIORITY.
20595 This differs from default_named_section_asm_out_constructor in
20596 that we have special handling for -mrelocatable. */
20598 static void
20599 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
20601 const char *section = ".ctors";
20602 char buf[16];
20604 if (priority != DEFAULT_INIT_PRIORITY)
20606 sprintf (buf, ".ctors.%.5u",
20607 /* Invert the numbering so the linker puts us in the proper
20608 order; constructors are run from right to left, and the
20609 linker sorts in increasing order. */
20610 MAX_INIT_PRIORITY - priority);
20611 section = buf;
20614 switch_to_section (get_section (section, SECTION_WRITE, NULL));
20615 assemble_align (POINTER_SIZE);
20617 if (TARGET_RELOCATABLE)
20619 fputs ("\t.long (", asm_out_file);
20620 output_addr_const (asm_out_file, symbol);
20621 fputs (")@fixup\n", asm_out_file);
20623 else
20624 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
20627 static void
20628 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
20630 const char *section = ".dtors";
20631 char buf[16];
20633 if (priority != DEFAULT_INIT_PRIORITY)
20635 sprintf (buf, ".dtors.%.5u",
20636 /* Invert the numbering so the linker puts us in the proper
20637 order; constructors are run from right to left, and the
20638 linker sorts in increasing order. */
20639 MAX_INIT_PRIORITY - priority);
20640 section = buf;
20643 switch_to_section (get_section (section, SECTION_WRITE, NULL));
20644 assemble_align (POINTER_SIZE);
20646 if (TARGET_RELOCATABLE)
20648 fputs ("\t.long (", asm_out_file);
20649 output_addr_const (asm_out_file, symbol);
20650 fputs (")@fixup\n", asm_out_file);
20652 else
20653 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
20656 void
20657 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
20659 if (TARGET_64BIT)
20661 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
20662 ASM_OUTPUT_LABEL (file, name);
20663 fputs (DOUBLE_INT_ASM_OP, file);
20664 rs6000_output_function_entry (file, name);
20665 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
20666 if (DOT_SYMBOLS)
20668 fputs ("\t.size\t", file);
20669 assemble_name (file, name);
20670 fputs (",24\n\t.type\t.", file);
20671 assemble_name (file, name);
20672 fputs (",@function\n", file);
20673 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
20675 fputs ("\t.globl\t.", file);
20676 assemble_name (file, name);
20677 putc ('\n', file);
20680 else
20681 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
20682 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
20683 rs6000_output_function_entry (file, name);
20684 fputs (":\n", file);
20685 return;
20688 if (TARGET_RELOCATABLE
20689 && !TARGET_SECURE_PLT
20690 && (get_pool_size () != 0 || crtl->profile)
20691 && uses_TOC ())
20693 char buf[256];
20695 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
20697 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
20698 fprintf (file, "\t.long ");
20699 assemble_name (file, buf);
20700 putc ('-', file);
20701 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
20702 assemble_name (file, buf);
20703 putc ('\n', file);
20706 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
20707 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
20709 if (DEFAULT_ABI == ABI_AIX)
20711 const char *desc_name, *orig_name;
20713 orig_name = (*targetm.strip_name_encoding) (name);
20714 desc_name = orig_name;
20715 while (*desc_name == '.')
20716 desc_name++;
20718 if (TREE_PUBLIC (decl))
20719 fprintf (file, "\t.globl %s\n", desc_name);
20721 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20722 fprintf (file, "%s:\n", desc_name);
20723 fprintf (file, "\t.long %s\n", orig_name);
20724 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
20725 if (DEFAULT_ABI == ABI_AIX)
20726 fputs ("\t.long 0\n", file);
20727 fprintf (file, "\t.previous\n");
20729 ASM_OUTPUT_LABEL (file, name);
20732 static void
20733 rs6000_elf_end_indicate_exec_stack (void)
20735 if (TARGET_32BIT)
20736 file_end_indicate_exec_stack ();
20738 #endif
20740 #if TARGET_XCOFF
20741 static void
20742 rs6000_xcoff_asm_output_anchor (rtx symbol)
20744 char buffer[100];
20746 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
20747 SYMBOL_REF_BLOCK_OFFSET (symbol));
20748 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
20751 static void
20752 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
20754 fputs (GLOBAL_ASM_OP, stream);
20755 RS6000_OUTPUT_BASENAME (stream, name);
20756 putc ('\n', stream);
20759 /* A get_unnamed_decl callback, used for read-only sections. PTR
20760 points to the section string variable. */
20762 static void
20763 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
20765 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
20766 *(const char *const *) directive,
20767 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
20770 /* Likewise for read-write sections. */
20772 static void
20773 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
20775 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
20776 *(const char *const *) directive,
20777 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
20780 /* A get_unnamed_section callback, used for switching to toc_section. */
20782 static void
20783 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
20785 if (TARGET_MINIMAL_TOC)
20787 /* toc_section is always selected at least once from
20788 rs6000_xcoff_file_start, so this is guaranteed to
20789 always be defined once and only once in each file. */
20790 if (!toc_initialized)
20792 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
20793 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
20794 toc_initialized = 1;
20796 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
20797 (TARGET_32BIT ? "" : ",3"));
20799 else
20800 fputs ("\t.toc\n", asm_out_file);
20803 /* Implement TARGET_ASM_INIT_SECTIONS. */
20805 static void
20806 rs6000_xcoff_asm_init_sections (void)
20808 read_only_data_section
20809 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
20810 &xcoff_read_only_section_name);
20812 private_data_section
20813 = get_unnamed_section (SECTION_WRITE,
20814 rs6000_xcoff_output_readwrite_section_asm_op,
20815 &xcoff_private_data_section_name);
20817 read_only_private_data_section
20818 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
20819 &xcoff_private_data_section_name);
20821 toc_section
20822 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
20824 readonly_data_section = read_only_data_section;
20825 exception_section = data_section;
20828 static int
20829 rs6000_xcoff_reloc_rw_mask (void)
20831 return 3;
20834 static void
20835 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
20836 tree decl ATTRIBUTE_UNUSED)
20838 int smclass;
20839 static const char * const suffix[3] = { "PR", "RO", "RW" };
20841 if (flags & SECTION_CODE)
20842 smclass = 0;
20843 else if (flags & SECTION_WRITE)
20844 smclass = 2;
20845 else
20846 smclass = 1;
20848 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
20849 (flags & SECTION_CODE) ? "." : "",
20850 name, suffix[smclass], flags & SECTION_ENTSIZE);
20853 static section *
20854 rs6000_xcoff_select_section (tree decl, int reloc,
20855 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
20857 if (decl_readonly_section (decl, reloc))
20859 if (TREE_PUBLIC (decl))
20860 return read_only_data_section;
20861 else
20862 return read_only_private_data_section;
20864 else
20866 if (TREE_PUBLIC (decl))
20867 return data_section;
20868 else
20869 return private_data_section;
20873 static void
20874 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
20876 const char *name;
20878 /* Use select_section for private and uninitialized data. */
20879 if (!TREE_PUBLIC (decl)
20880 || DECL_COMMON (decl)
20881 || DECL_INITIAL (decl) == NULL_TREE
20882 || DECL_INITIAL (decl) == error_mark_node
20883 || (flag_zero_initialized_in_bss
20884 && initializer_zerop (DECL_INITIAL (decl))))
20885 return;
20887 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
20888 name = (*targetm.strip_name_encoding) (name);
20889 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
20892 /* Select section for constant in constant pool.
20894 On RS/6000, all constants are in the private read-only data area.
20895 However, if this is being placed in the TOC it must be output as a
20896 toc entry. */
20898 static section *
20899 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
20900 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
20902 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
20903 return toc_section;
20904 else
20905 return read_only_private_data_section;
20908 /* Remove any trailing [DS] or the like from the symbol name. */
20910 static const char *
20911 rs6000_xcoff_strip_name_encoding (const char *name)
20913 size_t len;
20914 if (*name == '*')
20915 name++;
20916 len = strlen (name);
20917 if (name[len - 1] == ']')
20918 return ggc_alloc_string (name, len - 4);
20919 else
20920 return name;
20923 /* Section attributes. AIX is always PIC. */
20925 static unsigned int
20926 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
20928 unsigned int align;
20929 unsigned int flags = default_section_type_flags (decl, name, reloc);
20931 /* Align to at least UNIT size. */
20932 if (flags & SECTION_CODE)
20933 align = MIN_UNITS_PER_WORD;
20934 else
20935 /* Increase alignment of large objects if not already stricter. */
20936 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
20937 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
20938 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
20940 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
20943 /* Output at beginning of assembler file.
20945 Initialize the section names for the RS/6000 at this point.
20947 Specify filename, including full path, to assembler.
20949 We want to go into the TOC section so at least one .toc will be emitted.
20950 Also, in order to output proper .bs/.es pairs, we need at least one static
20951 [RW] section emitted.
20953 Finally, declare mcount when profiling to make the assembler happy. */
20955 static void
20956 rs6000_xcoff_file_start (void)
20958 rs6000_gen_section_name (&xcoff_bss_section_name,
20959 main_input_filename, ".bss_");
20960 rs6000_gen_section_name (&xcoff_private_data_section_name,
20961 main_input_filename, ".rw_");
20962 rs6000_gen_section_name (&xcoff_read_only_section_name,
20963 main_input_filename, ".ro_");
20965 fputs ("\t.file\t", asm_out_file);
20966 output_quoted_string (asm_out_file, main_input_filename);
20967 fputc ('\n', asm_out_file);
20968 if (write_symbols != NO_DEBUG)
20969 switch_to_section (private_data_section);
20970 switch_to_section (text_section);
20971 if (profile_flag)
20972 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
20973 rs6000_file_start ();
20976 /* Output at end of assembler file.
20977 On the RS/6000, referencing data should automatically pull in text. */
20979 static void
20980 rs6000_xcoff_file_end (void)
20982 switch_to_section (text_section);
20983 fputs ("_section_.text:\n", asm_out_file);
20984 switch_to_section (data_section);
20985 fputs (TARGET_32BIT
20986 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
20987 asm_out_file);
20989 #endif /* TARGET_XCOFF */
20991 /* Compute a (partial) cost for rtx X. Return true if the complete
20992 cost has been computed, and false if subexpressions should be
20993 scanned. In either case, *TOTAL contains the cost result. */
20995 static bool
20996 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
20998 enum machine_mode mode = GET_MODE (x);
21000 switch (code)
21002 /* On the RS/6000, if it is valid in the insn, it is free. */
21003 case CONST_INT:
21004 if (((outer_code == SET
21005 || outer_code == PLUS
21006 || outer_code == MINUS)
21007 && (satisfies_constraint_I (x)
21008 || satisfies_constraint_L (x)))
21009 || (outer_code == AND
21010 && (satisfies_constraint_K (x)
21011 || (mode == SImode
21012 ? satisfies_constraint_L (x)
21013 : satisfies_constraint_J (x))
21014 || mask_operand (x, mode)
21015 || (mode == DImode
21016 && mask64_operand (x, DImode))))
21017 || ((outer_code == IOR || outer_code == XOR)
21018 && (satisfies_constraint_K (x)
21019 || (mode == SImode
21020 ? satisfies_constraint_L (x)
21021 : satisfies_constraint_J (x))))
21022 || outer_code == ASHIFT
21023 || outer_code == ASHIFTRT
21024 || outer_code == LSHIFTRT
21025 || outer_code == ROTATE
21026 || outer_code == ROTATERT
21027 || outer_code == ZERO_EXTRACT
21028 || (outer_code == MULT
21029 && satisfies_constraint_I (x))
21030 || ((outer_code == DIV || outer_code == UDIV
21031 || outer_code == MOD || outer_code == UMOD)
21032 && exact_log2 (INTVAL (x)) >= 0)
21033 || (outer_code == COMPARE
21034 && (satisfies_constraint_I (x)
21035 || satisfies_constraint_K (x)))
21036 || (outer_code == EQ
21037 && (satisfies_constraint_I (x)
21038 || satisfies_constraint_K (x)
21039 || (mode == SImode
21040 ? satisfies_constraint_L (x)
21041 : satisfies_constraint_J (x))))
21042 || (outer_code == GTU
21043 && satisfies_constraint_I (x))
21044 || (outer_code == LTU
21045 && satisfies_constraint_P (x)))
21047 *total = 0;
21048 return true;
21050 else if ((outer_code == PLUS
21051 && reg_or_add_cint_operand (x, VOIDmode))
21052 || (outer_code == MINUS
21053 && reg_or_sub_cint_operand (x, VOIDmode))
21054 || ((outer_code == SET
21055 || outer_code == IOR
21056 || outer_code == XOR)
21057 && (INTVAL (x)
21058 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
21060 *total = COSTS_N_INSNS (1);
21061 return true;
21063 /* FALLTHRU */
21065 case CONST_DOUBLE:
21066 if (mode == DImode && code == CONST_DOUBLE)
21068 if ((outer_code == IOR || outer_code == XOR)
21069 && CONST_DOUBLE_HIGH (x) == 0
21070 && (CONST_DOUBLE_LOW (x)
21071 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
21073 *total = 0;
21074 return true;
21076 else if ((outer_code == AND && and64_2_operand (x, DImode))
21077 || ((outer_code == SET
21078 || outer_code == IOR
21079 || outer_code == XOR)
21080 && CONST_DOUBLE_HIGH (x) == 0))
21082 *total = COSTS_N_INSNS (1);
21083 return true;
21086 /* FALLTHRU */
21088 case CONST:
21089 case HIGH:
21090 case SYMBOL_REF:
21091 case MEM:
21092 /* When optimizing for size, MEM should be slightly more expensive
21093 than generating address, e.g., (plus (reg) (const)).
21094 L1 cache latency is about two instructions. */
21095 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
21096 return true;
21098 case LABEL_REF:
21099 *total = 0;
21100 return true;
21102 case PLUS:
21103 if (mode == DFmode)
21105 if (GET_CODE (XEXP (x, 0)) == MULT)
21107 /* FNMA accounted in outer NEG. */
21108 if (outer_code == NEG)
21109 *total = rs6000_cost->dmul - rs6000_cost->fp;
21110 else
21111 *total = rs6000_cost->dmul;
21113 else
21114 *total = rs6000_cost->fp;
21116 else if (mode == SFmode)
21118 /* FNMA accounted in outer NEG. */
21119 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
21120 *total = 0;
21121 else
21122 *total = rs6000_cost->fp;
21124 else
21125 *total = COSTS_N_INSNS (1);
21126 return false;
21128 case MINUS:
21129 if (mode == DFmode)
21131 if (GET_CODE (XEXP (x, 0)) == MULT
21132 || GET_CODE (XEXP (x, 1)) == MULT)
21134 /* FNMA accounted in outer NEG. */
21135 if (outer_code == NEG)
21136 *total = rs6000_cost->dmul - rs6000_cost->fp;
21137 else
21138 *total = rs6000_cost->dmul;
21140 else
21141 *total = rs6000_cost->fp;
21143 else if (mode == SFmode)
21145 /* FNMA accounted in outer NEG. */
21146 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
21147 *total = 0;
21148 else
21149 *total = rs6000_cost->fp;
21151 else
21152 *total = COSTS_N_INSNS (1);
21153 return false;
21155 case MULT:
21156 if (GET_CODE (XEXP (x, 1)) == CONST_INT
21157 && satisfies_constraint_I (XEXP (x, 1)))
21159 if (INTVAL (XEXP (x, 1)) >= -256
21160 && INTVAL (XEXP (x, 1)) <= 255)
21161 *total = rs6000_cost->mulsi_const9;
21162 else
21163 *total = rs6000_cost->mulsi_const;
21165 /* FMA accounted in outer PLUS/MINUS. */
21166 else if ((mode == DFmode || mode == SFmode)
21167 && (outer_code == PLUS || outer_code == MINUS))
21168 *total = 0;
21169 else if (mode == DFmode)
21170 *total = rs6000_cost->dmul;
21171 else if (mode == SFmode)
21172 *total = rs6000_cost->fp;
21173 else if (mode == DImode)
21174 *total = rs6000_cost->muldi;
21175 else
21176 *total = rs6000_cost->mulsi;
21177 return false;
21179 case DIV:
21180 case MOD:
21181 if (FLOAT_MODE_P (mode))
21183 *total = mode == DFmode ? rs6000_cost->ddiv
21184 : rs6000_cost->sdiv;
21185 return false;
21187 /* FALLTHRU */
21189 case UDIV:
21190 case UMOD:
21191 if (GET_CODE (XEXP (x, 1)) == CONST_INT
21192 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
21194 if (code == DIV || code == MOD)
21195 /* Shift, addze */
21196 *total = COSTS_N_INSNS (2);
21197 else
21198 /* Shift */
21199 *total = COSTS_N_INSNS (1);
21201 else
21203 if (GET_MODE (XEXP (x, 1)) == DImode)
21204 *total = rs6000_cost->divdi;
21205 else
21206 *total = rs6000_cost->divsi;
21208 /* Add in shift and subtract for MOD. */
21209 if (code == MOD || code == UMOD)
21210 *total += COSTS_N_INSNS (2);
21211 return false;
21213 case CTZ:
21214 case FFS:
21215 *total = COSTS_N_INSNS (4);
21216 return false;
21218 case POPCOUNT:
21219 *total = COSTS_N_INSNS (6);
21220 return false;
21222 case NOT:
21223 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
21225 *total = 0;
21226 return false;
21228 /* FALLTHRU */
21230 case AND:
21231 case CLZ:
21232 case IOR:
21233 case XOR:
21234 case ZERO_EXTRACT:
21235 *total = COSTS_N_INSNS (1);
21236 return false;
21238 case ASHIFT:
21239 case ASHIFTRT:
21240 case LSHIFTRT:
21241 case ROTATE:
21242 case ROTATERT:
21243 /* Handle mul_highpart. */
21244 if (outer_code == TRUNCATE
21245 && GET_CODE (XEXP (x, 0)) == MULT)
21247 if (mode == DImode)
21248 *total = rs6000_cost->muldi;
21249 else
21250 *total = rs6000_cost->mulsi;
21251 return true;
21253 else if (outer_code == AND)
21254 *total = 0;
21255 else
21256 *total = COSTS_N_INSNS (1);
21257 return false;
21259 case SIGN_EXTEND:
21260 case ZERO_EXTEND:
21261 if (GET_CODE (XEXP (x, 0)) == MEM)
21262 *total = 0;
21263 else
21264 *total = COSTS_N_INSNS (1);
21265 return false;
21267 case COMPARE:
21268 case NEG:
21269 case ABS:
21270 if (!FLOAT_MODE_P (mode))
21272 *total = COSTS_N_INSNS (1);
21273 return false;
21275 /* FALLTHRU */
21277 case FLOAT:
21278 case UNSIGNED_FLOAT:
21279 case FIX:
21280 case UNSIGNED_FIX:
21281 case FLOAT_TRUNCATE:
21282 *total = rs6000_cost->fp;
21283 return false;
21285 case FLOAT_EXTEND:
21286 if (mode == DFmode)
21287 *total = 0;
21288 else
21289 *total = rs6000_cost->fp;
21290 return false;
21292 case UNSPEC:
21293 switch (XINT (x, 1))
21295 case UNSPEC_FRSP:
21296 *total = rs6000_cost->fp;
21297 return true;
21299 default:
21300 break;
21302 break;
21304 case CALL:
21305 case IF_THEN_ELSE:
21306 if (optimize_size)
21308 *total = COSTS_N_INSNS (1);
21309 return true;
21311 else if (FLOAT_MODE_P (mode)
21312 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
21314 *total = rs6000_cost->fp;
21315 return false;
21317 break;
21319 case EQ:
21320 case GTU:
21321 case LTU:
21322 /* Carry bit requires mode == Pmode.
21323 NEG or PLUS already counted so only add one. */
21324 if (mode == Pmode
21325 && (outer_code == NEG || outer_code == PLUS))
21327 *total = COSTS_N_INSNS (1);
21328 return true;
21330 if (outer_code == SET)
21332 if (XEXP (x, 1) == const0_rtx)
21334 *total = COSTS_N_INSNS (2);
21335 return true;
21337 else if (mode == Pmode)
21339 *total = COSTS_N_INSNS (3);
21340 return false;
21343 /* FALLTHRU */
21345 case GT:
21346 case LT:
21347 case UNORDERED:
21348 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
21350 *total = COSTS_N_INSNS (2);
21351 return true;
21353 /* CC COMPARE. */
21354 if (outer_code == COMPARE)
21356 *total = 0;
21357 return true;
21359 break;
21361 default:
21362 break;
21365 return false;
21368 /* A C expression returning the cost of moving data from a register of class
21369 CLASS1 to one of CLASS2. */
21372 rs6000_register_move_cost (enum machine_mode mode,
21373 enum reg_class from, enum reg_class to)
21375 /* Moves from/to GENERAL_REGS. */
21376 if (reg_classes_intersect_p (to, GENERAL_REGS)
21377 || reg_classes_intersect_p (from, GENERAL_REGS))
21379 if (! reg_classes_intersect_p (to, GENERAL_REGS))
21380 from = to;
21382 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
21383 return (rs6000_memory_move_cost (mode, from, 0)
21384 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
21386 /* It's more expensive to move CR_REGS than CR0_REGS because of the
21387 shift. */
21388 else if (from == CR_REGS)
21389 return 4;
21391 /* Power6 has slower LR/CTR moves so make them more expensive than
21392 memory in order to bias spills to memory .*/
21393 else if (rs6000_cpu == PROCESSOR_POWER6
21394 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
21395 return 6 * hard_regno_nregs[0][mode];
21397 else
21398 /* A move will cost one instruction per GPR moved. */
21399 return 2 * hard_regno_nregs[0][mode];
21402 /* Moving between two similar registers is just one instruction. */
21403 else if (reg_classes_intersect_p (to, from))
21404 return (mode == TFmode || mode == TDmode) ? 4 : 2;
21406 /* Everything else has to go through GENERAL_REGS. */
21407 else
21408 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
21409 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
21412 /* A C expressions returning the cost of moving data of MODE from a register to
21413 or from memory. */
21416 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
21417 int in ATTRIBUTE_UNUSED)
21419 if (reg_classes_intersect_p (class, GENERAL_REGS))
21420 return 4 * hard_regno_nregs[0][mode];
21421 else if (reg_classes_intersect_p (class, FLOAT_REGS))
21422 return 4 * hard_regno_nregs[32][mode];
21423 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
21424 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
21425 else
21426 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
21429 /* Returns a code for a target-specific builtin that implements
21430 reciprocal of the function, or NULL_TREE if not available. */
21432 static tree
21433 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
21434 bool sqrt ATTRIBUTE_UNUSED)
21436 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
21437 && flag_finite_math_only && !flag_trapping_math
21438 && flag_unsafe_math_optimizations))
21439 return NULL_TREE;
21441 if (md_fn)
21442 return NULL_TREE;
21443 else
21444 switch (fn)
21446 case BUILT_IN_SQRTF:
21447 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
21449 default:
21450 return NULL_TREE;
21454 /* Newton-Raphson approximation of single-precision floating point divide n/d.
21455 Assumes no trapping math and finite arguments. */
21457 void
21458 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
21460 rtx x0, e0, e1, y1, u0, v0, one;
21462 x0 = gen_reg_rtx (SFmode);
21463 e0 = gen_reg_rtx (SFmode);
21464 e1 = gen_reg_rtx (SFmode);
21465 y1 = gen_reg_rtx (SFmode);
21466 u0 = gen_reg_rtx (SFmode);
21467 v0 = gen_reg_rtx (SFmode);
21468 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
21470 /* x0 = 1./d estimate */
21471 emit_insn (gen_rtx_SET (VOIDmode, x0,
21472 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
21473 UNSPEC_FRES)));
21474 /* e0 = 1. - d * x0 */
21475 emit_insn (gen_rtx_SET (VOIDmode, e0,
21476 gen_rtx_MINUS (SFmode, one,
21477 gen_rtx_MULT (SFmode, d, x0))));
21478 /* e1 = e0 + e0 * e0 */
21479 emit_insn (gen_rtx_SET (VOIDmode, e1,
21480 gen_rtx_PLUS (SFmode,
21481 gen_rtx_MULT (SFmode, e0, e0), e0)));
21482 /* y1 = x0 + e1 * x0 */
21483 emit_insn (gen_rtx_SET (VOIDmode, y1,
21484 gen_rtx_PLUS (SFmode,
21485 gen_rtx_MULT (SFmode, e1, x0), x0)));
21486 /* u0 = n * y1 */
21487 emit_insn (gen_rtx_SET (VOIDmode, u0,
21488 gen_rtx_MULT (SFmode, n, y1)));
21489 /* v0 = n - d * u0 */
21490 emit_insn (gen_rtx_SET (VOIDmode, v0,
21491 gen_rtx_MINUS (SFmode, n,
21492 gen_rtx_MULT (SFmode, d, u0))));
21493 /* dst = u0 + v0 * y1 */
21494 emit_insn (gen_rtx_SET (VOIDmode, dst,
21495 gen_rtx_PLUS (SFmode,
21496 gen_rtx_MULT (SFmode, v0, y1), u0)));
21499 /* Newton-Raphson approximation of double-precision floating point divide n/d.
21500 Assumes no trapping math and finite arguments. */
21502 void
21503 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
21505 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
21507 x0 = gen_reg_rtx (DFmode);
21508 e0 = gen_reg_rtx (DFmode);
21509 e1 = gen_reg_rtx (DFmode);
21510 e2 = gen_reg_rtx (DFmode);
21511 y1 = gen_reg_rtx (DFmode);
21512 y2 = gen_reg_rtx (DFmode);
21513 y3 = gen_reg_rtx (DFmode);
21514 u0 = gen_reg_rtx (DFmode);
21515 v0 = gen_reg_rtx (DFmode);
21516 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
21518 /* x0 = 1./d estimate */
21519 emit_insn (gen_rtx_SET (VOIDmode, x0,
21520 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
21521 UNSPEC_FRES)));
21522 /* e0 = 1. - d * x0 */
21523 emit_insn (gen_rtx_SET (VOIDmode, e0,
21524 gen_rtx_MINUS (DFmode, one,
21525 gen_rtx_MULT (SFmode, d, x0))));
21526 /* y1 = x0 + e0 * x0 */
21527 emit_insn (gen_rtx_SET (VOIDmode, y1,
21528 gen_rtx_PLUS (DFmode,
21529 gen_rtx_MULT (DFmode, e0, x0), x0)));
21530 /* e1 = e0 * e0 */
21531 emit_insn (gen_rtx_SET (VOIDmode, e1,
21532 gen_rtx_MULT (DFmode, e0, e0)));
21533 /* y2 = y1 + e1 * y1 */
21534 emit_insn (gen_rtx_SET (VOIDmode, y2,
21535 gen_rtx_PLUS (DFmode,
21536 gen_rtx_MULT (DFmode, e1, y1), y1)));
21537 /* e2 = e1 * e1 */
21538 emit_insn (gen_rtx_SET (VOIDmode, e2,
21539 gen_rtx_MULT (DFmode, e1, e1)));
21540 /* y3 = y2 + e2 * y2 */
21541 emit_insn (gen_rtx_SET (VOIDmode, y3,
21542 gen_rtx_PLUS (DFmode,
21543 gen_rtx_MULT (DFmode, e2, y2), y2)));
21544 /* u0 = n * y3 */
21545 emit_insn (gen_rtx_SET (VOIDmode, u0,
21546 gen_rtx_MULT (DFmode, n, y3)));
21547 /* v0 = n - d * u0 */
21548 emit_insn (gen_rtx_SET (VOIDmode, v0,
21549 gen_rtx_MINUS (DFmode, n,
21550 gen_rtx_MULT (DFmode, d, u0))));
21551 /* dst = u0 + v0 * y3 */
21552 emit_insn (gen_rtx_SET (VOIDmode, dst,
21553 gen_rtx_PLUS (DFmode,
21554 gen_rtx_MULT (DFmode, v0, y3), u0)));
21558 /* Newton-Raphson approximation of single-precision floating point rsqrt.
21559 Assumes no trapping math and finite arguments. */
21561 void
21562 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
21564 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
21565 half, one, halfthree, c1, cond, label;
21567 x0 = gen_reg_rtx (SFmode);
21568 x1 = gen_reg_rtx (SFmode);
21569 x2 = gen_reg_rtx (SFmode);
21570 y1 = gen_reg_rtx (SFmode);
21571 u0 = gen_reg_rtx (SFmode);
21572 u1 = gen_reg_rtx (SFmode);
21573 u2 = gen_reg_rtx (SFmode);
21574 v0 = gen_reg_rtx (SFmode);
21575 v1 = gen_reg_rtx (SFmode);
21576 v2 = gen_reg_rtx (SFmode);
21577 t0 = gen_reg_rtx (SFmode);
21578 halfthree = gen_reg_rtx (SFmode);
21579 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
21580 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
21582 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
21583 emit_insn (gen_rtx_SET (VOIDmode, t0,
21584 gen_rtx_MULT (SFmode, src, src)));
21586 emit_insn (gen_rtx_SET (VOIDmode, cond,
21587 gen_rtx_COMPARE (CCFPmode, t0, src)));
21588 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
21589 emit_unlikely_jump (c1, label);
21591 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
21592 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
21594 /* halfthree = 1.5 = 1.0 + 0.5 */
21595 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
21596 gen_rtx_PLUS (SFmode, one, half)));
21598 /* x0 = rsqrt estimate */
21599 emit_insn (gen_rtx_SET (VOIDmode, x0,
21600 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
21601 UNSPEC_RSQRT)));
21603 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
21604 emit_insn (gen_rtx_SET (VOIDmode, y1,
21605 gen_rtx_MINUS (SFmode,
21606 gen_rtx_MULT (SFmode, src, halfthree),
21607 src)));
21609 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
21610 emit_insn (gen_rtx_SET (VOIDmode, u0,
21611 gen_rtx_MULT (SFmode, x0, x0)));
21612 emit_insn (gen_rtx_SET (VOIDmode, v0,
21613 gen_rtx_MINUS (SFmode,
21614 halfthree,
21615 gen_rtx_MULT (SFmode, y1, u0))));
21616 emit_insn (gen_rtx_SET (VOIDmode, x1,
21617 gen_rtx_MULT (SFmode, x0, v0)));
21619 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
21620 emit_insn (gen_rtx_SET (VOIDmode, u1,
21621 gen_rtx_MULT (SFmode, x1, x1)));
21622 emit_insn (gen_rtx_SET (VOIDmode, v1,
21623 gen_rtx_MINUS (SFmode,
21624 halfthree,
21625 gen_rtx_MULT (SFmode, y1, u1))));
21626 emit_insn (gen_rtx_SET (VOIDmode, x2,
21627 gen_rtx_MULT (SFmode, x1, v1)));
21629 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
21630 emit_insn (gen_rtx_SET (VOIDmode, u2,
21631 gen_rtx_MULT (SFmode, x2, x2)));
21632 emit_insn (gen_rtx_SET (VOIDmode, v2,
21633 gen_rtx_MINUS (SFmode,
21634 halfthree,
21635 gen_rtx_MULT (SFmode, y1, u2))));
21636 emit_insn (gen_rtx_SET (VOIDmode, dst,
21637 gen_rtx_MULT (SFmode, x2, v2)));
21639 emit_label (XEXP (label, 0));
21642 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
21643 target, and SRC is the argument operand. */
21645 void
21646 rs6000_emit_popcount (rtx dst, rtx src)
21648 enum machine_mode mode = GET_MODE (dst);
21649 rtx tmp1, tmp2;
21651 tmp1 = gen_reg_rtx (mode);
21653 if (mode == SImode)
21655 emit_insn (gen_popcntbsi2 (tmp1, src));
21656 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
21657 NULL_RTX, 0);
21658 tmp2 = force_reg (SImode, tmp2);
21659 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
21661 else
21663 emit_insn (gen_popcntbdi2 (tmp1, src));
21664 tmp2 = expand_mult (DImode, tmp1,
21665 GEN_INT ((HOST_WIDE_INT)
21666 0x01010101 << 32 | 0x01010101),
21667 NULL_RTX, 0);
21668 tmp2 = force_reg (DImode, tmp2);
21669 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
21674 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
21675 target, and SRC is the argument operand. */
21677 void
21678 rs6000_emit_parity (rtx dst, rtx src)
21680 enum machine_mode mode = GET_MODE (dst);
21681 rtx tmp;
21683 tmp = gen_reg_rtx (mode);
21684 if (mode == SImode)
21686 /* Is mult+shift >= shift+xor+shift+xor? */
21687 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
21689 rtx tmp1, tmp2, tmp3, tmp4;
21691 tmp1 = gen_reg_rtx (SImode);
21692 emit_insn (gen_popcntbsi2 (tmp1, src));
21694 tmp2 = gen_reg_rtx (SImode);
21695 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
21696 tmp3 = gen_reg_rtx (SImode);
21697 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
21699 tmp4 = gen_reg_rtx (SImode);
21700 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
21701 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
21703 else
21704 rs6000_emit_popcount (tmp, src);
21705 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
21707 else
21709 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
21710 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
21712 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
21714 tmp1 = gen_reg_rtx (DImode);
21715 emit_insn (gen_popcntbdi2 (tmp1, src));
21717 tmp2 = gen_reg_rtx (DImode);
21718 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
21719 tmp3 = gen_reg_rtx (DImode);
21720 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
21722 tmp4 = gen_reg_rtx (DImode);
21723 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
21724 tmp5 = gen_reg_rtx (DImode);
21725 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
21727 tmp6 = gen_reg_rtx (DImode);
21728 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
21729 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
21731 else
21732 rs6000_emit_popcount (tmp, src);
21733 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
21737 /* Return an RTX representing where to find the function value of a
21738 function returning MODE. */
21739 static rtx
21740 rs6000_complex_function_value (enum machine_mode mode)
21742 unsigned int regno;
21743 rtx r1, r2;
21744 enum machine_mode inner = GET_MODE_INNER (mode);
21745 unsigned int inner_bytes = GET_MODE_SIZE (inner);
21747 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
21748 regno = FP_ARG_RETURN;
21749 else
21751 regno = GP_ARG_RETURN;
21753 /* 32-bit is OK since it'll go in r3/r4. */
21754 if (TARGET_32BIT && inner_bytes >= 4)
21755 return gen_rtx_REG (mode, regno);
21758 if (inner_bytes >= 8)
21759 return gen_rtx_REG (mode, regno);
21761 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
21762 const0_rtx);
21763 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
21764 GEN_INT (inner_bytes));
21765 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
21768 /* Define how to find the value returned by a function.
21769 VALTYPE is the data type of the value (as a tree).
21770 If the precise function being called is known, FUNC is its FUNCTION_DECL;
21771 otherwise, FUNC is 0.
21773 On the SPE, both FPs and vectors are returned in r3.
21775 On RS/6000 an integer value is in r3 and a floating-point value is in
21776 fp1, unless -msoft-float. */
21779 rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
21781 enum machine_mode mode;
21782 unsigned int regno;
21784 /* Special handling for structs in darwin64. */
21785 if (rs6000_darwin64_abi
21786 && TYPE_MODE (valtype) == BLKmode
21787 && TREE_CODE (valtype) == RECORD_TYPE
21788 && int_size_in_bytes (valtype) > 0)
21790 CUMULATIVE_ARGS valcum;
21791 rtx valret;
21793 valcum.words = 0;
21794 valcum.fregno = FP_ARG_MIN_REG;
21795 valcum.vregno = ALTIVEC_ARG_MIN_REG;
21796 /* Do a trial code generation as if this were going to be passed as
21797 an argument; if any part goes in memory, we return NULL. */
21798 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
21799 if (valret)
21800 return valret;
21801 /* Otherwise fall through to standard ABI rules. */
21804 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
21806 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21807 return gen_rtx_PARALLEL (DImode,
21808 gen_rtvec (2,
21809 gen_rtx_EXPR_LIST (VOIDmode,
21810 gen_rtx_REG (SImode, GP_ARG_RETURN),
21811 const0_rtx),
21812 gen_rtx_EXPR_LIST (VOIDmode,
21813 gen_rtx_REG (SImode,
21814 GP_ARG_RETURN + 1),
21815 GEN_INT (4))));
21817 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
21819 return gen_rtx_PARALLEL (DCmode,
21820 gen_rtvec (4,
21821 gen_rtx_EXPR_LIST (VOIDmode,
21822 gen_rtx_REG (SImode, GP_ARG_RETURN),
21823 const0_rtx),
21824 gen_rtx_EXPR_LIST (VOIDmode,
21825 gen_rtx_REG (SImode,
21826 GP_ARG_RETURN + 1),
21827 GEN_INT (4)),
21828 gen_rtx_EXPR_LIST (VOIDmode,
21829 gen_rtx_REG (SImode,
21830 GP_ARG_RETURN + 2),
21831 GEN_INT (8)),
21832 gen_rtx_EXPR_LIST (VOIDmode,
21833 gen_rtx_REG (SImode,
21834 GP_ARG_RETURN + 3),
21835 GEN_INT (12))));
21838 mode = TYPE_MODE (valtype);
21839 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
21840 || POINTER_TYPE_P (valtype))
21841 mode = TARGET_32BIT ? SImode : DImode;
21843 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
21844 /* _Decimal128 must use an even/odd register pair. */
21845 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
21846 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
21847 regno = FP_ARG_RETURN;
21848 else if (TREE_CODE (valtype) == COMPLEX_TYPE
21849 && targetm.calls.split_complex_arg)
21850 return rs6000_complex_function_value (mode);
21851 else if (TREE_CODE (valtype) == VECTOR_TYPE
21852 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
21853 && ALTIVEC_VECTOR_MODE (mode))
21854 regno = ALTIVEC_ARG_RETURN;
21855 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
21856 && (mode == DFmode || mode == DDmode || mode == DCmode
21857 || mode == TFmode || mode == TDmode || mode == TCmode))
21858 return spe_build_register_parallel (mode, GP_ARG_RETURN);
21859 else
21860 regno = GP_ARG_RETURN;
21862 return gen_rtx_REG (mode, regno);
21865 /* Define how to find the value returned by a library function
21866 assuming the value has mode MODE. */
21868 rs6000_libcall_value (enum machine_mode mode)
21870 unsigned int regno;
21872 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
21874 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21875 return gen_rtx_PARALLEL (DImode,
21876 gen_rtvec (2,
21877 gen_rtx_EXPR_LIST (VOIDmode,
21878 gen_rtx_REG (SImode, GP_ARG_RETURN),
21879 const0_rtx),
21880 gen_rtx_EXPR_LIST (VOIDmode,
21881 gen_rtx_REG (SImode,
21882 GP_ARG_RETURN + 1),
21883 GEN_INT (4))));
21886 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
21887 /* _Decimal128 must use an even/odd register pair. */
21888 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
21889 else if (SCALAR_FLOAT_MODE_P (mode)
21890 && TARGET_HARD_FLOAT && TARGET_FPRS)
21891 regno = FP_ARG_RETURN;
21892 else if (ALTIVEC_VECTOR_MODE (mode)
21893 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
21894 regno = ALTIVEC_ARG_RETURN;
21895 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
21896 return rs6000_complex_function_value (mode);
21897 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
21898 && (mode == DFmode || mode == DDmode || mode == DCmode
21899 || mode == TFmode || mode == TDmode || mode == TCmode))
21900 return spe_build_register_parallel (mode, GP_ARG_RETURN);
21901 else
21902 regno = GP_ARG_RETURN;
21904 return gen_rtx_REG (mode, regno);
21907 /* Define the offset between two registers, FROM to be eliminated and its
21908 replacement TO, at the start of a routine. */
21909 HOST_WIDE_INT
21910 rs6000_initial_elimination_offset (int from, int to)
21912 rs6000_stack_t *info = rs6000_stack_info ();
21913 HOST_WIDE_INT offset;
21915 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
21916 offset = info->push_p ? 0 : -info->total_size;
21917 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
21919 offset = info->push_p ? 0 : -info->total_size;
21920 if (FRAME_GROWS_DOWNWARD)
21921 offset += info->fixed_size + info->vars_size + info->parm_size;
21923 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
21924 offset = FRAME_GROWS_DOWNWARD
21925 ? info->fixed_size + info->vars_size + info->parm_size
21926 : 0;
21927 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
21928 offset = info->total_size;
21929 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
21930 offset = info->push_p ? info->total_size : 0;
21931 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
21932 offset = 0;
21933 else
21934 gcc_unreachable ();
21936 return offset;
21939 /* Return true if TYPE is a SPE or AltiVec opaque type. */
21941 static bool
21942 rs6000_is_opaque_type (const_tree type)
21944 return (type == opaque_V2SI_type_node
21945 || type == opaque_V2SF_type_node
21946 || type == opaque_p_V2SI_type_node
21947 || type == opaque_V4SI_type_node);
21950 static rtx
21951 rs6000_dwarf_register_span (rtx reg)
21953 unsigned regno;
21955 if (TARGET_SPE
21956 && (SPE_VECTOR_MODE (GET_MODE (reg))
21957 || (TARGET_E500_DOUBLE
21958 && (GET_MODE (reg) == DFmode || GET_MODE (reg) == DDmode))))
21960 else
21961 return NULL_RTX;
21963 regno = REGNO (reg);
21965 /* The duality of the SPE register size wreaks all kinds of havoc.
21966 This is a way of distinguishing r0 in 32-bits from r0 in
21967 64-bits. */
21968 return
21969 gen_rtx_PARALLEL (VOIDmode,
21970 BYTES_BIG_ENDIAN
21971 ? gen_rtvec (2,
21972 gen_rtx_REG (SImode, regno + 1200),
21973 gen_rtx_REG (SImode, regno))
21974 : gen_rtvec (2,
21975 gen_rtx_REG (SImode, regno),
21976 gen_rtx_REG (SImode, regno + 1200)));
21979 /* Fill in sizes for SPE register high parts in table used by unwinder. */
21981 static void
21982 rs6000_init_dwarf_reg_sizes_extra (tree address)
21984 if (TARGET_SPE)
21986 int i;
21987 enum machine_mode mode = TYPE_MODE (char_type_node);
21988 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
21989 rtx mem = gen_rtx_MEM (BLKmode, addr);
21990 rtx value = gen_int_mode (4, mode);
21992 for (i = 1201; i < 1232; i++)
21994 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
21995 HOST_WIDE_INT offset
21996 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
21998 emit_move_insn (adjust_address (mem, mode, offset), value);
22003 /* Map internal gcc register numbers to DWARF2 register numbers. */
22005 unsigned int
22006 rs6000_dbx_register_number (unsigned int regno)
22008 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
22009 return regno;
22010 if (regno == MQ_REGNO)
22011 return 100;
22012 if (regno == LR_REGNO)
22013 return 108;
22014 if (regno == CTR_REGNO)
22015 return 109;
22016 if (CR_REGNO_P (regno))
22017 return regno - CR0_REGNO + 86;
22018 if (regno == XER_REGNO)
22019 return 101;
22020 if (ALTIVEC_REGNO_P (regno))
22021 return regno - FIRST_ALTIVEC_REGNO + 1124;
22022 if (regno == VRSAVE_REGNO)
22023 return 356;
22024 if (regno == VSCR_REGNO)
22025 return 67;
22026 if (regno == SPE_ACC_REGNO)
22027 return 99;
22028 if (regno == SPEFSCR_REGNO)
22029 return 612;
22030 /* SPE high reg number. We get these values of regno from
22031 rs6000_dwarf_register_span. */
22032 gcc_assert (regno >= 1200 && regno < 1232);
22033 return regno;
22036 /* target hook eh_return_filter_mode */
22037 static enum machine_mode
22038 rs6000_eh_return_filter_mode (void)
22040 return TARGET_32BIT ? SImode : word_mode;
22043 /* Target hook for scalar_mode_supported_p. */
22044 static bool
22045 rs6000_scalar_mode_supported_p (enum machine_mode mode)
22047 if (DECIMAL_FLOAT_MODE_P (mode))
22048 return true;
22049 else
22050 return default_scalar_mode_supported_p (mode);
22053 /* Target hook for vector_mode_supported_p. */
22054 static bool
22055 rs6000_vector_mode_supported_p (enum machine_mode mode)
22058 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
22059 return true;
22061 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
22062 return true;
22064 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
22065 return true;
22067 else
22068 return false;
22071 /* Target hook for invalid_arg_for_unprototyped_fn. */
22072 static const char *
22073 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
22075 return (!rs6000_darwin64_abi
22076 && typelist == 0
22077 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
22078 && (funcdecl == NULL_TREE
22079 || (TREE_CODE (funcdecl) == FUNCTION_DECL
22080 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
22081 ? N_("AltiVec argument passed to unprototyped function")
22082 : NULL;
22085 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
22086 setup by using __stack_chk_fail_local hidden function instead of
22087 calling __stack_chk_fail directly. Otherwise it is better to call
22088 __stack_chk_fail directly. */
22090 static tree
22091 rs6000_stack_protect_fail (void)
22093 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
22094 ? default_hidden_stack_protect_fail ()
22095 : default_external_stack_protect_fail ();
22098 #include "gt-rs6000.h"