2008-05-30 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob1eafc999fde43acdf2096bc73a8cb66450f46db6
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 tga = rs6000_tls_get_addr ();
3902 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
3903 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
3904 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
3905 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
3906 else if (DEFAULT_ABI == ABI_V4)
3907 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
3908 else
3909 gcc_unreachable ();
3911 start_sequence ();
3912 insn = emit_call_insn (insn);
3913 RTL_CONST_CALL_P (insn) = 1;
3914 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3915 insn = get_insns ();
3916 end_sequence ();
3917 emit_libcall_block (insn, dest, r3, addr);
3919 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3921 r3 = gen_rtx_REG (Pmode, 3);
3922 tga = rs6000_tls_get_addr ();
3924 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
3925 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
3926 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
3927 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
3928 else if (DEFAULT_ABI == ABI_V4)
3929 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
3930 else
3931 gcc_unreachable ();
3933 start_sequence ();
3934 insn = emit_call_insn (insn);
3935 RTL_CONST_CALL_P (insn) = 1;
3936 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3937 insn = get_insns ();
3938 end_sequence ();
3939 tmp1 = gen_reg_rtx (Pmode);
3940 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3941 UNSPEC_TLSLD);
3942 emit_libcall_block (insn, tmp1, r3, eqv);
3943 if (rs6000_tls_size == 16)
3945 if (TARGET_64BIT)
3946 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3947 else
3948 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3950 else if (rs6000_tls_size == 32)
3952 tmp2 = gen_reg_rtx (Pmode);
3953 if (TARGET_64BIT)
3954 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3955 else
3956 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3957 emit_insn (insn);
3958 if (TARGET_64BIT)
3959 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3960 else
3961 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3963 else
3965 tmp2 = gen_reg_rtx (Pmode);
3966 if (TARGET_64BIT)
3967 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3968 else
3969 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3970 emit_insn (insn);
3971 insn = gen_rtx_SET (Pmode, dest,
3972 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3974 emit_insn (insn);
3976 else
3978 /* IE, or 64-bit offset LE. */
3979 tmp2 = gen_reg_rtx (Pmode);
3980 if (TARGET_64BIT)
3981 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3982 else
3983 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3984 emit_insn (insn);
3985 if (TARGET_64BIT)
3986 insn = gen_tls_tls_64 (dest, tmp2, addr);
3987 else
3988 insn = gen_tls_tls_32 (dest, tmp2, addr);
3989 emit_insn (insn);
3993 return dest;
3996 /* Return 1 if X contains a thread-local symbol. */
3998 bool
3999 rs6000_tls_referenced_p (rtx x)
4001 if (! TARGET_HAVE_TLS)
4002 return false;
4004 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
4007 /* Return 1 if *X is a thread-local symbol. This is the same as
4008 rs6000_tls_symbol_ref except for the type of the unused argument. */
4010 static int
4011 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
4013 return RS6000_SYMBOL_REF_TLS_P (*x);
4016 /* The convention appears to be to define this wherever it is used.
4017 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
4018 is now used here. */
4019 #ifndef REG_MODE_OK_FOR_BASE_P
4020 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
4021 #endif
4023 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
4024 replace the input X, or the original X if no replacement is called for.
4025 The output parameter *WIN is 1 if the calling macro should goto WIN,
4026 0 if it should not.
4028 For RS/6000, we wish to handle large displacements off a base
4029 register by splitting the addend across an addiu/addis and the mem insn.
4030 This cuts number of extra insns needed from 3 to 1.
4032 On Darwin, we use this to generate code for floating point constants.
4033 A movsf_low is generated so we wind up with 2 instructions rather than 3.
4034 The Darwin code is inside #if TARGET_MACHO because only then is
4035 machopic_function_base_name() defined. */
4037 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
4038 int opnum, int type,
4039 int ind_levels ATTRIBUTE_UNUSED, int *win)
4041 /* We must recognize output that we have already generated ourselves. */
4042 if (GET_CODE (x) == PLUS
4043 && GET_CODE (XEXP (x, 0)) == PLUS
4044 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
4045 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4046 && GET_CODE (XEXP (x, 1)) == CONST_INT)
4048 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4049 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
4050 opnum, (enum reload_type)type);
4051 *win = 1;
4052 return x;
4055 #if TARGET_MACHO
4056 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
4057 && GET_CODE (x) == LO_SUM
4058 && GET_CODE (XEXP (x, 0)) == PLUS
4059 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
4060 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
4061 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
4062 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
4063 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
4064 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
4065 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
4067 /* Result of previous invocation of this function on Darwin
4068 floating point constant. */
4069 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4070 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
4071 opnum, (enum reload_type)type);
4072 *win = 1;
4073 return x;
4075 #endif
4077 /* Force ld/std non-word aligned offset into base register by wrapping
4078 in offset 0. */
4079 if (GET_CODE (x) == PLUS
4080 && GET_CODE (XEXP (x, 0)) == REG
4081 && REGNO (XEXP (x, 0)) < 32
4082 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
4083 && GET_CODE (XEXP (x, 1)) == CONST_INT
4084 && (INTVAL (XEXP (x, 1)) & 3) != 0
4085 && !ALTIVEC_VECTOR_MODE (mode)
4086 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
4087 && TARGET_POWERPC64)
4089 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
4090 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4091 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
4092 opnum, (enum reload_type) type);
4093 *win = 1;
4094 return x;
4097 if (GET_CODE (x) == PLUS
4098 && GET_CODE (XEXP (x, 0)) == REG
4099 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
4100 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
4101 && GET_CODE (XEXP (x, 1)) == CONST_INT
4102 && !SPE_VECTOR_MODE (mode)
4103 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4104 || mode == DDmode || mode == TDmode
4105 || mode == DImode))
4106 && !ALTIVEC_VECTOR_MODE (mode))
4108 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
4109 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
4110 HOST_WIDE_INT high
4111 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
4113 /* Check for 32-bit overflow. */
4114 if (high + low != val)
4116 *win = 0;
4117 return x;
4120 /* Reload the high part into a base reg; leave the low part
4121 in the mem directly. */
4123 x = gen_rtx_PLUS (GET_MODE (x),
4124 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
4125 GEN_INT (high)),
4126 GEN_INT (low));
4128 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4129 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
4130 opnum, (enum reload_type)type);
4131 *win = 1;
4132 return x;
4135 if (GET_CODE (x) == SYMBOL_REF
4136 && !ALTIVEC_VECTOR_MODE (mode)
4137 && !SPE_VECTOR_MODE (mode)
4138 #if TARGET_MACHO
4139 && DEFAULT_ABI == ABI_DARWIN
4140 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
4141 #else
4142 && DEFAULT_ABI == ABI_V4
4143 && !flag_pic
4144 #endif
4145 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
4146 The same goes for DImode without 64-bit gprs and DFmode and DDmode
4147 without fprs. */
4148 && mode != TFmode
4149 && mode != TDmode
4150 && (mode != DImode || TARGET_POWERPC64)
4151 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
4152 || (TARGET_FPRS && TARGET_HARD_FLOAT)))
4154 #if TARGET_MACHO
4155 if (flag_pic)
4157 rtx offset = gen_rtx_CONST (Pmode,
4158 gen_rtx_MINUS (Pmode, x,
4159 machopic_function_base_sym ()));
4160 x = gen_rtx_LO_SUM (GET_MODE (x),
4161 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
4162 gen_rtx_HIGH (Pmode, offset)), offset);
4164 else
4165 #endif
4166 x = gen_rtx_LO_SUM (GET_MODE (x),
4167 gen_rtx_HIGH (Pmode, x), x);
4169 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
4170 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
4171 opnum, (enum reload_type)type);
4172 *win = 1;
4173 return x;
4176 /* Reload an offset address wrapped by an AND that represents the
4177 masking of the lower bits. Strip the outer AND and let reload
4178 convert the offset address into an indirect address. */
4179 if (TARGET_ALTIVEC
4180 && ALTIVEC_VECTOR_MODE (mode)
4181 && GET_CODE (x) == AND
4182 && GET_CODE (XEXP (x, 0)) == PLUS
4183 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
4184 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4185 && GET_CODE (XEXP (x, 1)) == CONST_INT
4186 && INTVAL (XEXP (x, 1)) == -16)
4188 x = XEXP (x, 0);
4189 *win = 1;
4190 return x;
4193 if (TARGET_TOC
4194 && constant_pool_expr_p (x)
4195 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
4197 x = create_TOC_reference (x);
4198 *win = 1;
4199 return x;
4201 *win = 0;
4202 return x;
4205 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
4206 that is a valid memory address for an instruction.
4207 The MODE argument is the machine mode for the MEM expression
4208 that wants to use this address.
4210 On the RS/6000, there are four valid address: a SYMBOL_REF that
4211 refers to a constant pool entry of an address (or the sum of it
4212 plus a constant), a short (16-bit signed) constant plus a register,
4213 the sum of two registers, or a register indirect, possibly with an
4214 auto-increment. For DFmode, DDmode and DImode with a constant plus
4215 register, we must ensure that both words are addressable or PowerPC64
4216 with offset word aligned.
4218 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
4219 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
4220 because adjacent memory cells are accessed by adding word-sized offsets
4221 during assembly output. */
4223 rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
4225 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
4226 if (TARGET_ALTIVEC
4227 && ALTIVEC_VECTOR_MODE (mode)
4228 && GET_CODE (x) == AND
4229 && GET_CODE (XEXP (x, 1)) == CONST_INT
4230 && INTVAL (XEXP (x, 1)) == -16)
4231 x = XEXP (x, 0);
4233 if (RS6000_SYMBOL_REF_TLS_P (x))
4234 return 0;
4235 if (legitimate_indirect_address_p (x, reg_ok_strict))
4236 return 1;
4237 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
4238 && !ALTIVEC_VECTOR_MODE (mode)
4239 && !SPE_VECTOR_MODE (mode)
4240 && mode != TFmode
4241 && mode != TDmode
4242 /* Restrict addressing for DI because of our SUBREG hackery. */
4243 && !(TARGET_E500_DOUBLE
4244 && (mode == DFmode || mode == DDmode || mode == DImode))
4245 && TARGET_UPDATE
4246 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
4247 return 1;
4248 if (legitimate_small_data_p (mode, x))
4249 return 1;
4250 if (legitimate_constant_pool_address_p (x))
4251 return 1;
4252 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
4253 if (! reg_ok_strict
4254 && GET_CODE (x) == PLUS
4255 && GET_CODE (XEXP (x, 0)) == REG
4256 && (XEXP (x, 0) == virtual_stack_vars_rtx
4257 || XEXP (x, 0) == arg_pointer_rtx)
4258 && GET_CODE (XEXP (x, 1)) == CONST_INT)
4259 return 1;
4260 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
4261 return 1;
4262 if (mode != TImode
4263 && mode != TFmode
4264 && mode != TDmode
4265 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
4266 || TARGET_POWERPC64
4267 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
4268 && (TARGET_POWERPC64 || mode != DImode)
4269 && legitimate_indexed_address_p (x, reg_ok_strict))
4270 return 1;
4271 if (GET_CODE (x) == PRE_MODIFY
4272 && mode != TImode
4273 && mode != TFmode
4274 && mode != TDmode
4275 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
4276 || TARGET_POWERPC64
4277 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
4278 && (TARGET_POWERPC64 || mode != DImode)
4279 && !ALTIVEC_VECTOR_MODE (mode)
4280 && !SPE_VECTOR_MODE (mode)
4281 /* Restrict addressing for DI because of our SUBREG hackery. */
4282 && !(TARGET_E500_DOUBLE
4283 && (mode == DFmode || mode == DDmode || mode == DImode))
4284 && TARGET_UPDATE
4285 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
4286 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
4287 || legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict))
4288 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
4289 return 1;
4290 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
4291 return 1;
4292 return 0;
4295 /* Go to LABEL if ADDR (a legitimate address expression)
4296 has an effect that depends on the machine mode it is used for.
4298 On the RS/6000 this is true of all integral offsets (since AltiVec
4299 modes don't allow them) or is a pre-increment or decrement.
4301 ??? Except that due to conceptual problems in offsettable_address_p
4302 we can't really report the problems of integral offsets. So leave
4303 this assuming that the adjustable offset must be valid for the
4304 sub-words of a TFmode operand, which is what we had before. */
4306 bool
4307 rs6000_mode_dependent_address (rtx addr)
4309 switch (GET_CODE (addr))
4311 case PLUS:
4312 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
4314 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
4315 return val + 12 + 0x8000 >= 0x10000;
4317 break;
4319 case LO_SUM:
4320 return true;
4322 case PRE_INC:
4323 case PRE_DEC:
4324 case PRE_MODIFY:
4325 return TARGET_UPDATE;
4327 default:
4328 break;
4331 return false;
4334 /* More elaborate version of recog's offsettable_memref_p predicate
4335 that works around the ??? note of rs6000_mode_dependent_address.
4336 In particular it accepts
4338 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
4340 in 32-bit mode, that the recog predicate rejects. */
4342 bool
4343 rs6000_offsettable_memref_p (rtx op)
4345 if (!MEM_P (op))
4346 return false;
4348 /* First mimic offsettable_memref_p. */
4349 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
4350 return true;
4352 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
4353 the latter predicate knows nothing about the mode of the memory
4354 reference and, therefore, assumes that it is the largest supported
4355 mode (TFmode). As a consequence, legitimate offsettable memory
4356 references are rejected. rs6000_legitimate_offset_address_p contains
4357 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
4358 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
4361 /* Return number of consecutive hard regs needed starting at reg REGNO
4362 to hold something of mode MODE.
4363 This is ordinarily the length in words of a value of mode MODE
4364 but can be less for certain modes in special long registers.
4366 For the SPE, GPRs are 64 bits but only 32 bits are visible in
4367 scalar instructions. The upper 32 bits are only available to the
4368 SIMD instructions.
4370 POWER and PowerPC GPRs hold 32 bits worth;
4371 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
4374 rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
4376 if (FP_REGNO_P (regno))
4377 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
4379 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
4380 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
4382 if (ALTIVEC_REGNO_P (regno))
4383 return
4384 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
4386 /* The value returned for SCmode in the E500 double case is 2 for
4387 ABI compatibility; storing an SCmode value in a single register
4388 would require function_arg and rs6000_spe_function_arg to handle
4389 SCmode so as to pass the value correctly in a pair of
4390 registers. */
4391 if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode)
4392 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
4394 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4397 /* Change register usage conditional on target flags. */
4398 void
4399 rs6000_conditional_register_usage (void)
4401 int i;
4403 /* Set MQ register fixed (already call_used) if not POWER
4404 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
4405 be allocated. */
4406 if (! TARGET_POWER)
4407 fixed_regs[64] = 1;
4409 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
4410 if (TARGET_64BIT)
4411 fixed_regs[13] = call_used_regs[13]
4412 = call_really_used_regs[13] = 1;
4414 /* Conditionally disable FPRs. */
4415 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
4416 for (i = 32; i < 64; i++)
4417 fixed_regs[i] = call_used_regs[i]
4418 = call_really_used_regs[i] = 1;
4420 /* The TOC register is not killed across calls in a way that is
4421 visible to the compiler. */
4422 if (DEFAULT_ABI == ABI_AIX)
4423 call_really_used_regs[2] = 0;
4425 if (DEFAULT_ABI == ABI_V4
4426 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
4427 && flag_pic == 2)
4428 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4430 if (DEFAULT_ABI == ABI_V4
4431 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
4432 && flag_pic == 1)
4433 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4434 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4435 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4437 if (DEFAULT_ABI == ABI_DARWIN
4438 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
4439 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4440 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4441 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4443 if (TARGET_TOC && TARGET_MINIMAL_TOC)
4444 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4445 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4447 if (TARGET_SPE)
4449 global_regs[SPEFSCR_REGNO] = 1;
4450 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
4451 registers in prologues and epilogues. We no longer use r14
4452 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
4453 pool for link-compatibility with older versions of GCC. Once
4454 "old" code has died out, we can return r14 to the allocation
4455 pool. */
4456 fixed_regs[14]
4457 = call_used_regs[14]
4458 = call_really_used_regs[14] = 1;
4461 if (!TARGET_ALTIVEC)
4463 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
4464 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
4465 call_really_used_regs[VRSAVE_REGNO] = 1;
4468 if (TARGET_ALTIVEC)
4469 global_regs[VSCR_REGNO] = 1;
4471 if (TARGET_ALTIVEC_ABI)
4473 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
4474 call_used_regs[i] = call_really_used_regs[i] = 1;
4476 /* AIX reserves VR20:31 in non-extended ABI mode. */
4477 if (TARGET_XCOFF)
4478 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
4479 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
4483 /* Try to output insns to set TARGET equal to the constant C if it can
4484 be done in less than N insns. Do all computations in MODE.
4485 Returns the place where the output has been placed if it can be
4486 done and the insns have been emitted. If it would take more than N
4487 insns, zero is returned and no insns and emitted. */
4490 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
4491 rtx source, int n ATTRIBUTE_UNUSED)
4493 rtx result, insn, set;
4494 HOST_WIDE_INT c0, c1;
4496 switch (mode)
4498 case QImode:
4499 case HImode:
4500 if (dest == NULL)
4501 dest = gen_reg_rtx (mode);
4502 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
4503 return dest;
4505 case SImode:
4506 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
4508 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
4509 GEN_INT (INTVAL (source)
4510 & (~ (HOST_WIDE_INT) 0xffff))));
4511 emit_insn (gen_rtx_SET (VOIDmode, dest,
4512 gen_rtx_IOR (SImode, copy_rtx (result),
4513 GEN_INT (INTVAL (source) & 0xffff))));
4514 result = dest;
4515 break;
4517 case DImode:
4518 switch (GET_CODE (source))
4520 case CONST_INT:
4521 c0 = INTVAL (source);
4522 c1 = -(c0 < 0);
4523 break;
4525 case CONST_DOUBLE:
4526 #if HOST_BITS_PER_WIDE_INT >= 64
4527 c0 = CONST_DOUBLE_LOW (source);
4528 c1 = -(c0 < 0);
4529 #else
4530 c0 = CONST_DOUBLE_LOW (source);
4531 c1 = CONST_DOUBLE_HIGH (source);
4532 #endif
4533 break;
4535 default:
4536 gcc_unreachable ();
4539 result = rs6000_emit_set_long_const (dest, c0, c1);
4540 break;
4542 default:
4543 gcc_unreachable ();
4546 insn = get_last_insn ();
4547 set = single_set (insn);
4548 if (! CONSTANT_P (SET_SRC (set)))
4549 set_unique_reg_note (insn, REG_EQUAL, source);
4551 return result;
4554 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4555 fall back to a straight forward decomposition. We do this to avoid
4556 exponential run times encountered when looking for longer sequences
4557 with rs6000_emit_set_const. */
4558 static rtx
4559 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
4561 if (!TARGET_POWERPC64)
4563 rtx operand1, operand2;
4565 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
4566 DImode);
4567 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
4568 DImode);
4569 emit_move_insn (operand1, GEN_INT (c1));
4570 emit_move_insn (operand2, GEN_INT (c2));
4572 else
4574 HOST_WIDE_INT ud1, ud2, ud3, ud4;
4576 ud1 = c1 & 0xffff;
4577 ud2 = (c1 & 0xffff0000) >> 16;
4578 #if HOST_BITS_PER_WIDE_INT >= 64
4579 c2 = c1 >> 32;
4580 #endif
4581 ud3 = c2 & 0xffff;
4582 ud4 = (c2 & 0xffff0000) >> 16;
4584 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
4585 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
4587 if (ud1 & 0x8000)
4588 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
4589 else
4590 emit_move_insn (dest, GEN_INT (ud1));
4593 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
4594 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
4596 if (ud2 & 0x8000)
4597 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
4598 - 0x80000000));
4599 else
4600 emit_move_insn (dest, GEN_INT (ud2 << 16));
4601 if (ud1 != 0)
4602 emit_move_insn (copy_rtx (dest),
4603 gen_rtx_IOR (DImode, copy_rtx (dest),
4604 GEN_INT (ud1)));
4606 else if ((ud4 == 0xffff && (ud3 & 0x8000))
4607 || (ud4 == 0 && ! (ud3 & 0x8000)))
4609 if (ud3 & 0x8000)
4610 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
4611 - 0x80000000));
4612 else
4613 emit_move_insn (dest, GEN_INT (ud3 << 16));
4615 if (ud2 != 0)
4616 emit_move_insn (copy_rtx (dest),
4617 gen_rtx_IOR (DImode, copy_rtx (dest),
4618 GEN_INT (ud2)));
4619 emit_move_insn (copy_rtx (dest),
4620 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4621 GEN_INT (16)));
4622 if (ud1 != 0)
4623 emit_move_insn (copy_rtx (dest),
4624 gen_rtx_IOR (DImode, copy_rtx (dest),
4625 GEN_INT (ud1)));
4627 else
4629 if (ud4 & 0x8000)
4630 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
4631 - 0x80000000));
4632 else
4633 emit_move_insn (dest, GEN_INT (ud4 << 16));
4635 if (ud3 != 0)
4636 emit_move_insn (copy_rtx (dest),
4637 gen_rtx_IOR (DImode, copy_rtx (dest),
4638 GEN_INT (ud3)));
4640 emit_move_insn (copy_rtx (dest),
4641 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4642 GEN_INT (32)));
4643 if (ud2 != 0)
4644 emit_move_insn (copy_rtx (dest),
4645 gen_rtx_IOR (DImode, copy_rtx (dest),
4646 GEN_INT (ud2 << 16)));
4647 if (ud1 != 0)
4648 emit_move_insn (copy_rtx (dest),
4649 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
4652 return dest;
4655 /* Helper for the following. Get rid of [r+r] memory refs
4656 in cases where it won't work (TImode, TFmode, TDmode). */
4658 static void
4659 rs6000_eliminate_indexed_memrefs (rtx operands[2])
4661 if (GET_CODE (operands[0]) == MEM
4662 && GET_CODE (XEXP (operands[0], 0)) != REG
4663 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
4664 && ! reload_in_progress)
4665 operands[0]
4666 = replace_equiv_address (operands[0],
4667 copy_addr_to_reg (XEXP (operands[0], 0)));
4669 if (GET_CODE (operands[1]) == MEM
4670 && GET_CODE (XEXP (operands[1], 0)) != REG
4671 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
4672 && ! reload_in_progress)
4673 operands[1]
4674 = replace_equiv_address (operands[1],
4675 copy_addr_to_reg (XEXP (operands[1], 0)));
4678 /* Emit a move from SOURCE to DEST in mode MODE. */
4679 void
4680 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
4682 rtx operands[2];
4683 operands[0] = dest;
4684 operands[1] = source;
4686 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4687 if (GET_CODE (operands[1]) == CONST_DOUBLE
4688 && ! FLOAT_MODE_P (mode)
4689 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
4691 /* FIXME. This should never happen. */
4692 /* Since it seems that it does, do the safe thing and convert
4693 to a CONST_INT. */
4694 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
4696 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
4697 || FLOAT_MODE_P (mode)
4698 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
4699 || CONST_DOUBLE_LOW (operands[1]) < 0)
4700 && (CONST_DOUBLE_HIGH (operands[1]) != -1
4701 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
4703 /* Check if GCC is setting up a block move that will end up using FP
4704 registers as temporaries. We must make sure this is acceptable. */
4705 if (GET_CODE (operands[0]) == MEM
4706 && GET_CODE (operands[1]) == MEM
4707 && mode == DImode
4708 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
4709 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
4710 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
4711 ? 32 : MEM_ALIGN (operands[0])))
4712 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
4713 ? 32
4714 : MEM_ALIGN (operands[1]))))
4715 && ! MEM_VOLATILE_P (operands [0])
4716 && ! MEM_VOLATILE_P (operands [1]))
4718 emit_move_insn (adjust_address (operands[0], SImode, 0),
4719 adjust_address (operands[1], SImode, 0));
4720 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
4721 adjust_address (copy_rtx (operands[1]), SImode, 4));
4722 return;
4725 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
4726 && !gpc_reg_operand (operands[1], mode))
4727 operands[1] = force_reg (mode, operands[1]);
4729 if (mode == SFmode && ! TARGET_POWERPC
4730 && TARGET_HARD_FLOAT && TARGET_FPRS
4731 && GET_CODE (operands[0]) == MEM)
4733 int regnum;
4735 if (reload_in_progress || reload_completed)
4736 regnum = true_regnum (operands[1]);
4737 else if (GET_CODE (operands[1]) == REG)
4738 regnum = REGNO (operands[1]);
4739 else
4740 regnum = -1;
4742 /* If operands[1] is a register, on POWER it may have
4743 double-precision data in it, so truncate it to single
4744 precision. */
4745 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
4747 rtx newreg;
4748 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
4749 : gen_reg_rtx (mode));
4750 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
4751 operands[1] = newreg;
4755 /* Recognize the case where operand[1] is a reference to thread-local
4756 data and load its address to a register. */
4757 if (rs6000_tls_referenced_p (operands[1]))
4759 enum tls_model model;
4760 rtx tmp = operands[1];
4761 rtx addend = NULL;
4763 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
4765 addend = XEXP (XEXP (tmp, 0), 1);
4766 tmp = XEXP (XEXP (tmp, 0), 0);
4769 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
4770 model = SYMBOL_REF_TLS_MODEL (tmp);
4771 gcc_assert (model != 0);
4773 tmp = rs6000_legitimize_tls_address (tmp, model);
4774 if (addend)
4776 tmp = gen_rtx_PLUS (mode, tmp, addend);
4777 tmp = force_operand (tmp, operands[0]);
4779 operands[1] = tmp;
4782 /* Handle the case where reload calls us with an invalid address. */
4783 if (reload_in_progress && mode == Pmode
4784 && (! general_operand (operands[1], mode)
4785 || ! nonimmediate_operand (operands[0], mode)))
4786 goto emit_set;
4788 /* 128-bit constant floating-point values on Darwin should really be
4789 loaded as two parts. */
4790 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
4791 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
4793 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4794 know how to get a DFmode SUBREG of a TFmode. */
4795 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
4796 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
4797 simplify_gen_subreg (imode, operands[1], mode, 0),
4798 imode);
4799 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
4800 GET_MODE_SIZE (imode)),
4801 simplify_gen_subreg (imode, operands[1], mode,
4802 GET_MODE_SIZE (imode)),
4803 imode);
4804 return;
4807 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
4808 cfun->machine->sdmode_stack_slot =
4809 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
4811 if (reload_in_progress
4812 && mode == SDmode
4813 && MEM_P (operands[0])
4814 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
4815 && REG_P (operands[1]))
4817 if (FP_REGNO_P (REGNO (operands[1])))
4819 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
4820 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
4821 emit_insn (gen_movsd_store (mem, operands[1]));
4823 else if (INT_REGNO_P (REGNO (operands[1])))
4825 rtx mem = adjust_address_nv (operands[0], mode, 4);
4826 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
4827 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
4829 else
4830 gcc_unreachable();
4831 return;
4833 if (reload_in_progress
4834 && mode == SDmode
4835 && REG_P (operands[0])
4836 && MEM_P (operands[1])
4837 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
4839 if (FP_REGNO_P (REGNO (operands[0])))
4841 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
4842 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
4843 emit_insn (gen_movsd_load (operands[0], mem));
4845 else if (INT_REGNO_P (REGNO (operands[0])))
4847 rtx mem = adjust_address_nv (operands[1], mode, 4);
4848 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
4849 emit_insn (gen_movsd_hardfloat (operands[0], mem));
4851 else
4852 gcc_unreachable();
4853 return;
4856 /* FIXME: In the long term, this switch statement should go away
4857 and be replaced by a sequence of tests based on things like
4858 mode == Pmode. */
4859 switch (mode)
4861 case HImode:
4862 case QImode:
4863 if (CONSTANT_P (operands[1])
4864 && GET_CODE (operands[1]) != CONST_INT)
4865 operands[1] = force_const_mem (mode, operands[1]);
4866 break;
4868 case TFmode:
4869 case TDmode:
4870 rs6000_eliminate_indexed_memrefs (operands);
4871 /* fall through */
4873 case DFmode:
4874 case DDmode:
4875 case SFmode:
4876 case SDmode:
4877 if (CONSTANT_P (operands[1])
4878 && ! easy_fp_constant (operands[1], mode))
4879 operands[1] = force_const_mem (mode, operands[1]);
4880 break;
4882 case V16QImode:
4883 case V8HImode:
4884 case V4SFmode:
4885 case V4SImode:
4886 case V4HImode:
4887 case V2SFmode:
4888 case V2SImode:
4889 case V1DImode:
4890 if (CONSTANT_P (operands[1])
4891 && !easy_vector_constant (operands[1], mode))
4892 operands[1] = force_const_mem (mode, operands[1]);
4893 break;
4895 case SImode:
4896 case DImode:
4897 /* Use default pattern for address of ELF small data */
4898 if (TARGET_ELF
4899 && mode == Pmode
4900 && DEFAULT_ABI == ABI_V4
4901 && (GET_CODE (operands[1]) == SYMBOL_REF
4902 || GET_CODE (operands[1]) == CONST)
4903 && small_data_operand (operands[1], mode))
4905 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4906 return;
4909 if (DEFAULT_ABI == ABI_V4
4910 && mode == Pmode && mode == SImode
4911 && flag_pic == 1 && got_operand (operands[1], mode))
4913 emit_insn (gen_movsi_got (operands[0], operands[1]));
4914 return;
4917 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
4918 && TARGET_NO_TOC
4919 && ! flag_pic
4920 && mode == Pmode
4921 && CONSTANT_P (operands[1])
4922 && GET_CODE (operands[1]) != HIGH
4923 && GET_CODE (operands[1]) != CONST_INT)
4925 rtx target = (!can_create_pseudo_p ()
4926 ? operands[0]
4927 : gen_reg_rtx (mode));
4929 /* If this is a function address on -mcall-aixdesc,
4930 convert it to the address of the descriptor. */
4931 if (DEFAULT_ABI == ABI_AIX
4932 && GET_CODE (operands[1]) == SYMBOL_REF
4933 && XSTR (operands[1], 0)[0] == '.')
4935 const char *name = XSTR (operands[1], 0);
4936 rtx new_ref;
4937 while (*name == '.')
4938 name++;
4939 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
4940 CONSTANT_POOL_ADDRESS_P (new_ref)
4941 = CONSTANT_POOL_ADDRESS_P (operands[1]);
4942 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
4943 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4944 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
4945 operands[1] = new_ref;
4948 if (DEFAULT_ABI == ABI_DARWIN)
4950 #if TARGET_MACHO
4951 if (MACHO_DYNAMIC_NO_PIC_P)
4953 /* Take care of any required data indirection. */
4954 operands[1] = rs6000_machopic_legitimize_pic_address (
4955 operands[1], mode, operands[0]);
4956 if (operands[0] != operands[1])
4957 emit_insn (gen_rtx_SET (VOIDmode,
4958 operands[0], operands[1]));
4959 return;
4961 #endif
4962 emit_insn (gen_macho_high (target, operands[1]));
4963 emit_insn (gen_macho_low (operands[0], target, operands[1]));
4964 return;
4967 emit_insn (gen_elf_high (target, operands[1]));
4968 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4969 return;
4972 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4973 and we have put it in the TOC, we just need to make a TOC-relative
4974 reference to it. */
4975 if (TARGET_TOC
4976 && GET_CODE (operands[1]) == SYMBOL_REF
4977 && constant_pool_expr_p (operands[1])
4978 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
4979 get_pool_mode (operands[1])))
4981 operands[1] = create_TOC_reference (operands[1]);
4983 else if (mode == Pmode
4984 && CONSTANT_P (operands[1])
4985 && ((GET_CODE (operands[1]) != CONST_INT
4986 && ! easy_fp_constant (operands[1], mode))
4987 || (GET_CODE (operands[1]) == CONST_INT
4988 && num_insns_constant (operands[1], mode) > 2)
4989 || (GET_CODE (operands[0]) == REG
4990 && FP_REGNO_P (REGNO (operands[0]))))
4991 && GET_CODE (operands[1]) != HIGH
4992 && ! legitimate_constant_pool_address_p (operands[1])
4993 && ! toc_relative_expr_p (operands[1]))
4995 /* Emit a USE operation so that the constant isn't deleted if
4996 expensive optimizations are turned on because nobody
4997 references it. This should only be done for operands that
4998 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4999 This should not be done for operands that contain LABEL_REFs.
5000 For now, we just handle the obvious case. */
5001 if (GET_CODE (operands[1]) != LABEL_REF)
5002 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5004 #if TARGET_MACHO
5005 /* Darwin uses a special PIC legitimizer. */
5006 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
5008 operands[1] =
5009 rs6000_machopic_legitimize_pic_address (operands[1], mode,
5010 operands[0]);
5011 if (operands[0] != operands[1])
5012 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
5013 return;
5015 #endif
5017 /* If we are to limit the number of things we put in the TOC and
5018 this is a symbol plus a constant we can add in one insn,
5019 just put the symbol in the TOC and add the constant. Don't do
5020 this if reload is in progress. */
5021 if (GET_CODE (operands[1]) == CONST
5022 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
5023 && GET_CODE (XEXP (operands[1], 0)) == PLUS
5024 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
5025 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
5026 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
5027 && ! side_effects_p (operands[0]))
5029 rtx sym =
5030 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
5031 rtx other = XEXP (XEXP (operands[1], 0), 1);
5033 sym = force_reg (mode, sym);
5034 if (mode == SImode)
5035 emit_insn (gen_addsi3 (operands[0], sym, other));
5036 else
5037 emit_insn (gen_adddi3 (operands[0], sym, other));
5038 return;
5041 operands[1] = force_const_mem (mode, operands[1]);
5043 if (TARGET_TOC
5044 && constant_pool_expr_p (XEXP (operands[1], 0))
5045 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
5046 get_pool_constant (XEXP (operands[1], 0)),
5047 get_pool_mode (XEXP (operands[1], 0))))
5049 operands[1]
5050 = gen_const_mem (mode,
5051 create_TOC_reference (XEXP (operands[1], 0)));
5052 set_mem_alias_set (operands[1], get_TOC_alias_set ());
5055 break;
5057 case TImode:
5058 rs6000_eliminate_indexed_memrefs (operands);
5060 if (TARGET_POWER)
5062 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5063 gen_rtvec (2,
5064 gen_rtx_SET (VOIDmode,
5065 operands[0], operands[1]),
5066 gen_rtx_CLOBBER (VOIDmode,
5067 gen_rtx_SCRATCH (SImode)))));
5068 return;
5070 break;
5072 default:
5073 gcc_unreachable ();
5076 /* Above, we may have called force_const_mem which may have returned
5077 an invalid address. If we can, fix this up; otherwise, reload will
5078 have to deal with it. */
5079 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
5080 operands[1] = validize_mem (operands[1]);
5082 emit_set:
5083 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
5086 /* Nonzero if we can use a floating-point register to pass this arg. */
5087 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
5088 (SCALAR_FLOAT_MODE_P (MODE) \
5089 && (CUM)->fregno <= FP_ARG_MAX_REG \
5090 && TARGET_HARD_FLOAT && TARGET_FPRS)
5092 /* Nonzero if we can use an AltiVec register to pass this arg. */
5093 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
5094 (ALTIVEC_VECTOR_MODE (MODE) \
5095 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
5096 && TARGET_ALTIVEC_ABI \
5097 && (NAMED))
5099 /* Return a nonzero value to say to return the function value in
5100 memory, just as large structures are always returned. TYPE will be
5101 the data type of the value, and FNTYPE will be the type of the
5102 function doing the returning, or @code{NULL} for libcalls.
5104 The AIX ABI for the RS/6000 specifies that all structures are
5105 returned in memory. The Darwin ABI does the same. The SVR4 ABI
5106 specifies that structures <= 8 bytes are returned in r3/r4, but a
5107 draft put them in memory, and GCC used to implement the draft
5108 instead of the final standard. Therefore, aix_struct_return
5109 controls this instead of DEFAULT_ABI; V.4 targets needing backward
5110 compatibility can change DRAFT_V4_STRUCT_RET to override the
5111 default, and -m switches get the final word. See
5112 rs6000_override_options for more details.
5114 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
5115 long double support is enabled. These values are returned in memory.
5117 int_size_in_bytes returns -1 for variable size objects, which go in
5118 memory always. The cast to unsigned makes -1 > 8. */
5120 static bool
5121 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
5123 /* In the darwin64 abi, try to use registers for larger structs
5124 if possible. */
5125 if (rs6000_darwin64_abi
5126 && TREE_CODE (type) == RECORD_TYPE
5127 && int_size_in_bytes (type) > 0)
5129 CUMULATIVE_ARGS valcum;
5130 rtx valret;
5132 valcum.words = 0;
5133 valcum.fregno = FP_ARG_MIN_REG;
5134 valcum.vregno = ALTIVEC_ARG_MIN_REG;
5135 /* Do a trial code generation as if this were going to be passed
5136 as an argument; if any part goes in memory, we return NULL. */
5137 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
5138 if (valret)
5139 return false;
5140 /* Otherwise fall through to more conventional ABI rules. */
5143 if (AGGREGATE_TYPE_P (type)
5144 && (aix_struct_return
5145 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
5146 return true;
5148 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5149 modes only exist for GCC vector types if -maltivec. */
5150 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
5151 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
5152 return false;
5154 /* Return synthetic vectors in memory. */
5155 if (TREE_CODE (type) == VECTOR_TYPE
5156 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
5158 static bool warned_for_return_big_vectors = false;
5159 if (!warned_for_return_big_vectors)
5161 warning (0, "GCC vector returned by reference: "
5162 "non-standard ABI extension with no compatibility guarantee");
5163 warned_for_return_big_vectors = true;
5165 return true;
5168 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
5169 return true;
5171 return false;
5174 /* Initialize a variable CUM of type CUMULATIVE_ARGS
5175 for a call to a function whose data type is FNTYPE.
5176 For a library call, FNTYPE is 0.
5178 For incoming args we set the number of arguments in the prototype large
5179 so we never return a PARALLEL. */
5181 void
5182 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
5183 rtx libname ATTRIBUTE_UNUSED, int incoming,
5184 int libcall, int n_named_args)
5186 static CUMULATIVE_ARGS zero_cumulative;
5188 *cum = zero_cumulative;
5189 cum->words = 0;
5190 cum->fregno = FP_ARG_MIN_REG;
5191 cum->vregno = ALTIVEC_ARG_MIN_REG;
5192 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
5193 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
5194 ? CALL_LIBCALL : CALL_NORMAL);
5195 cum->sysv_gregno = GP_ARG_MIN_REG;
5196 cum->stdarg = fntype
5197 && (TYPE_ARG_TYPES (fntype) != 0
5198 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
5199 != void_type_node));
5201 cum->nargs_prototype = 0;
5202 if (incoming || cum->prototype)
5203 cum->nargs_prototype = n_named_args;
5205 /* Check for a longcall attribute. */
5206 if ((!fntype && rs6000_default_long_calls)
5207 || (fntype
5208 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
5209 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
5210 cum->call_cookie |= CALL_LONG;
5212 if (TARGET_DEBUG_ARG)
5214 fprintf (stderr, "\ninit_cumulative_args:");
5215 if (fntype)
5217 tree ret_type = TREE_TYPE (fntype);
5218 fprintf (stderr, " ret code = %s,",
5219 tree_code_name[ (int)TREE_CODE (ret_type) ]);
5222 if (cum->call_cookie & CALL_LONG)
5223 fprintf (stderr, " longcall,");
5225 fprintf (stderr, " proto = %d, nargs = %d\n",
5226 cum->prototype, cum->nargs_prototype);
5229 if (fntype
5230 && !TARGET_ALTIVEC
5231 && TARGET_ALTIVEC_ABI
5232 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
5234 error ("cannot return value in vector register because"
5235 " altivec instructions are disabled, use -maltivec"
5236 " to enable them");
5240 /* Return true if TYPE must be passed on the stack and not in registers. */
5242 static bool
5243 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
5245 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
5246 return must_pass_in_stack_var_size (mode, type);
5247 else
5248 return must_pass_in_stack_var_size_or_pad (mode, type);
5251 /* If defined, a C expression which determines whether, and in which
5252 direction, to pad out an argument with extra space. The value
5253 should be of type `enum direction': either `upward' to pad above
5254 the argument, `downward' to pad below, or `none' to inhibit
5255 padding.
5257 For the AIX ABI structs are always stored left shifted in their
5258 argument slot. */
5260 enum direction
5261 function_arg_padding (enum machine_mode mode, const_tree type)
5263 #ifndef AGGREGATE_PADDING_FIXED
5264 #define AGGREGATE_PADDING_FIXED 0
5265 #endif
5266 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
5267 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
5268 #endif
5270 if (!AGGREGATE_PADDING_FIXED)
5272 /* GCC used to pass structures of the same size as integer types as
5273 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
5274 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
5275 passed padded downward, except that -mstrict-align further
5276 muddied the water in that multi-component structures of 2 and 4
5277 bytes in size were passed padded upward.
5279 The following arranges for best compatibility with previous
5280 versions of gcc, but removes the -mstrict-align dependency. */
5281 if (BYTES_BIG_ENDIAN)
5283 HOST_WIDE_INT size = 0;
5285 if (mode == BLKmode)
5287 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
5288 size = int_size_in_bytes (type);
5290 else
5291 size = GET_MODE_SIZE (mode);
5293 if (size == 1 || size == 2 || size == 4)
5294 return downward;
5296 return upward;
5299 if (AGGREGATES_PAD_UPWARD_ALWAYS)
5301 if (type != 0 && AGGREGATE_TYPE_P (type))
5302 return upward;
5305 /* Fall back to the default. */
5306 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
5309 /* If defined, a C expression that gives the alignment boundary, in bits,
5310 of an argument with the specified mode and type. If it is not defined,
5311 PARM_BOUNDARY is used for all arguments.
5313 V.4 wants long longs and doubles to be double word aligned. Just
5314 testing the mode size is a boneheaded way to do this as it means
5315 that other types such as complex int are also double word aligned.
5316 However, we're stuck with this because changing the ABI might break
5317 existing library interfaces.
5319 Doubleword align SPE vectors.
5320 Quadword align Altivec vectors.
5321 Quadword align large synthetic vector types. */
5324 function_arg_boundary (enum machine_mode mode, tree type)
5326 if (DEFAULT_ABI == ABI_V4
5327 && (GET_MODE_SIZE (mode) == 8
5328 || (TARGET_HARD_FLOAT
5329 && TARGET_FPRS
5330 && (mode == TFmode || mode == TDmode))))
5331 return 64;
5332 else if (SPE_VECTOR_MODE (mode)
5333 || (type && TREE_CODE (type) == VECTOR_TYPE
5334 && int_size_in_bytes (type) >= 8
5335 && int_size_in_bytes (type) < 16))
5336 return 64;
5337 else if (ALTIVEC_VECTOR_MODE (mode)
5338 || (type && TREE_CODE (type) == VECTOR_TYPE
5339 && int_size_in_bytes (type) >= 16))
5340 return 128;
5341 else if (rs6000_darwin64_abi && mode == BLKmode
5342 && type && TYPE_ALIGN (type) > 64)
5343 return 128;
5344 else
5345 return PARM_BOUNDARY;
5348 /* For a function parm of MODE and TYPE, return the starting word in
5349 the parameter area. NWORDS of the parameter area are already used. */
5351 static unsigned int
5352 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
5354 unsigned int align;
5355 unsigned int parm_offset;
5357 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
5358 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
5359 return nwords + (-(parm_offset + nwords) & align);
5362 /* Compute the size (in words) of a function argument. */
5364 static unsigned long
5365 rs6000_arg_size (enum machine_mode mode, tree type)
5367 unsigned long size;
5369 if (mode != BLKmode)
5370 size = GET_MODE_SIZE (mode);
5371 else
5372 size = int_size_in_bytes (type);
5374 if (TARGET_32BIT)
5375 return (size + 3) >> 2;
5376 else
5377 return (size + 7) >> 3;
5380 /* Use this to flush pending int fields. */
5382 static void
5383 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
5384 HOST_WIDE_INT bitpos)
5386 unsigned int startbit, endbit;
5387 int intregs, intoffset;
5388 enum machine_mode mode;
5390 if (cum->intoffset == -1)
5391 return;
5393 intoffset = cum->intoffset;
5394 cum->intoffset = -1;
5396 if (intoffset % BITS_PER_WORD != 0)
5398 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5399 MODE_INT, 0);
5400 if (mode == BLKmode)
5402 /* We couldn't find an appropriate mode, which happens,
5403 e.g., in packed structs when there are 3 bytes to load.
5404 Back intoffset back to the beginning of the word in this
5405 case. */
5406 intoffset = intoffset & -BITS_PER_WORD;
5410 startbit = intoffset & -BITS_PER_WORD;
5411 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5412 intregs = (endbit - startbit) / BITS_PER_WORD;
5413 cum->words += intregs;
5416 /* The darwin64 ABI calls for us to recurse down through structs,
5417 looking for elements passed in registers. Unfortunately, we have
5418 to track int register count here also because of misalignments
5419 in powerpc alignment mode. */
5421 static void
5422 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
5423 tree type,
5424 HOST_WIDE_INT startbitpos)
5426 tree f;
5428 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5429 if (TREE_CODE (f) == FIELD_DECL)
5431 HOST_WIDE_INT bitpos = startbitpos;
5432 tree ftype = TREE_TYPE (f);
5433 enum machine_mode mode;
5434 if (ftype == error_mark_node)
5435 continue;
5436 mode = TYPE_MODE (ftype);
5438 if (DECL_SIZE (f) != 0
5439 && host_integerp (bit_position (f), 1))
5440 bitpos += int_bit_position (f);
5442 /* ??? FIXME: else assume zero offset. */
5444 if (TREE_CODE (ftype) == RECORD_TYPE)
5445 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
5446 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
5448 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
5449 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5450 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
5452 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
5454 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
5455 cum->vregno++;
5456 cum->words += 2;
5458 else if (cum->intoffset == -1)
5459 cum->intoffset = bitpos;
5463 /* Update the data in CUM to advance over an argument
5464 of mode MODE and data type TYPE.
5465 (TYPE is null for libcalls where that information may not be available.)
5467 Note that for args passed by reference, function_arg will be called
5468 with MODE and TYPE set to that of the pointer to the arg, not the arg
5469 itself. */
5471 void
5472 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5473 tree type, int named, int depth)
5475 int size;
5477 /* Only tick off an argument if we're not recursing. */
5478 if (depth == 0)
5479 cum->nargs_prototype--;
5481 if (TARGET_ALTIVEC_ABI
5482 && (ALTIVEC_VECTOR_MODE (mode)
5483 || (type && TREE_CODE (type) == VECTOR_TYPE
5484 && int_size_in_bytes (type) == 16)))
5486 bool stack = false;
5488 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
5490 cum->vregno++;
5491 if (!TARGET_ALTIVEC)
5492 error ("cannot pass argument in vector register because"
5493 " altivec instructions are disabled, use -maltivec"
5494 " to enable them");
5496 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
5497 even if it is going to be passed in a vector register.
5498 Darwin does the same for variable-argument functions. */
5499 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5500 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
5501 stack = true;
5503 else
5504 stack = true;
5506 if (stack)
5508 int align;
5510 /* Vector parameters must be 16-byte aligned. This places
5511 them at 2 mod 4 in terms of words in 32-bit mode, since
5512 the parameter save area starts at offset 24 from the
5513 stack. In 64-bit mode, they just have to start on an
5514 even word, since the parameter save area is 16-byte
5515 aligned. Space for GPRs is reserved even if the argument
5516 will be passed in memory. */
5517 if (TARGET_32BIT)
5518 align = (2 - cum->words) & 3;
5519 else
5520 align = cum->words & 1;
5521 cum->words += align + rs6000_arg_size (mode, type);
5523 if (TARGET_DEBUG_ARG)
5525 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
5526 cum->words, align);
5527 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
5528 cum->nargs_prototype, cum->prototype,
5529 GET_MODE_NAME (mode));
5533 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
5534 && !cum->stdarg
5535 && cum->sysv_gregno <= GP_ARG_MAX_REG)
5536 cum->sysv_gregno++;
5538 else if (rs6000_darwin64_abi
5539 && mode == BLKmode
5540 && TREE_CODE (type) == RECORD_TYPE
5541 && (size = int_size_in_bytes (type)) > 0)
5543 /* Variable sized types have size == -1 and are
5544 treated as if consisting entirely of ints.
5545 Pad to 16 byte boundary if needed. */
5546 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5547 && (cum->words % 2) != 0)
5548 cum->words++;
5549 /* For varargs, we can just go up by the size of the struct. */
5550 if (!named)
5551 cum->words += (size + 7) / 8;
5552 else
5554 /* It is tempting to say int register count just goes up by
5555 sizeof(type)/8, but this is wrong in a case such as
5556 { int; double; int; } [powerpc alignment]. We have to
5557 grovel through the fields for these too. */
5558 cum->intoffset = 0;
5559 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
5560 rs6000_darwin64_record_arg_advance_flush (cum,
5561 size * BITS_PER_UNIT);
5564 else if (DEFAULT_ABI == ABI_V4)
5566 if (TARGET_HARD_FLOAT && TARGET_FPRS
5567 && (mode == SFmode || mode == DFmode
5568 || mode == SDmode || mode == DDmode || mode == TDmode
5569 || (mode == TFmode && !TARGET_IEEEQUAD)))
5571 /* _Decimal128 must use an even/odd register pair. This assumes
5572 that the register number is odd when fregno is odd. */
5573 if (mode == TDmode && (cum->fregno % 2) == 1)
5574 cum->fregno++;
5576 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
5577 <= FP_ARG_V4_MAX_REG)
5578 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5579 else
5581 cum->fregno = FP_ARG_V4_MAX_REG + 1;
5582 if (mode == DFmode || mode == TFmode
5583 || mode == DDmode || mode == TDmode)
5584 cum->words += cum->words & 1;
5585 cum->words += rs6000_arg_size (mode, type);
5588 else
5590 int n_words = rs6000_arg_size (mode, type);
5591 int gregno = cum->sysv_gregno;
5593 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5594 (r7,r8) or (r9,r10). As does any other 2 word item such
5595 as complex int due to a historical mistake. */
5596 if (n_words == 2)
5597 gregno += (1 - gregno) & 1;
5599 /* Multi-reg args are not split between registers and stack. */
5600 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5602 /* Long long and SPE vectors are aligned on the stack.
5603 So are other 2 word items such as complex int due to
5604 a historical mistake. */
5605 if (n_words == 2)
5606 cum->words += cum->words & 1;
5607 cum->words += n_words;
5610 /* Note: continuing to accumulate gregno past when we've started
5611 spilling to the stack indicates the fact that we've started
5612 spilling to the stack to expand_builtin_saveregs. */
5613 cum->sysv_gregno = gregno + n_words;
5616 if (TARGET_DEBUG_ARG)
5618 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5619 cum->words, cum->fregno);
5620 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
5621 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
5622 fprintf (stderr, "mode = %4s, named = %d\n",
5623 GET_MODE_NAME (mode), named);
5626 else
5628 int n_words = rs6000_arg_size (mode, type);
5629 int start_words = cum->words;
5630 int align_words = rs6000_parm_start (mode, type, start_words);
5632 cum->words = align_words + n_words;
5634 if (SCALAR_FLOAT_MODE_P (mode)
5635 && TARGET_HARD_FLOAT && TARGET_FPRS)
5637 /* _Decimal128 must be passed in an even/odd float register pair.
5638 This assumes that the register number is odd when fregno is
5639 odd. */
5640 if (mode == TDmode && (cum->fregno % 2) == 1)
5641 cum->fregno++;
5642 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5645 if (TARGET_DEBUG_ARG)
5647 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5648 cum->words, cum->fregno);
5649 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
5650 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
5651 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
5652 named, align_words - start_words, depth);
5657 static rtx
5658 spe_build_register_parallel (enum machine_mode mode, int gregno)
5660 rtx r1, r3, r5, r7;
5662 switch (mode)
5664 case DFmode:
5665 case DDmode:
5666 r1 = gen_rtx_REG (DImode, gregno);
5667 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5668 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
5670 case DCmode:
5671 case TFmode:
5672 case TDmode:
5673 r1 = gen_rtx_REG (DImode, gregno);
5674 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5675 r3 = gen_rtx_REG (DImode, gregno + 2);
5676 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5677 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
5679 case TCmode:
5680 r1 = gen_rtx_REG (DImode, gregno);
5681 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5682 r3 = gen_rtx_REG (DImode, gregno + 2);
5683 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5684 r5 = gen_rtx_REG (DImode, gregno + 4);
5685 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
5686 r7 = gen_rtx_REG (DImode, gregno + 6);
5687 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
5688 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
5690 default:
5691 gcc_unreachable ();
5695 /* Determine where to put a SIMD argument on the SPE. */
5696 static rtx
5697 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5698 tree type)
5700 int gregno = cum->sysv_gregno;
5702 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5703 are passed and returned in a pair of GPRs for ABI compatibility. */
5704 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5705 || mode == DDmode || mode == TDmode
5706 || mode == DCmode || mode == TCmode))
5708 int n_words = rs6000_arg_size (mode, type);
5710 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5711 if (mode == DFmode || mode == DDmode)
5712 gregno += (1 - gregno) & 1;
5714 /* Multi-reg args are not split between registers and stack. */
5715 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5716 return NULL_RTX;
5718 return spe_build_register_parallel (mode, gregno);
5720 if (cum->stdarg)
5722 int n_words = rs6000_arg_size (mode, type);
5724 /* SPE vectors are put in odd registers. */
5725 if (n_words == 2 && (gregno & 1) == 0)
5726 gregno += 1;
5728 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
5730 rtx r1, r2;
5731 enum machine_mode m = SImode;
5733 r1 = gen_rtx_REG (m, gregno);
5734 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
5735 r2 = gen_rtx_REG (m, gregno + 1);
5736 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
5737 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
5739 else
5740 return NULL_RTX;
5742 else
5744 if (gregno <= GP_ARG_MAX_REG)
5745 return gen_rtx_REG (mode, gregno);
5746 else
5747 return NULL_RTX;
5751 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5752 structure between cum->intoffset and bitpos to integer registers. */
5754 static void
5755 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
5756 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
5758 enum machine_mode mode;
5759 unsigned int regno;
5760 unsigned int startbit, endbit;
5761 int this_regno, intregs, intoffset;
5762 rtx reg;
5764 if (cum->intoffset == -1)
5765 return;
5767 intoffset = cum->intoffset;
5768 cum->intoffset = -1;
5770 /* If this is the trailing part of a word, try to only load that
5771 much into the register. Otherwise load the whole register. Note
5772 that in the latter case we may pick up unwanted bits. It's not a
5773 problem at the moment but may wish to revisit. */
5775 if (intoffset % BITS_PER_WORD != 0)
5777 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5778 MODE_INT, 0);
5779 if (mode == BLKmode)
5781 /* We couldn't find an appropriate mode, which happens,
5782 e.g., in packed structs when there are 3 bytes to load.
5783 Back intoffset back to the beginning of the word in this
5784 case. */
5785 intoffset = intoffset & -BITS_PER_WORD;
5786 mode = word_mode;
5789 else
5790 mode = word_mode;
5792 startbit = intoffset & -BITS_PER_WORD;
5793 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5794 intregs = (endbit - startbit) / BITS_PER_WORD;
5795 this_regno = cum->words + intoffset / BITS_PER_WORD;
5797 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
5798 cum->use_stack = 1;
5800 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
5801 if (intregs <= 0)
5802 return;
5804 intoffset /= BITS_PER_UNIT;
5807 regno = GP_ARG_MIN_REG + this_regno;
5808 reg = gen_rtx_REG (mode, regno);
5809 rvec[(*k)++] =
5810 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
5812 this_regno += 1;
5813 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
5814 mode = word_mode;
5815 intregs -= 1;
5817 while (intregs > 0);
5820 /* Recursive workhorse for the following. */
5822 static void
5823 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
5824 HOST_WIDE_INT startbitpos, rtx rvec[],
5825 int *k)
5827 tree f;
5829 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5830 if (TREE_CODE (f) == FIELD_DECL)
5832 HOST_WIDE_INT bitpos = startbitpos;
5833 tree ftype = TREE_TYPE (f);
5834 enum machine_mode mode;
5835 if (ftype == error_mark_node)
5836 continue;
5837 mode = TYPE_MODE (ftype);
5839 if (DECL_SIZE (f) != 0
5840 && host_integerp (bit_position (f), 1))
5841 bitpos += int_bit_position (f);
5843 /* ??? FIXME: else assume zero offset. */
5845 if (TREE_CODE (ftype) == RECORD_TYPE)
5846 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
5847 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
5849 #if 0
5850 switch (mode)
5852 case SCmode: mode = SFmode; break;
5853 case DCmode: mode = DFmode; break;
5854 case TCmode: mode = TFmode; break;
5855 default: break;
5857 #endif
5858 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5859 rvec[(*k)++]
5860 = gen_rtx_EXPR_LIST (VOIDmode,
5861 gen_rtx_REG (mode, cum->fregno++),
5862 GEN_INT (bitpos / BITS_PER_UNIT));
5863 if (mode == TFmode || mode == TDmode)
5864 cum->fregno++;
5866 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
5868 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5869 rvec[(*k)++]
5870 = gen_rtx_EXPR_LIST (VOIDmode,
5871 gen_rtx_REG (mode, cum->vregno++),
5872 GEN_INT (bitpos / BITS_PER_UNIT));
5874 else if (cum->intoffset == -1)
5875 cum->intoffset = bitpos;
5879 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5880 the register(s) to be used for each field and subfield of a struct
5881 being passed by value, along with the offset of where the
5882 register's value may be found in the block. FP fields go in FP
5883 register, vector fields go in vector registers, and everything
5884 else goes in int registers, packed as in memory.
5886 This code is also used for function return values. RETVAL indicates
5887 whether this is the case.
5889 Much of this is taken from the SPARC V9 port, which has a similar
5890 calling convention. */
5892 static rtx
5893 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
5894 int named, bool retval)
5896 rtx rvec[FIRST_PSEUDO_REGISTER];
5897 int k = 1, kbase = 1;
5898 HOST_WIDE_INT typesize = int_size_in_bytes (type);
5899 /* This is a copy; modifications are not visible to our caller. */
5900 CUMULATIVE_ARGS copy_cum = *orig_cum;
5901 CUMULATIVE_ARGS *cum = &copy_cum;
5903 /* Pad to 16 byte boundary if needed. */
5904 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5905 && (cum->words % 2) != 0)
5906 cum->words++;
5908 cum->intoffset = 0;
5909 cum->use_stack = 0;
5910 cum->named = named;
5912 /* Put entries into rvec[] for individual FP and vector fields, and
5913 for the chunks of memory that go in int regs. Note we start at
5914 element 1; 0 is reserved for an indication of using memory, and
5915 may or may not be filled in below. */
5916 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
5917 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
5919 /* If any part of the struct went on the stack put all of it there.
5920 This hack is because the generic code for
5921 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5922 parts of the struct are not at the beginning. */
5923 if (cum->use_stack)
5925 if (retval)
5926 return NULL_RTX; /* doesn't go in registers at all */
5927 kbase = 0;
5928 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5930 if (k > 1 || cum->use_stack)
5931 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
5932 else
5933 return NULL_RTX;
5936 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5938 static rtx
5939 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
5941 int n_units;
5942 int i, k;
5943 rtx rvec[GP_ARG_NUM_REG + 1];
5945 if (align_words >= GP_ARG_NUM_REG)
5946 return NULL_RTX;
5948 n_units = rs6000_arg_size (mode, type);
5950 /* Optimize the simple case where the arg fits in one gpr, except in
5951 the case of BLKmode due to assign_parms assuming that registers are
5952 BITS_PER_WORD wide. */
5953 if (n_units == 0
5954 || (n_units == 1 && mode != BLKmode))
5955 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5957 k = 0;
5958 if (align_words + n_units > GP_ARG_NUM_REG)
5959 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5960 using a magic NULL_RTX component.
5961 This is not strictly correct. Only some of the arg belongs in
5962 memory, not all of it. However, the normal scheme using
5963 function_arg_partial_nregs can result in unusual subregs, eg.
5964 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5965 store the whole arg to memory is often more efficient than code
5966 to store pieces, and we know that space is available in the right
5967 place for the whole arg. */
5968 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5970 i = 0;
5973 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
5974 rtx off = GEN_INT (i++ * 4);
5975 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5977 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
5979 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5982 /* Determine where to put an argument to a function.
5983 Value is zero to push the argument on the stack,
5984 or a hard register in which to store the argument.
5986 MODE is the argument's machine mode.
5987 TYPE is the data type of the argument (as a tree).
5988 This is null for libcalls where that information may
5989 not be available.
5990 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5991 the preceding args and about the function being called. It is
5992 not modified in this routine.
5993 NAMED is nonzero if this argument is a named parameter
5994 (otherwise it is an extra parameter matching an ellipsis).
5996 On RS/6000 the first eight words of non-FP are normally in registers
5997 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5998 Under V.4, the first 8 FP args are in registers.
6000 If this is floating-point and no prototype is specified, we use
6001 both an FP and integer register (or possibly FP reg and stack). Library
6002 functions (when CALL_LIBCALL is set) always have the proper types for args,
6003 so we can pass the FP value just in one register. emit_library_function
6004 doesn't support PARALLEL anyway.
6006 Note that for args passed by reference, function_arg will be called
6007 with MODE and TYPE set to that of the pointer to the arg, not the arg
6008 itself. */
6011 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6012 tree type, int named)
6014 enum rs6000_abi abi = DEFAULT_ABI;
6016 /* Return a marker to indicate whether CR1 needs to set or clear the
6017 bit that V.4 uses to say fp args were passed in registers.
6018 Assume that we don't need the marker for software floating point,
6019 or compiler generated library calls. */
6020 if (mode == VOIDmode)
6022 if (abi == ABI_V4
6023 && (cum->call_cookie & CALL_LIBCALL) == 0
6024 && (cum->stdarg
6025 || (cum->nargs_prototype < 0
6026 && (cum->prototype || TARGET_NO_PROTOTYPE))))
6028 /* For the SPE, we need to crxor CR6 always. */
6029 if (TARGET_SPE_ABI)
6030 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
6031 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
6032 return GEN_INT (cum->call_cookie
6033 | ((cum->fregno == FP_ARG_MIN_REG)
6034 ? CALL_V4_SET_FP_ARGS
6035 : CALL_V4_CLEAR_FP_ARGS));
6038 return GEN_INT (cum->call_cookie);
6041 if (rs6000_darwin64_abi && mode == BLKmode
6042 && TREE_CODE (type) == RECORD_TYPE)
6044 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
6045 if (rslt != NULL_RTX)
6046 return rslt;
6047 /* Else fall through to usual handling. */
6050 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
6051 if (TARGET_64BIT && ! cum->prototype)
6053 /* Vector parameters get passed in vector register
6054 and also in GPRs or memory, in absence of prototype. */
6055 int align_words;
6056 rtx slot;
6057 align_words = (cum->words + 1) & ~1;
6059 if (align_words >= GP_ARG_NUM_REG)
6061 slot = NULL_RTX;
6063 else
6065 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
6067 return gen_rtx_PARALLEL (mode,
6068 gen_rtvec (2,
6069 gen_rtx_EXPR_LIST (VOIDmode,
6070 slot, const0_rtx),
6071 gen_rtx_EXPR_LIST (VOIDmode,
6072 gen_rtx_REG (mode, cum->vregno),
6073 const0_rtx)));
6075 else
6076 return gen_rtx_REG (mode, cum->vregno);
6077 else if (TARGET_ALTIVEC_ABI
6078 && (ALTIVEC_VECTOR_MODE (mode)
6079 || (type && TREE_CODE (type) == VECTOR_TYPE
6080 && int_size_in_bytes (type) == 16)))
6082 if (named || abi == ABI_V4)
6083 return NULL_RTX;
6084 else
6086 /* Vector parameters to varargs functions under AIX or Darwin
6087 get passed in memory and possibly also in GPRs. */
6088 int align, align_words, n_words;
6089 enum machine_mode part_mode;
6091 /* Vector parameters must be 16-byte aligned. This places them at
6092 2 mod 4 in terms of words in 32-bit mode, since the parameter
6093 save area starts at offset 24 from the stack. In 64-bit mode,
6094 they just have to start on an even word, since the parameter
6095 save area is 16-byte aligned. */
6096 if (TARGET_32BIT)
6097 align = (2 - cum->words) & 3;
6098 else
6099 align = cum->words & 1;
6100 align_words = cum->words + align;
6102 /* Out of registers? Memory, then. */
6103 if (align_words >= GP_ARG_NUM_REG)
6104 return NULL_RTX;
6106 if (TARGET_32BIT && TARGET_POWERPC64)
6107 return rs6000_mixed_function_arg (mode, type, align_words);
6109 /* The vector value goes in GPRs. Only the part of the
6110 value in GPRs is reported here. */
6111 part_mode = mode;
6112 n_words = rs6000_arg_size (mode, type);
6113 if (align_words + n_words > GP_ARG_NUM_REG)
6114 /* Fortunately, there are only two possibilities, the value
6115 is either wholly in GPRs or half in GPRs and half not. */
6116 part_mode = DImode;
6118 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
6121 else if (TARGET_SPE_ABI && TARGET_SPE
6122 && (SPE_VECTOR_MODE (mode)
6123 || (TARGET_E500_DOUBLE && (mode == DFmode
6124 || mode == DDmode
6125 || mode == DCmode
6126 || mode == TFmode
6127 || mode == TDmode
6128 || mode == TCmode))))
6129 return rs6000_spe_function_arg (cum, mode, type);
6131 else if (abi == ABI_V4)
6133 if (TARGET_HARD_FLOAT && TARGET_FPRS
6134 && (mode == SFmode || mode == DFmode
6135 || (mode == TFmode && !TARGET_IEEEQUAD)
6136 || mode == SDmode || mode == DDmode || mode == TDmode))
6138 /* _Decimal128 must use an even/odd register pair. This assumes
6139 that the register number is odd when fregno is odd. */
6140 if (mode == TDmode && (cum->fregno % 2) == 1)
6141 cum->fregno++;
6143 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
6144 <= FP_ARG_V4_MAX_REG)
6145 return gen_rtx_REG (mode, cum->fregno);
6146 else
6147 return NULL_RTX;
6149 else
6151 int n_words = rs6000_arg_size (mode, type);
6152 int gregno = cum->sysv_gregno;
6154 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
6155 (r7,r8) or (r9,r10). As does any other 2 word item such
6156 as complex int due to a historical mistake. */
6157 if (n_words == 2)
6158 gregno += (1 - gregno) & 1;
6160 /* Multi-reg args are not split between registers and stack. */
6161 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
6162 return NULL_RTX;
6164 if (TARGET_32BIT && TARGET_POWERPC64)
6165 return rs6000_mixed_function_arg (mode, type,
6166 gregno - GP_ARG_MIN_REG);
6167 return gen_rtx_REG (mode, gregno);
6170 else
6172 int align_words = rs6000_parm_start (mode, type, cum->words);
6174 /* _Decimal128 must be passed in an even/odd float register pair.
6175 This assumes that the register number is odd when fregno is odd. */
6176 if (mode == TDmode && (cum->fregno % 2) == 1)
6177 cum->fregno++;
6179 if (USE_FP_FOR_ARG_P (cum, mode, type))
6181 rtx rvec[GP_ARG_NUM_REG + 1];
6182 rtx r;
6183 int k;
6184 bool needs_psave;
6185 enum machine_mode fmode = mode;
6186 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
6188 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
6190 /* Currently, we only ever need one reg here because complex
6191 doubles are split. */
6192 gcc_assert (cum->fregno == FP_ARG_MAX_REG
6193 && (fmode == TFmode || fmode == TDmode));
6195 /* Long double or _Decimal128 split over regs and memory. */
6196 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
6199 /* Do we also need to pass this arg in the parameter save
6200 area? */
6201 needs_psave = (type
6202 && (cum->nargs_prototype <= 0
6203 || (DEFAULT_ABI == ABI_AIX
6204 && TARGET_XL_COMPAT
6205 && align_words >= GP_ARG_NUM_REG)));
6207 if (!needs_psave && mode == fmode)
6208 return gen_rtx_REG (fmode, cum->fregno);
6210 k = 0;
6211 if (needs_psave)
6213 /* Describe the part that goes in gprs or the stack.
6214 This piece must come first, before the fprs. */
6215 if (align_words < GP_ARG_NUM_REG)
6217 unsigned long n_words = rs6000_arg_size (mode, type);
6219 if (align_words + n_words > GP_ARG_NUM_REG
6220 || (TARGET_32BIT && TARGET_POWERPC64))
6222 /* If this is partially on the stack, then we only
6223 include the portion actually in registers here. */
6224 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
6225 rtx off;
6226 int i = 0;
6227 if (align_words + n_words > GP_ARG_NUM_REG)
6228 /* Not all of the arg fits in gprs. Say that it
6229 goes in memory too, using a magic NULL_RTX
6230 component. Also see comment in
6231 rs6000_mixed_function_arg for why the normal
6232 function_arg_partial_nregs scheme doesn't work
6233 in this case. */
6234 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
6235 const0_rtx);
6238 r = gen_rtx_REG (rmode,
6239 GP_ARG_MIN_REG + align_words);
6240 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
6241 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
6243 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
6245 else
6247 /* The whole arg fits in gprs. */
6248 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
6249 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
6252 else
6253 /* It's entirely in memory. */
6254 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
6257 /* Describe where this piece goes in the fprs. */
6258 r = gen_rtx_REG (fmode, cum->fregno);
6259 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
6261 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
6263 else if (align_words < GP_ARG_NUM_REG)
6265 if (TARGET_32BIT && TARGET_POWERPC64)
6266 return rs6000_mixed_function_arg (mode, type, align_words);
6268 if (mode == BLKmode)
6269 mode = Pmode;
6271 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
6273 else
6274 return NULL_RTX;
6278 /* For an arg passed partly in registers and partly in memory, this is
6279 the number of bytes passed in registers. For args passed entirely in
6280 registers or entirely in memory, zero. When an arg is described by a
6281 PARALLEL, perhaps using more than one register type, this function
6282 returns the number of bytes used by the first element of the PARALLEL. */
6284 static int
6285 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6286 tree type, bool named)
6288 int ret = 0;
6289 int align_words;
6291 if (DEFAULT_ABI == ABI_V4)
6292 return 0;
6294 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
6295 && cum->nargs_prototype >= 0)
6296 return 0;
6298 /* In this complicated case we just disable the partial_nregs code. */
6299 if (rs6000_darwin64_abi && mode == BLKmode
6300 && TREE_CODE (type) == RECORD_TYPE
6301 && int_size_in_bytes (type) > 0)
6302 return 0;
6304 align_words = rs6000_parm_start (mode, type, cum->words);
6306 if (USE_FP_FOR_ARG_P (cum, mode, type))
6308 /* If we are passing this arg in the fixed parameter save area
6309 (gprs or memory) as well as fprs, then this function should
6310 return the number of partial bytes passed in the parameter
6311 save area rather than partial bytes passed in fprs. */
6312 if (type
6313 && (cum->nargs_prototype <= 0
6314 || (DEFAULT_ABI == ABI_AIX
6315 && TARGET_XL_COMPAT
6316 && align_words >= GP_ARG_NUM_REG)))
6317 return 0;
6318 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
6319 > FP_ARG_MAX_REG + 1)
6320 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
6321 else if (cum->nargs_prototype >= 0)
6322 return 0;
6325 if (align_words < GP_ARG_NUM_REG
6326 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
6327 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
6329 if (ret != 0 && TARGET_DEBUG_ARG)
6330 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
6332 return ret;
6335 /* A C expression that indicates when an argument must be passed by
6336 reference. If nonzero for an argument, a copy of that argument is
6337 made in memory and a pointer to the argument is passed instead of
6338 the argument itself. The pointer is passed in whatever way is
6339 appropriate for passing a pointer to that type.
6341 Under V.4, aggregates and long double are passed by reference.
6343 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
6344 reference unless the AltiVec vector extension ABI is in force.
6346 As an extension to all ABIs, variable sized types are passed by
6347 reference. */
6349 static bool
6350 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
6351 enum machine_mode mode, const_tree type,
6352 bool named ATTRIBUTE_UNUSED)
6354 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
6356 if (TARGET_DEBUG_ARG)
6357 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
6358 return 1;
6361 if (!type)
6362 return 0;
6364 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
6366 if (TARGET_DEBUG_ARG)
6367 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
6368 return 1;
6371 if (int_size_in_bytes (type) < 0)
6373 if (TARGET_DEBUG_ARG)
6374 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
6375 return 1;
6378 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6379 modes only exist for GCC vector types if -maltivec. */
6380 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
6382 if (TARGET_DEBUG_ARG)
6383 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
6384 return 1;
6387 /* Pass synthetic vectors in memory. */
6388 if (TREE_CODE (type) == VECTOR_TYPE
6389 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6391 static bool warned_for_pass_big_vectors = false;
6392 if (TARGET_DEBUG_ARG)
6393 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
6394 if (!warned_for_pass_big_vectors)
6396 warning (0, "GCC vector passed by reference: "
6397 "non-standard ABI extension with no compatibility guarantee");
6398 warned_for_pass_big_vectors = true;
6400 return 1;
6403 return 0;
6406 static void
6407 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
6409 int i;
6410 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
6412 if (nregs == 0)
6413 return;
6415 for (i = 0; i < nregs; i++)
6417 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
6418 if (reload_completed)
6420 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
6421 tem = NULL_RTX;
6422 else
6423 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
6424 i * GET_MODE_SIZE (reg_mode));
6426 else
6427 tem = replace_equiv_address (tem, XEXP (tem, 0));
6429 gcc_assert (tem);
6431 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
6435 /* Perform any needed actions needed for a function that is receiving a
6436 variable number of arguments.
6438 CUM is as above.
6440 MODE and TYPE are the mode and type of the current parameter.
6442 PRETEND_SIZE is a variable that should be set to the amount of stack
6443 that must be pushed by the prolog to pretend that our caller pushed
6446 Normally, this macro will push all remaining incoming registers on the
6447 stack and set PRETEND_SIZE to the length of the registers pushed. */
6449 static void
6450 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6451 tree type, int *pretend_size ATTRIBUTE_UNUSED,
6452 int no_rtl)
6454 CUMULATIVE_ARGS next_cum;
6455 int reg_size = TARGET_32BIT ? 4 : 8;
6456 rtx save_area = NULL_RTX, mem;
6457 int first_reg_offset;
6458 alias_set_type set;
6460 /* Skip the last named argument. */
6461 next_cum = *cum;
6462 function_arg_advance (&next_cum, mode, type, 1, 0);
6464 if (DEFAULT_ABI == ABI_V4)
6466 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
6468 if (! no_rtl)
6470 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
6471 HOST_WIDE_INT offset = 0;
6473 /* Try to optimize the size of the varargs save area.
6474 The ABI requires that ap.reg_save_area is doubleword
6475 aligned, but we don't need to allocate space for all
6476 the bytes, only those to which we actually will save
6477 anything. */
6478 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
6479 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
6480 if (TARGET_HARD_FLOAT && TARGET_FPRS
6481 && next_cum.fregno <= FP_ARG_V4_MAX_REG
6482 && cfun->va_list_fpr_size)
6484 if (gpr_reg_num)
6485 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
6486 * UNITS_PER_FP_WORD;
6487 if (cfun->va_list_fpr_size
6488 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
6489 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
6490 else
6491 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
6492 * UNITS_PER_FP_WORD;
6494 if (gpr_reg_num)
6496 offset = -((first_reg_offset * reg_size) & ~7);
6497 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
6499 gpr_reg_num = cfun->va_list_gpr_size;
6500 if (reg_size == 4 && (first_reg_offset & 1))
6501 gpr_reg_num++;
6503 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
6505 else if (fpr_size)
6506 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
6507 * UNITS_PER_FP_WORD
6508 - (int) (GP_ARG_NUM_REG * reg_size);
6510 if (gpr_size + fpr_size)
6512 rtx reg_save_area
6513 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
6514 gcc_assert (GET_CODE (reg_save_area) == MEM);
6515 reg_save_area = XEXP (reg_save_area, 0);
6516 if (GET_CODE (reg_save_area) == PLUS)
6518 gcc_assert (XEXP (reg_save_area, 0)
6519 == virtual_stack_vars_rtx);
6520 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
6521 offset += INTVAL (XEXP (reg_save_area, 1));
6523 else
6524 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
6527 cfun->machine->varargs_save_offset = offset;
6528 save_area = plus_constant (virtual_stack_vars_rtx, offset);
6531 else
6533 first_reg_offset = next_cum.words;
6534 save_area = virtual_incoming_args_rtx;
6536 if (targetm.calls.must_pass_in_stack (mode, type))
6537 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
6540 set = get_varargs_alias_set ();
6541 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
6542 && cfun->va_list_gpr_size)
6544 int nregs = GP_ARG_NUM_REG - first_reg_offset;
6546 if (va_list_gpr_counter_field)
6548 /* V4 va_list_gpr_size counts number of registers needed. */
6549 if (nregs > cfun->va_list_gpr_size)
6550 nregs = cfun->va_list_gpr_size;
6552 else
6554 /* char * va_list instead counts number of bytes needed. */
6555 if (nregs > cfun->va_list_gpr_size / reg_size)
6556 nregs = cfun->va_list_gpr_size / reg_size;
6559 mem = gen_rtx_MEM (BLKmode,
6560 plus_constant (save_area,
6561 first_reg_offset * reg_size));
6562 MEM_NOTRAP_P (mem) = 1;
6563 set_mem_alias_set (mem, set);
6564 set_mem_align (mem, BITS_PER_WORD);
6566 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
6567 nregs);
6570 /* Save FP registers if needed. */
6571 if (DEFAULT_ABI == ABI_V4
6572 && TARGET_HARD_FLOAT && TARGET_FPRS
6573 && ! no_rtl
6574 && next_cum.fregno <= FP_ARG_V4_MAX_REG
6575 && cfun->va_list_fpr_size)
6577 int fregno = next_cum.fregno, nregs;
6578 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
6579 rtx lab = gen_label_rtx ();
6580 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
6581 * UNITS_PER_FP_WORD);
6583 emit_jump_insn
6584 (gen_rtx_SET (VOIDmode,
6585 pc_rtx,
6586 gen_rtx_IF_THEN_ELSE (VOIDmode,
6587 gen_rtx_NE (VOIDmode, cr1,
6588 const0_rtx),
6589 gen_rtx_LABEL_REF (VOIDmode, lab),
6590 pc_rtx)));
6592 for (nregs = 0;
6593 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
6594 fregno++, off += UNITS_PER_FP_WORD, nregs++)
6596 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
6597 MEM_NOTRAP_P (mem) = 1;
6598 set_mem_alias_set (mem, set);
6599 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
6600 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
6603 emit_label (lab);
6607 /* Create the va_list data type. */
6609 static tree
6610 rs6000_build_builtin_va_list (void)
6612 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
6614 /* For AIX, prefer 'char *' because that's what the system
6615 header files like. */
6616 if (DEFAULT_ABI != ABI_V4)
6617 return build_pointer_type (char_type_node);
6619 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
6620 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6622 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
6623 unsigned_char_type_node);
6624 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
6625 unsigned_char_type_node);
6626 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6627 every user file. */
6628 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
6629 short_unsigned_type_node);
6630 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
6631 ptr_type_node);
6632 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
6633 ptr_type_node);
6635 va_list_gpr_counter_field = f_gpr;
6636 va_list_fpr_counter_field = f_fpr;
6638 DECL_FIELD_CONTEXT (f_gpr) = record;
6639 DECL_FIELD_CONTEXT (f_fpr) = record;
6640 DECL_FIELD_CONTEXT (f_res) = record;
6641 DECL_FIELD_CONTEXT (f_ovf) = record;
6642 DECL_FIELD_CONTEXT (f_sav) = record;
6644 TREE_CHAIN (record) = type_decl;
6645 TYPE_NAME (record) = type_decl;
6646 TYPE_FIELDS (record) = f_gpr;
6647 TREE_CHAIN (f_gpr) = f_fpr;
6648 TREE_CHAIN (f_fpr) = f_res;
6649 TREE_CHAIN (f_res) = f_ovf;
6650 TREE_CHAIN (f_ovf) = f_sav;
6652 layout_type (record);
6654 /* The correct type is an array type of one element. */
6655 return build_array_type (record, build_index_type (size_zero_node));
6658 /* Implement va_start. */
6660 static void
6661 rs6000_va_start (tree valist, rtx nextarg)
6663 HOST_WIDE_INT words, n_gpr, n_fpr;
6664 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6665 tree gpr, fpr, ovf, sav, t;
6667 /* Only SVR4 needs something special. */
6668 if (DEFAULT_ABI != ABI_V4)
6670 std_expand_builtin_va_start (valist, nextarg);
6671 return;
6674 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6675 f_fpr = TREE_CHAIN (f_gpr);
6676 f_res = TREE_CHAIN (f_fpr);
6677 f_ovf = TREE_CHAIN (f_res);
6678 f_sav = TREE_CHAIN (f_ovf);
6680 valist = build_va_arg_indirect_ref (valist);
6681 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6682 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6683 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6684 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6686 /* Count number of gp and fp argument registers used. */
6687 words = crtl->args.info.words;
6688 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
6689 GP_ARG_NUM_REG);
6690 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
6691 FP_ARG_NUM_REG);
6693 if (TARGET_DEBUG_ARG)
6694 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
6695 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
6696 words, n_gpr, n_fpr);
6698 if (cfun->va_list_gpr_size)
6700 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr,
6701 build_int_cst (NULL_TREE, n_gpr));
6702 TREE_SIDE_EFFECTS (t) = 1;
6703 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6706 if (cfun->va_list_fpr_size)
6708 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr,
6709 build_int_cst (NULL_TREE, n_fpr));
6710 TREE_SIDE_EFFECTS (t) = 1;
6711 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6714 /* Find the overflow area. */
6715 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6716 if (words != 0)
6717 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
6718 size_int (words * UNITS_PER_WORD));
6719 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6720 TREE_SIDE_EFFECTS (t) = 1;
6721 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6723 /* If there were no va_arg invocations, don't set up the register
6724 save area. */
6725 if (!cfun->va_list_gpr_size
6726 && !cfun->va_list_fpr_size
6727 && n_gpr < GP_ARG_NUM_REG
6728 && n_fpr < FP_ARG_V4_MAX_REG)
6729 return;
6731 /* Find the register save area. */
6732 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
6733 if (cfun->machine->varargs_save_offset)
6734 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
6735 size_int (cfun->machine->varargs_save_offset));
6736 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
6737 TREE_SIDE_EFFECTS (t) = 1;
6738 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6741 /* Implement va_arg. */
6743 tree
6744 rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
6746 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6747 tree gpr, fpr, ovf, sav, reg, t, u;
6748 int size, rsize, n_reg, sav_ofs, sav_scale;
6749 tree lab_false, lab_over, addr;
6750 int align;
6751 tree ptrtype = build_pointer_type (type);
6752 int regalign = 0;
6754 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
6756 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
6757 return build_va_arg_indirect_ref (t);
6760 if (DEFAULT_ABI != ABI_V4)
6762 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
6764 tree elem_type = TREE_TYPE (type);
6765 enum machine_mode elem_mode = TYPE_MODE (elem_type);
6766 int elem_size = GET_MODE_SIZE (elem_mode);
6768 if (elem_size < UNITS_PER_WORD)
6770 tree real_part, imag_part;
6771 tree post = NULL_TREE;
6773 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6774 &post);
6775 /* Copy the value into a temporary, lest the formal temporary
6776 be reused out from under us. */
6777 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
6778 append_to_statement_list (post, pre_p);
6780 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6781 post_p);
6783 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
6787 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6790 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6791 f_fpr = TREE_CHAIN (f_gpr);
6792 f_res = TREE_CHAIN (f_fpr);
6793 f_ovf = TREE_CHAIN (f_res);
6794 f_sav = TREE_CHAIN (f_ovf);
6796 valist = build_va_arg_indirect_ref (valist);
6797 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6798 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6799 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6800 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6802 size = int_size_in_bytes (type);
6803 rsize = (size + 3) / 4;
6804 align = 1;
6806 if (TARGET_HARD_FLOAT && TARGET_FPRS
6807 && (TYPE_MODE (type) == SFmode
6808 || TYPE_MODE (type) == DFmode
6809 || TYPE_MODE (type) == TFmode
6810 || TYPE_MODE (type) == SDmode
6811 || TYPE_MODE (type) == DDmode
6812 || TYPE_MODE (type) == TDmode))
6814 /* FP args go in FP registers, if present. */
6815 reg = fpr;
6816 n_reg = (size + 7) / 8;
6817 sav_ofs = 8*4;
6818 sav_scale = 8;
6819 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
6820 align = 8;
6822 else
6824 /* Otherwise into GP registers. */
6825 reg = gpr;
6826 n_reg = rsize;
6827 sav_ofs = 0;
6828 sav_scale = 4;
6829 if (n_reg == 2)
6830 align = 8;
6833 /* Pull the value out of the saved registers.... */
6835 lab_over = NULL;
6836 addr = create_tmp_var (ptr_type_node, "addr");
6837 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
6839 /* AltiVec vectors never go in registers when -mabi=altivec. */
6840 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6841 align = 16;
6842 else
6844 lab_false = create_artificial_label ();
6845 lab_over = create_artificial_label ();
6847 /* Long long and SPE vectors are aligned in the registers.
6848 As are any other 2 gpr item such as complex int due to a
6849 historical mistake. */
6850 u = reg;
6851 if (n_reg == 2 && reg == gpr)
6853 regalign = 1;
6854 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
6855 build_int_cst (TREE_TYPE (reg), n_reg - 1));
6856 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
6858 /* _Decimal128 is passed in even/odd fpr pairs; the stored
6859 reg number is 0 for f1, so we want to make it odd. */
6860 else if (reg == fpr && TYPE_MODE (type) == TDmode)
6862 regalign = 1;
6863 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), reg,
6864 build_int_cst (TREE_TYPE (reg), 1));
6865 u = build2 (MODIFY_EXPR, void_type_node, reg, t);
6868 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
6869 t = build2 (GE_EXPR, boolean_type_node, u, t);
6870 u = build1 (GOTO_EXPR, void_type_node, lab_false);
6871 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
6872 gimplify_and_add (t, pre_p);
6874 t = sav;
6875 if (sav_ofs)
6876 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
6878 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
6879 build_int_cst (TREE_TYPE (reg), n_reg));
6880 u = fold_convert (sizetype, u);
6881 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
6882 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
6884 /* _Decimal32 varargs are located in the second word of the 64-bit
6885 FP register for 32-bit binaries. */
6886 if (!TARGET_POWERPC64 && TYPE_MODE (type) == SDmode)
6887 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
6889 t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6890 gimplify_and_add (t, pre_p);
6892 t = build1 (GOTO_EXPR, void_type_node, lab_over);
6893 gimplify_and_add (t, pre_p);
6895 t = build1 (LABEL_EXPR, void_type_node, lab_false);
6896 append_to_statement_list (t, pre_p);
6898 if ((n_reg == 2 && !regalign) || n_reg > 2)
6900 /* Ensure that we don't find any more args in regs.
6901 Alignment has taken care of for special cases. */
6902 t = build_gimple_modify_stmt (reg,
6903 build_int_cst (TREE_TYPE (reg), 8));
6904 gimplify_and_add (t, pre_p);
6908 /* ... otherwise out of the overflow area. */
6910 /* Care for on-stack alignment if needed. */
6911 t = ovf;
6912 if (align != 1)
6914 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
6915 t = fold_convert (sizetype, t);
6916 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
6917 size_int (-align));
6918 t = fold_convert (TREE_TYPE (ovf), t);
6920 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
6922 u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6923 gimplify_and_add (u, pre_p);
6925 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
6926 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6927 gimplify_and_add (t, pre_p);
6929 if (lab_over)
6931 t = build1 (LABEL_EXPR, void_type_node, lab_over);
6932 append_to_statement_list (t, pre_p);
6935 if (STRICT_ALIGNMENT
6936 && (TYPE_ALIGN (type)
6937 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
6939 /* The value (of type complex double, for example) may not be
6940 aligned in memory in the saved registers, so copy via a
6941 temporary. (This is the same code as used for SPARC.) */
6942 tree tmp = create_tmp_var (type, "va_arg_tmp");
6943 tree dest_addr = build_fold_addr_expr (tmp);
6945 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
6946 3, dest_addr, addr, size_int (rsize * 4));
6948 gimplify_and_add (copy, pre_p);
6949 addr = dest_addr;
6952 addr = fold_convert (ptrtype, addr);
6953 return build_va_arg_indirect_ref (addr);
6956 /* Builtins. */
6958 static void
6959 def_builtin (int mask, const char *name, tree type, int code)
6961 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
6963 if (rs6000_builtin_decls[code])
6964 abort ();
6966 rs6000_builtin_decls[code] =
6967 add_builtin_function (name, type, code, BUILT_IN_MD,
6968 NULL, NULL_TREE);
6972 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6974 static const struct builtin_description bdesc_3arg[] =
6976 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
6977 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
6978 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
6979 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
6980 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
6981 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
6982 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
6983 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
6984 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
6985 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
6986 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
6987 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
6988 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
6989 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
6990 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
6991 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
6992 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
6993 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
6994 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
6995 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
6996 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
6997 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
6998 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
7000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
7001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
7002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
7003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
7004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
7005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
7006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
7007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
7008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
7009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
7010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
7011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
7012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
7013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
7014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
7016 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
7017 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
7018 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
7019 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
7020 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
7021 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
7022 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
7023 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
7024 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
7027 /* DST operations: void foo (void *, const int, const char). */
7029 static const struct builtin_description bdesc_dst[] =
7031 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
7032 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
7033 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
7034 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
7036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
7037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
7038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
7039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
7042 /* Simple binary operations: VECc = foo (VECa, VECb). */
7044 static struct builtin_description bdesc_2arg[] =
7046 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
7047 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
7048 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
7049 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
7050 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
7051 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
7052 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
7053 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
7054 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
7055 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
7056 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
7057 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
7058 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
7059 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
7060 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
7061 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
7062 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
7063 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
7064 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
7065 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
7066 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
7067 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
7068 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
7069 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
7070 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
7071 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
7072 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
7073 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
7074 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
7075 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
7076 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
7077 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
7078 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
7079 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
7080 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
7081 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
7082 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
7083 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
7084 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
7085 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
7086 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
7087 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
7088 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
7089 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
7090 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
7091 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
7092 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
7093 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
7094 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
7095 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
7096 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
7097 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
7098 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
7099 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
7100 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
7101 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
7102 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
7103 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
7104 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
7105 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
7106 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
7107 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
7108 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
7109 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
7110 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
7111 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
7112 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
7113 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
7114 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
7115 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
7116 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
7117 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
7118 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
7119 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
7120 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
7121 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
7122 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
7123 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
7124 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
7125 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
7126 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
7127 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
7128 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
7129 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
7130 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
7131 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
7132 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
7133 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
7134 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
7135 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
7136 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
7137 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
7138 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
7139 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
7140 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
7141 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
7142 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
7143 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
7144 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
7145 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
7146 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
7147 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
7148 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
7149 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
7150 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
7151 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
7152 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
7153 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
7154 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
7155 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
7156 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
7158 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
7159 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
7160 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
7161 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
7162 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
7163 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
7164 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
7165 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
7166 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
7167 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
7168 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
7169 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
7170 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
7171 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
7172 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
7173 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
7174 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
7175 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
7176 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
7177 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
7178 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
7179 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
7180 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
7181 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
7182 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
7183 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
7184 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
7185 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
7186 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
7187 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
7188 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
7189 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
7190 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
7191 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
7192 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
7193 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
7194 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
7195 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
7196 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
7197 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
7198 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
7199 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
7200 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
7201 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
7202 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
7203 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
7204 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
7205 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
7206 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
7207 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
7208 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
7209 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
7210 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
7211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
7212 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
7213 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
7214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
7215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
7216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
7217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
7218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
7219 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
7220 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
7221 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
7222 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
7223 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
7224 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
7225 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
7226 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
7227 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
7228 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
7229 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
7230 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
7231 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
7232 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
7233 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
7234 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
7235 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
7236 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
7237 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
7238 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
7239 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
7240 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
7241 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
7242 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
7243 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
7244 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
7245 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
7246 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
7247 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
7248 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
7249 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
7250 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
7251 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
7252 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
7253 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
7254 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
7255 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
7256 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
7257 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
7258 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
7259 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
7260 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
7261 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
7262 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
7263 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
7264 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
7265 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
7266 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
7267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
7268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
7269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
7270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
7271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
7272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
7273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
7274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
7275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
7276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
7277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
7278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
7279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
7280 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
7281 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
7282 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
7283 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
7284 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
7286 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
7287 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
7288 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
7289 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
7290 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
7291 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
7292 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
7293 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
7294 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
7295 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
7297 /* Place holder, leave as first spe builtin. */
7298 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
7299 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
7300 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
7301 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
7302 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
7303 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
7304 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
7305 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
7306 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
7307 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
7308 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
7309 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
7310 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
7311 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
7312 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
7313 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
7314 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
7315 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
7316 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
7317 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
7318 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
7319 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
7320 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
7321 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
7322 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
7323 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
7324 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
7325 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
7326 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
7327 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
7328 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
7329 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
7330 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
7331 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
7332 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
7333 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
7334 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
7335 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
7336 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
7337 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
7338 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
7339 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
7340 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
7341 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
7342 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
7343 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
7344 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
7345 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
7346 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
7347 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
7348 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
7349 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
7350 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
7351 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
7352 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
7353 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
7354 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
7355 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
7356 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
7357 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
7358 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
7359 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
7360 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
7361 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
7362 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
7363 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
7364 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
7365 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
7366 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
7367 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
7368 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
7369 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
7370 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
7371 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
7372 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
7373 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
7374 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
7375 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
7376 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
7377 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
7378 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
7379 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
7380 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
7381 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
7382 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
7383 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
7384 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
7385 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
7386 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
7387 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
7388 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
7389 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
7390 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
7391 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
7392 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
7393 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
7394 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
7395 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
7396 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
7397 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
7398 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
7399 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
7400 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
7401 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
7402 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
7403 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
7404 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
7405 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
7406 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
7408 /* SPE binary operations expecting a 5-bit unsigned literal. */
7409 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
7411 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
7412 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
7413 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
7414 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
7415 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
7416 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
7417 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
7418 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
7419 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
7420 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
7421 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
7422 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
7423 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
7424 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
7425 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
7426 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
7427 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
7428 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
7429 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
7430 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
7431 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
7432 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
7433 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
7434 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
7435 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
7436 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
7438 /* Place-holder. Leave as last binary SPE builtin. */
7439 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
7442 /* AltiVec predicates. */
7444 struct builtin_description_predicates
7446 const unsigned int mask;
7447 const enum insn_code icode;
7448 const char *opcode;
7449 const char *const name;
7450 const enum rs6000_builtins code;
7453 static const struct builtin_description_predicates bdesc_altivec_preds[] =
7455 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
7456 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
7457 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
7458 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
7459 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
7460 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
7461 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
7462 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
7463 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
7464 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
7465 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
7466 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
7467 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
7469 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
7470 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
7471 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
7474 /* SPE predicates. */
7475 static struct builtin_description bdesc_spe_predicates[] =
7477 /* Place-holder. Leave as first. */
7478 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
7479 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
7480 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
7481 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
7482 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
7483 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
7484 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
7485 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
7486 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
7487 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
7488 /* Place-holder. Leave as last. */
7489 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
7492 /* SPE evsel predicates. */
7493 static struct builtin_description bdesc_spe_evsel[] =
7495 /* Place-holder. Leave as first. */
7496 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
7497 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
7498 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
7499 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
7500 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
7501 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
7502 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
7503 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
7504 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
7505 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
7506 /* Place-holder. Leave as last. */
7507 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
7510 /* PAIRED predicates. */
7511 static const struct builtin_description bdesc_paired_preds[] =
7513 /* Place-holder. Leave as first. */
7514 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
7515 /* Place-holder. Leave as last. */
7516 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
7519 /* ABS* operations. */
7521 static const struct builtin_description bdesc_abs[] =
7523 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
7524 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
7525 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
7526 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
7527 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
7528 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
7529 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
7532 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
7533 foo (VECa). */
7535 static struct builtin_description bdesc_1arg[] =
7537 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
7538 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
7539 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
7540 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
7541 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
7542 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
7543 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
7544 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
7545 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
7546 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
7547 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
7548 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
7549 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
7550 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
7551 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
7552 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
7553 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
7555 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
7556 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
7557 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
7558 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
7559 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
7560 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
7561 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
7562 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
7563 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
7564 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
7565 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
7566 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
7567 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
7568 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
7569 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
7570 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
7571 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
7572 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
7573 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
7575 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
7576 end with SPE_BUILTIN_EVSUBFUSIAAW. */
7577 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
7578 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
7579 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
7580 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
7581 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
7582 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
7583 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
7584 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
7585 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
7586 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
7587 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
7588 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
7589 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
7590 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
7591 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
7592 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
7593 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
7594 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
7595 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
7596 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
7597 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
7598 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
7599 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
7600 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
7601 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
7602 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
7603 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
7604 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
7606 /* Place-holder. Leave as last unary SPE builtin. */
7607 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
7609 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
7610 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
7611 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
7612 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
7613 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
7616 static rtx
7617 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
7619 rtx pat;
7620 tree arg0 = CALL_EXPR_ARG (exp, 0);
7621 rtx op0 = expand_normal (arg0);
7622 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7623 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7625 if (icode == CODE_FOR_nothing)
7626 /* Builtin not supported on this processor. */
7627 return 0;
7629 /* If we got invalid arguments bail out before generating bad rtl. */
7630 if (arg0 == error_mark_node)
7631 return const0_rtx;
7633 if (icode == CODE_FOR_altivec_vspltisb
7634 || icode == CODE_FOR_altivec_vspltish
7635 || icode == CODE_FOR_altivec_vspltisw
7636 || icode == CODE_FOR_spe_evsplatfi
7637 || icode == CODE_FOR_spe_evsplati)
7639 /* Only allow 5-bit *signed* literals. */
7640 if (GET_CODE (op0) != CONST_INT
7641 || INTVAL (op0) > 15
7642 || INTVAL (op0) < -16)
7644 error ("argument 1 must be a 5-bit signed literal");
7645 return const0_rtx;
7649 if (target == 0
7650 || GET_MODE (target) != tmode
7651 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7652 target = gen_reg_rtx (tmode);
7654 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7655 op0 = copy_to_mode_reg (mode0, op0);
7657 pat = GEN_FCN (icode) (target, op0);
7658 if (! pat)
7659 return 0;
7660 emit_insn (pat);
7662 return target;
7665 static rtx
7666 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
7668 rtx pat, scratch1, scratch2;
7669 tree arg0 = CALL_EXPR_ARG (exp, 0);
7670 rtx op0 = expand_normal (arg0);
7671 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7672 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7674 /* If we have invalid arguments, bail out before generating bad rtl. */
7675 if (arg0 == error_mark_node)
7676 return const0_rtx;
7678 if (target == 0
7679 || GET_MODE (target) != tmode
7680 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7681 target = gen_reg_rtx (tmode);
7683 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7684 op0 = copy_to_mode_reg (mode0, op0);
7686 scratch1 = gen_reg_rtx (mode0);
7687 scratch2 = gen_reg_rtx (mode0);
7689 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
7690 if (! pat)
7691 return 0;
7692 emit_insn (pat);
7694 return target;
7697 static rtx
7698 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
7700 rtx pat;
7701 tree arg0 = CALL_EXPR_ARG (exp, 0);
7702 tree arg1 = CALL_EXPR_ARG (exp, 1);
7703 rtx op0 = expand_normal (arg0);
7704 rtx op1 = expand_normal (arg1);
7705 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7706 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7707 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7709 if (icode == CODE_FOR_nothing)
7710 /* Builtin not supported on this processor. */
7711 return 0;
7713 /* If we got invalid arguments bail out before generating bad rtl. */
7714 if (arg0 == error_mark_node || arg1 == error_mark_node)
7715 return const0_rtx;
7717 if (icode == CODE_FOR_altivec_vcfux
7718 || icode == CODE_FOR_altivec_vcfsx
7719 || icode == CODE_FOR_altivec_vctsxs
7720 || icode == CODE_FOR_altivec_vctuxs
7721 || icode == CODE_FOR_altivec_vspltb
7722 || icode == CODE_FOR_altivec_vsplth
7723 || icode == CODE_FOR_altivec_vspltw
7724 || icode == CODE_FOR_spe_evaddiw
7725 || icode == CODE_FOR_spe_evldd
7726 || icode == CODE_FOR_spe_evldh
7727 || icode == CODE_FOR_spe_evldw
7728 || icode == CODE_FOR_spe_evlhhesplat
7729 || icode == CODE_FOR_spe_evlhhossplat
7730 || icode == CODE_FOR_spe_evlhhousplat
7731 || icode == CODE_FOR_spe_evlwhe
7732 || icode == CODE_FOR_spe_evlwhos
7733 || icode == CODE_FOR_spe_evlwhou
7734 || icode == CODE_FOR_spe_evlwhsplat
7735 || icode == CODE_FOR_spe_evlwwsplat
7736 || icode == CODE_FOR_spe_evrlwi
7737 || icode == CODE_FOR_spe_evslwi
7738 || icode == CODE_FOR_spe_evsrwis
7739 || icode == CODE_FOR_spe_evsubifw
7740 || icode == CODE_FOR_spe_evsrwiu)
7742 /* Only allow 5-bit unsigned literals. */
7743 STRIP_NOPS (arg1);
7744 if (TREE_CODE (arg1) != INTEGER_CST
7745 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7747 error ("argument 2 must be a 5-bit unsigned literal");
7748 return const0_rtx;
7752 if (target == 0
7753 || GET_MODE (target) != tmode
7754 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7755 target = gen_reg_rtx (tmode);
7757 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7758 op0 = copy_to_mode_reg (mode0, op0);
7759 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7760 op1 = copy_to_mode_reg (mode1, op1);
7762 pat = GEN_FCN (icode) (target, op0, op1);
7763 if (! pat)
7764 return 0;
7765 emit_insn (pat);
7767 return target;
7770 static rtx
7771 altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
7772 tree exp, rtx target)
7774 rtx pat, scratch;
7775 tree cr6_form = CALL_EXPR_ARG (exp, 0);
7776 tree arg0 = CALL_EXPR_ARG (exp, 1);
7777 tree arg1 = CALL_EXPR_ARG (exp, 2);
7778 rtx op0 = expand_normal (arg0);
7779 rtx op1 = expand_normal (arg1);
7780 enum machine_mode tmode = SImode;
7781 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7782 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7783 int cr6_form_int;
7785 if (TREE_CODE (cr6_form) != INTEGER_CST)
7787 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7788 return const0_rtx;
7790 else
7791 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
7793 gcc_assert (mode0 == mode1);
7795 /* If we have invalid arguments, bail out before generating bad rtl. */
7796 if (arg0 == error_mark_node || arg1 == error_mark_node)
7797 return const0_rtx;
7799 if (target == 0
7800 || GET_MODE (target) != tmode
7801 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7802 target = gen_reg_rtx (tmode);
7804 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7805 op0 = copy_to_mode_reg (mode0, op0);
7806 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7807 op1 = copy_to_mode_reg (mode1, op1);
7809 scratch = gen_reg_rtx (mode0);
7811 pat = GEN_FCN (icode) (scratch, op0, op1,
7812 gen_rtx_SYMBOL_REF (Pmode, opcode));
7813 if (! pat)
7814 return 0;
7815 emit_insn (pat);
7817 /* The vec_any* and vec_all* predicates use the same opcodes for two
7818 different operations, but the bits in CR6 will be different
7819 depending on what information we want. So we have to play tricks
7820 with CR6 to get the right bits out.
7822 If you think this is disgusting, look at the specs for the
7823 AltiVec predicates. */
7825 switch (cr6_form_int)
7827 case 0:
7828 emit_insn (gen_cr6_test_for_zero (target));
7829 break;
7830 case 1:
7831 emit_insn (gen_cr6_test_for_zero_reverse (target));
7832 break;
7833 case 2:
7834 emit_insn (gen_cr6_test_for_lt (target));
7835 break;
7836 case 3:
7837 emit_insn (gen_cr6_test_for_lt_reverse (target));
7838 break;
7839 default:
7840 error ("argument 1 of __builtin_altivec_predicate is out of range");
7841 break;
7844 return target;
7847 static rtx
7848 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
7850 rtx pat, addr;
7851 tree arg0 = CALL_EXPR_ARG (exp, 0);
7852 tree arg1 = CALL_EXPR_ARG (exp, 1);
7853 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7854 enum machine_mode mode0 = Pmode;
7855 enum machine_mode mode1 = Pmode;
7856 rtx op0 = expand_normal (arg0);
7857 rtx op1 = expand_normal (arg1);
7859 if (icode == CODE_FOR_nothing)
7860 /* Builtin not supported on this processor. */
7861 return 0;
7863 /* If we got invalid arguments bail out before generating bad rtl. */
7864 if (arg0 == error_mark_node || arg1 == error_mark_node)
7865 return const0_rtx;
7867 if (target == 0
7868 || GET_MODE (target) != tmode
7869 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7870 target = gen_reg_rtx (tmode);
7872 op1 = copy_to_mode_reg (mode1, op1);
7874 if (op0 == const0_rtx)
7876 addr = gen_rtx_MEM (tmode, op1);
7878 else
7880 op0 = copy_to_mode_reg (mode0, op0);
7881 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7884 pat = GEN_FCN (icode) (target, addr);
7886 if (! pat)
7887 return 0;
7888 emit_insn (pat);
7890 return target;
7893 static rtx
7894 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
7896 rtx pat, addr;
7897 tree arg0 = CALL_EXPR_ARG (exp, 0);
7898 tree arg1 = CALL_EXPR_ARG (exp, 1);
7899 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7900 enum machine_mode mode0 = Pmode;
7901 enum machine_mode mode1 = Pmode;
7902 rtx op0 = expand_normal (arg0);
7903 rtx op1 = expand_normal (arg1);
7905 if (icode == CODE_FOR_nothing)
7906 /* Builtin not supported on this processor. */
7907 return 0;
7909 /* If we got invalid arguments bail out before generating bad rtl. */
7910 if (arg0 == error_mark_node || arg1 == error_mark_node)
7911 return const0_rtx;
7913 if (target == 0
7914 || GET_MODE (target) != tmode
7915 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7916 target = gen_reg_rtx (tmode);
7918 op1 = copy_to_mode_reg (mode1, op1);
7920 if (op0 == const0_rtx)
7922 addr = gen_rtx_MEM (tmode, op1);
7924 else
7926 op0 = copy_to_mode_reg (mode0, op0);
7927 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7930 pat = GEN_FCN (icode) (target, addr);
7932 if (! pat)
7933 return 0;
7934 emit_insn (pat);
7936 return target;
7939 static rtx
7940 spe_expand_stv_builtin (enum insn_code icode, tree exp)
7942 tree arg0 = CALL_EXPR_ARG (exp, 0);
7943 tree arg1 = CALL_EXPR_ARG (exp, 1);
7944 tree arg2 = CALL_EXPR_ARG (exp, 2);
7945 rtx op0 = expand_normal (arg0);
7946 rtx op1 = expand_normal (arg1);
7947 rtx op2 = expand_normal (arg2);
7948 rtx pat;
7949 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
7950 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
7951 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
7953 /* Invalid arguments. Bail before doing anything stoopid! */
7954 if (arg0 == error_mark_node
7955 || arg1 == error_mark_node
7956 || arg2 == error_mark_node)
7957 return const0_rtx;
7959 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
7960 op0 = copy_to_mode_reg (mode2, op0);
7961 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
7962 op1 = copy_to_mode_reg (mode0, op1);
7963 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7964 op2 = copy_to_mode_reg (mode1, op2);
7966 pat = GEN_FCN (icode) (op1, op2, op0);
7967 if (pat)
7968 emit_insn (pat);
7969 return NULL_RTX;
7972 static rtx
7973 paired_expand_stv_builtin (enum insn_code icode, tree exp)
7975 tree arg0 = CALL_EXPR_ARG (exp, 0);
7976 tree arg1 = CALL_EXPR_ARG (exp, 1);
7977 tree arg2 = CALL_EXPR_ARG (exp, 2);
7978 rtx op0 = expand_normal (arg0);
7979 rtx op1 = expand_normal (arg1);
7980 rtx op2 = expand_normal (arg2);
7981 rtx pat, addr;
7982 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7983 enum machine_mode mode1 = Pmode;
7984 enum machine_mode mode2 = Pmode;
7986 /* Invalid arguments. Bail before doing anything stoopid! */
7987 if (arg0 == error_mark_node
7988 || arg1 == error_mark_node
7989 || arg2 == error_mark_node)
7990 return const0_rtx;
7992 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
7993 op0 = copy_to_mode_reg (tmode, op0);
7995 op2 = copy_to_mode_reg (mode2, op2);
7997 if (op1 == const0_rtx)
7999 addr = gen_rtx_MEM (tmode, op2);
8001 else
8003 op1 = copy_to_mode_reg (mode1, op1);
8004 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
8007 pat = GEN_FCN (icode) (addr, op0);
8008 if (pat)
8009 emit_insn (pat);
8010 return NULL_RTX;
8013 static rtx
8014 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
8016 tree arg0 = CALL_EXPR_ARG (exp, 0);
8017 tree arg1 = CALL_EXPR_ARG (exp, 1);
8018 tree arg2 = CALL_EXPR_ARG (exp, 2);
8019 rtx op0 = expand_normal (arg0);
8020 rtx op1 = expand_normal (arg1);
8021 rtx op2 = expand_normal (arg2);
8022 rtx pat, addr;
8023 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8024 enum machine_mode mode1 = Pmode;
8025 enum machine_mode mode2 = Pmode;
8027 /* Invalid arguments. Bail before doing anything stoopid! */
8028 if (arg0 == error_mark_node
8029 || arg1 == error_mark_node
8030 || arg2 == error_mark_node)
8031 return const0_rtx;
8033 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
8034 op0 = copy_to_mode_reg (tmode, op0);
8036 op2 = copy_to_mode_reg (mode2, op2);
8038 if (op1 == const0_rtx)
8040 addr = gen_rtx_MEM (tmode, op2);
8042 else
8044 op1 = copy_to_mode_reg (mode1, op1);
8045 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
8048 pat = GEN_FCN (icode) (addr, op0);
8049 if (pat)
8050 emit_insn (pat);
8051 return NULL_RTX;
8054 static rtx
8055 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
8057 rtx pat;
8058 tree arg0 = CALL_EXPR_ARG (exp, 0);
8059 tree arg1 = CALL_EXPR_ARG (exp, 1);
8060 tree arg2 = CALL_EXPR_ARG (exp, 2);
8061 rtx op0 = expand_normal (arg0);
8062 rtx op1 = expand_normal (arg1);
8063 rtx op2 = expand_normal (arg2);
8064 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8065 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8066 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8067 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
8069 if (icode == CODE_FOR_nothing)
8070 /* Builtin not supported on this processor. */
8071 return 0;
8073 /* If we got invalid arguments bail out before generating bad rtl. */
8074 if (arg0 == error_mark_node
8075 || arg1 == error_mark_node
8076 || arg2 == error_mark_node)
8077 return const0_rtx;
8079 if (icode == CODE_FOR_altivec_vsldoi_v4sf
8080 || icode == CODE_FOR_altivec_vsldoi_v4si
8081 || icode == CODE_FOR_altivec_vsldoi_v8hi
8082 || icode == CODE_FOR_altivec_vsldoi_v16qi)
8084 /* Only allow 4-bit unsigned literals. */
8085 STRIP_NOPS (arg2);
8086 if (TREE_CODE (arg2) != INTEGER_CST
8087 || TREE_INT_CST_LOW (arg2) & ~0xf)
8089 error ("argument 3 must be a 4-bit unsigned literal");
8090 return const0_rtx;
8094 if (target == 0
8095 || GET_MODE (target) != tmode
8096 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8097 target = gen_reg_rtx (tmode);
8099 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8100 op0 = copy_to_mode_reg (mode0, op0);
8101 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
8102 op1 = copy_to_mode_reg (mode1, op1);
8103 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
8104 op2 = copy_to_mode_reg (mode2, op2);
8106 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
8107 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
8108 else
8109 pat = GEN_FCN (icode) (target, op0, op1, op2);
8110 if (! pat)
8111 return 0;
8112 emit_insn (pat);
8114 return target;
8117 /* Expand the lvx builtins. */
8118 static rtx
8119 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
8121 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8122 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8123 tree arg0;
8124 enum machine_mode tmode, mode0;
8125 rtx pat, op0;
8126 enum insn_code icode;
8128 switch (fcode)
8130 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
8131 icode = CODE_FOR_altivec_lvx_v16qi;
8132 break;
8133 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
8134 icode = CODE_FOR_altivec_lvx_v8hi;
8135 break;
8136 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
8137 icode = CODE_FOR_altivec_lvx_v4si;
8138 break;
8139 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
8140 icode = CODE_FOR_altivec_lvx_v4sf;
8141 break;
8142 default:
8143 *expandedp = false;
8144 return NULL_RTX;
8147 *expandedp = true;
8149 arg0 = CALL_EXPR_ARG (exp, 0);
8150 op0 = expand_normal (arg0);
8151 tmode = insn_data[icode].operand[0].mode;
8152 mode0 = insn_data[icode].operand[1].mode;
8154 if (target == 0
8155 || GET_MODE (target) != tmode
8156 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8157 target = gen_reg_rtx (tmode);
8159 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8160 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
8162 pat = GEN_FCN (icode) (target, op0);
8163 if (! pat)
8164 return 0;
8165 emit_insn (pat);
8166 return target;
8169 /* Expand the stvx builtins. */
8170 static rtx
8171 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
8172 bool *expandedp)
8174 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8175 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8176 tree arg0, arg1;
8177 enum machine_mode mode0, mode1;
8178 rtx pat, op0, op1;
8179 enum insn_code icode;
8181 switch (fcode)
8183 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
8184 icode = CODE_FOR_altivec_stvx_v16qi;
8185 break;
8186 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
8187 icode = CODE_FOR_altivec_stvx_v8hi;
8188 break;
8189 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
8190 icode = CODE_FOR_altivec_stvx_v4si;
8191 break;
8192 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
8193 icode = CODE_FOR_altivec_stvx_v4sf;
8194 break;
8195 default:
8196 *expandedp = false;
8197 return NULL_RTX;
8200 arg0 = CALL_EXPR_ARG (exp, 0);
8201 arg1 = CALL_EXPR_ARG (exp, 1);
8202 op0 = expand_normal (arg0);
8203 op1 = expand_normal (arg1);
8204 mode0 = insn_data[icode].operand[0].mode;
8205 mode1 = insn_data[icode].operand[1].mode;
8207 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8208 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
8209 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
8210 op1 = copy_to_mode_reg (mode1, op1);
8212 pat = GEN_FCN (icode) (op0, op1);
8213 if (pat)
8214 emit_insn (pat);
8216 *expandedp = true;
8217 return NULL_RTX;
8220 /* Expand the dst builtins. */
8221 static rtx
8222 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
8223 bool *expandedp)
8225 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8226 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8227 tree arg0, arg1, arg2;
8228 enum machine_mode mode0, mode1, mode2;
8229 rtx pat, op0, op1, op2;
8230 const struct builtin_description *d;
8231 size_t i;
8233 *expandedp = false;
8235 /* Handle DST variants. */
8236 d = bdesc_dst;
8237 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8238 if (d->code == fcode)
8240 arg0 = CALL_EXPR_ARG (exp, 0);
8241 arg1 = CALL_EXPR_ARG (exp, 1);
8242 arg2 = CALL_EXPR_ARG (exp, 2);
8243 op0 = expand_normal (arg0);
8244 op1 = expand_normal (arg1);
8245 op2 = expand_normal (arg2);
8246 mode0 = insn_data[d->icode].operand[0].mode;
8247 mode1 = insn_data[d->icode].operand[1].mode;
8248 mode2 = insn_data[d->icode].operand[2].mode;
8250 /* Invalid arguments, bail out before generating bad rtl. */
8251 if (arg0 == error_mark_node
8252 || arg1 == error_mark_node
8253 || arg2 == error_mark_node)
8254 return const0_rtx;
8256 *expandedp = true;
8257 STRIP_NOPS (arg2);
8258 if (TREE_CODE (arg2) != INTEGER_CST
8259 || TREE_INT_CST_LOW (arg2) & ~0x3)
8261 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
8262 return const0_rtx;
8265 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
8266 op0 = copy_to_mode_reg (Pmode, op0);
8267 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
8268 op1 = copy_to_mode_reg (mode1, op1);
8270 pat = GEN_FCN (d->icode) (op0, op1, op2);
8271 if (pat != 0)
8272 emit_insn (pat);
8274 return NULL_RTX;
8277 return NULL_RTX;
8280 /* Expand vec_init builtin. */
8281 static rtx
8282 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
8284 enum machine_mode tmode = TYPE_MODE (type);
8285 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
8286 int i, n_elt = GET_MODE_NUNITS (tmode);
8287 rtvec v = rtvec_alloc (n_elt);
8289 gcc_assert (VECTOR_MODE_P (tmode));
8290 gcc_assert (n_elt == call_expr_nargs (exp));
8292 for (i = 0; i < n_elt; ++i)
8294 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
8295 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
8298 if (!target || !register_operand (target, tmode))
8299 target = gen_reg_rtx (tmode);
8301 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
8302 return target;
8305 /* Return the integer constant in ARG. Constrain it to be in the range
8306 of the subparts of VEC_TYPE; issue an error if not. */
8308 static int
8309 get_element_number (tree vec_type, tree arg)
8311 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
8313 if (!host_integerp (arg, 1)
8314 || (elt = tree_low_cst (arg, 1), elt > max))
8316 error ("selector must be an integer constant in the range 0..%wi", max);
8317 return 0;
8320 return elt;
8323 /* Expand vec_set builtin. */
8324 static rtx
8325 altivec_expand_vec_set_builtin (tree exp)
8327 enum machine_mode tmode, mode1;
8328 tree arg0, arg1, arg2;
8329 int elt;
8330 rtx op0, op1;
8332 arg0 = CALL_EXPR_ARG (exp, 0);
8333 arg1 = CALL_EXPR_ARG (exp, 1);
8334 arg2 = CALL_EXPR_ARG (exp, 2);
8336 tmode = TYPE_MODE (TREE_TYPE (arg0));
8337 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
8338 gcc_assert (VECTOR_MODE_P (tmode));
8340 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
8341 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
8342 elt = get_element_number (TREE_TYPE (arg0), arg2);
8344 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
8345 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
8347 op0 = force_reg (tmode, op0);
8348 op1 = force_reg (mode1, op1);
8350 rs6000_expand_vector_set (op0, op1, elt);
8352 return op0;
8355 /* Expand vec_ext builtin. */
8356 static rtx
8357 altivec_expand_vec_ext_builtin (tree exp, rtx target)
8359 enum machine_mode tmode, mode0;
8360 tree arg0, arg1;
8361 int elt;
8362 rtx op0;
8364 arg0 = CALL_EXPR_ARG (exp, 0);
8365 arg1 = CALL_EXPR_ARG (exp, 1);
8367 op0 = expand_normal (arg0);
8368 elt = get_element_number (TREE_TYPE (arg0), arg1);
8370 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
8371 mode0 = TYPE_MODE (TREE_TYPE (arg0));
8372 gcc_assert (VECTOR_MODE_P (mode0));
8374 op0 = force_reg (mode0, op0);
8376 if (optimize || !target || !register_operand (target, tmode))
8377 target = gen_reg_rtx (tmode);
8379 rs6000_expand_vector_extract (target, op0, elt);
8381 return target;
8384 /* Expand the builtin in EXP and store the result in TARGET. Store
8385 true in *EXPANDEDP if we found a builtin to expand. */
8386 static rtx
8387 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
8389 const struct builtin_description *d;
8390 const struct builtin_description_predicates *dp;
8391 size_t i;
8392 enum insn_code icode;
8393 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8394 tree arg0;
8395 rtx op0, pat;
8396 enum machine_mode tmode, mode0;
8397 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8399 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8400 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
8402 *expandedp = true;
8403 error ("unresolved overload for Altivec builtin %qF", fndecl);
8404 return const0_rtx;
8407 target = altivec_expand_ld_builtin (exp, target, expandedp);
8408 if (*expandedp)
8409 return target;
8411 target = altivec_expand_st_builtin (exp, target, expandedp);
8412 if (*expandedp)
8413 return target;
8415 target = altivec_expand_dst_builtin (exp, target, expandedp);
8416 if (*expandedp)
8417 return target;
8419 *expandedp = true;
8421 switch (fcode)
8423 case ALTIVEC_BUILTIN_STVX:
8424 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
8425 case ALTIVEC_BUILTIN_STVEBX:
8426 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
8427 case ALTIVEC_BUILTIN_STVEHX:
8428 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
8429 case ALTIVEC_BUILTIN_STVEWX:
8430 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
8431 case ALTIVEC_BUILTIN_STVXL:
8432 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
8434 case ALTIVEC_BUILTIN_MFVSCR:
8435 icode = CODE_FOR_altivec_mfvscr;
8436 tmode = insn_data[icode].operand[0].mode;
8438 if (target == 0
8439 || GET_MODE (target) != tmode
8440 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8441 target = gen_reg_rtx (tmode);
8443 pat = GEN_FCN (icode) (target);
8444 if (! pat)
8445 return 0;
8446 emit_insn (pat);
8447 return target;
8449 case ALTIVEC_BUILTIN_MTVSCR:
8450 icode = CODE_FOR_altivec_mtvscr;
8451 arg0 = CALL_EXPR_ARG (exp, 0);
8452 op0 = expand_normal (arg0);
8453 mode0 = insn_data[icode].operand[0].mode;
8455 /* If we got invalid arguments bail out before generating bad rtl. */
8456 if (arg0 == error_mark_node)
8457 return const0_rtx;
8459 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8460 op0 = copy_to_mode_reg (mode0, op0);
8462 pat = GEN_FCN (icode) (op0);
8463 if (pat)
8464 emit_insn (pat);
8465 return NULL_RTX;
8467 case ALTIVEC_BUILTIN_DSSALL:
8468 emit_insn (gen_altivec_dssall ());
8469 return NULL_RTX;
8471 case ALTIVEC_BUILTIN_DSS:
8472 icode = CODE_FOR_altivec_dss;
8473 arg0 = CALL_EXPR_ARG (exp, 0);
8474 STRIP_NOPS (arg0);
8475 op0 = expand_normal (arg0);
8476 mode0 = insn_data[icode].operand[0].mode;
8478 /* If we got invalid arguments bail out before generating bad rtl. */
8479 if (arg0 == error_mark_node)
8480 return const0_rtx;
8482 if (TREE_CODE (arg0) != INTEGER_CST
8483 || TREE_INT_CST_LOW (arg0) & ~0x3)
8485 error ("argument to dss must be a 2-bit unsigned literal");
8486 return const0_rtx;
8489 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8490 op0 = copy_to_mode_reg (mode0, op0);
8492 emit_insn (gen_altivec_dss (op0));
8493 return NULL_RTX;
8495 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
8496 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
8497 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
8498 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
8499 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
8501 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
8502 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
8503 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
8504 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
8505 return altivec_expand_vec_set_builtin (exp);
8507 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
8508 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
8509 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
8510 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
8511 return altivec_expand_vec_ext_builtin (exp, target);
8513 default:
8514 break;
8515 /* Fall through. */
8518 /* Expand abs* operations. */
8519 d = bdesc_abs;
8520 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
8521 if (d->code == fcode)
8522 return altivec_expand_abs_builtin (d->icode, exp, target);
8524 /* Expand the AltiVec predicates. */
8525 dp = bdesc_altivec_preds;
8526 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
8527 if (dp->code == fcode)
8528 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
8529 exp, target);
8531 /* LV* are funky. We initialized them differently. */
8532 switch (fcode)
8534 case ALTIVEC_BUILTIN_LVSL:
8535 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
8536 exp, target);
8537 case ALTIVEC_BUILTIN_LVSR:
8538 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
8539 exp, target);
8540 case ALTIVEC_BUILTIN_LVEBX:
8541 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
8542 exp, target);
8543 case ALTIVEC_BUILTIN_LVEHX:
8544 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
8545 exp, target);
8546 case ALTIVEC_BUILTIN_LVEWX:
8547 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
8548 exp, target);
8549 case ALTIVEC_BUILTIN_LVXL:
8550 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
8551 exp, target);
8552 case ALTIVEC_BUILTIN_LVX:
8553 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
8554 exp, target);
8555 default:
8556 break;
8557 /* Fall through. */
8560 *expandedp = false;
8561 return NULL_RTX;
8564 /* Expand the builtin in EXP and store the result in TARGET. Store
8565 true in *EXPANDEDP if we found a builtin to expand. */
8566 static rtx
8567 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
8569 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8570 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8571 const struct builtin_description *d;
8572 size_t i;
8574 *expandedp = true;
8576 switch (fcode)
8578 case PAIRED_BUILTIN_STX:
8579 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
8580 case PAIRED_BUILTIN_LX:
8581 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
8582 default:
8583 break;
8584 /* Fall through. */
8587 /* Expand the paired predicates. */
8588 d = bdesc_paired_preds;
8589 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
8590 if (d->code == fcode)
8591 return paired_expand_predicate_builtin (d->icode, exp, target);
8593 *expandedp = false;
8594 return NULL_RTX;
8597 /* Binops that need to be initialized manually, but can be expanded
8598 automagically by rs6000_expand_binop_builtin. */
8599 static struct builtin_description bdesc_2arg_spe[] =
8601 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
8602 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
8603 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
8604 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
8605 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
8606 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
8607 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
8608 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
8609 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
8610 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
8611 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
8612 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
8613 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
8614 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
8615 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
8616 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
8617 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
8618 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
8619 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
8620 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
8621 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
8622 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
8625 /* Expand the builtin in EXP and store the result in TARGET. Store
8626 true in *EXPANDEDP if we found a builtin to expand.
8628 This expands the SPE builtins that are not simple unary and binary
8629 operations. */
8630 static rtx
8631 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
8633 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8634 tree arg1, arg0;
8635 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8636 enum insn_code icode;
8637 enum machine_mode tmode, mode0;
8638 rtx pat, op0;
8639 struct builtin_description *d;
8640 size_t i;
8642 *expandedp = true;
8644 /* Syntax check for a 5-bit unsigned immediate. */
8645 switch (fcode)
8647 case SPE_BUILTIN_EVSTDD:
8648 case SPE_BUILTIN_EVSTDH:
8649 case SPE_BUILTIN_EVSTDW:
8650 case SPE_BUILTIN_EVSTWHE:
8651 case SPE_BUILTIN_EVSTWHO:
8652 case SPE_BUILTIN_EVSTWWE:
8653 case SPE_BUILTIN_EVSTWWO:
8654 arg1 = CALL_EXPR_ARG (exp, 2);
8655 if (TREE_CODE (arg1) != INTEGER_CST
8656 || TREE_INT_CST_LOW (arg1) & ~0x1f)
8658 error ("argument 2 must be a 5-bit unsigned literal");
8659 return const0_rtx;
8661 break;
8662 default:
8663 break;
8666 /* The evsplat*i instructions are not quite generic. */
8667 switch (fcode)
8669 case SPE_BUILTIN_EVSPLATFI:
8670 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
8671 exp, target);
8672 case SPE_BUILTIN_EVSPLATI:
8673 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
8674 exp, target);
8675 default:
8676 break;
8679 d = (struct builtin_description *) bdesc_2arg_spe;
8680 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
8681 if (d->code == fcode)
8682 return rs6000_expand_binop_builtin (d->icode, exp, target);
8684 d = (struct builtin_description *) bdesc_spe_predicates;
8685 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
8686 if (d->code == fcode)
8687 return spe_expand_predicate_builtin (d->icode, exp, target);
8689 d = (struct builtin_description *) bdesc_spe_evsel;
8690 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
8691 if (d->code == fcode)
8692 return spe_expand_evsel_builtin (d->icode, exp, target);
8694 switch (fcode)
8696 case SPE_BUILTIN_EVSTDDX:
8697 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
8698 case SPE_BUILTIN_EVSTDHX:
8699 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
8700 case SPE_BUILTIN_EVSTDWX:
8701 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
8702 case SPE_BUILTIN_EVSTWHEX:
8703 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
8704 case SPE_BUILTIN_EVSTWHOX:
8705 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
8706 case SPE_BUILTIN_EVSTWWEX:
8707 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
8708 case SPE_BUILTIN_EVSTWWOX:
8709 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
8710 case SPE_BUILTIN_EVSTDD:
8711 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
8712 case SPE_BUILTIN_EVSTDH:
8713 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
8714 case SPE_BUILTIN_EVSTDW:
8715 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
8716 case SPE_BUILTIN_EVSTWHE:
8717 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
8718 case SPE_BUILTIN_EVSTWHO:
8719 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
8720 case SPE_BUILTIN_EVSTWWE:
8721 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
8722 case SPE_BUILTIN_EVSTWWO:
8723 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
8724 case SPE_BUILTIN_MFSPEFSCR:
8725 icode = CODE_FOR_spe_mfspefscr;
8726 tmode = insn_data[icode].operand[0].mode;
8728 if (target == 0
8729 || GET_MODE (target) != tmode
8730 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8731 target = gen_reg_rtx (tmode);
8733 pat = GEN_FCN (icode) (target);
8734 if (! pat)
8735 return 0;
8736 emit_insn (pat);
8737 return target;
8738 case SPE_BUILTIN_MTSPEFSCR:
8739 icode = CODE_FOR_spe_mtspefscr;
8740 arg0 = CALL_EXPR_ARG (exp, 0);
8741 op0 = expand_normal (arg0);
8742 mode0 = insn_data[icode].operand[0].mode;
8744 if (arg0 == error_mark_node)
8745 return const0_rtx;
8747 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8748 op0 = copy_to_mode_reg (mode0, op0);
8750 pat = GEN_FCN (icode) (op0);
8751 if (pat)
8752 emit_insn (pat);
8753 return NULL_RTX;
8754 default:
8755 break;
8758 *expandedp = false;
8759 return NULL_RTX;
8762 static rtx
8763 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
8765 rtx pat, scratch, tmp;
8766 tree form = CALL_EXPR_ARG (exp, 0);
8767 tree arg0 = CALL_EXPR_ARG (exp, 1);
8768 tree arg1 = CALL_EXPR_ARG (exp, 2);
8769 rtx op0 = expand_normal (arg0);
8770 rtx op1 = expand_normal (arg1);
8771 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8772 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8773 int form_int;
8774 enum rtx_code code;
8776 if (TREE_CODE (form) != INTEGER_CST)
8778 error ("argument 1 of __builtin_paired_predicate must be a constant");
8779 return const0_rtx;
8781 else
8782 form_int = TREE_INT_CST_LOW (form);
8784 gcc_assert (mode0 == mode1);
8786 if (arg0 == error_mark_node || arg1 == error_mark_node)
8787 return const0_rtx;
8789 if (target == 0
8790 || GET_MODE (target) != SImode
8791 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
8792 target = gen_reg_rtx (SImode);
8793 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
8794 op0 = copy_to_mode_reg (mode0, op0);
8795 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
8796 op1 = copy_to_mode_reg (mode1, op1);
8798 scratch = gen_reg_rtx (CCFPmode);
8800 pat = GEN_FCN (icode) (scratch, op0, op1);
8801 if (!pat)
8802 return const0_rtx;
8804 emit_insn (pat);
8806 switch (form_int)
8808 /* LT bit. */
8809 case 0:
8810 code = LT;
8811 break;
8812 /* GT bit. */
8813 case 1:
8814 code = GT;
8815 break;
8816 /* EQ bit. */
8817 case 2:
8818 code = EQ;
8819 break;
8820 /* UN bit. */
8821 case 3:
8822 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
8823 return target;
8824 default:
8825 error ("argument 1 of __builtin_paired_predicate is out of range");
8826 return const0_rtx;
8829 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8830 emit_move_insn (target, tmp);
8831 return target;
8834 static rtx
8835 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
8837 rtx pat, scratch, tmp;
8838 tree form = CALL_EXPR_ARG (exp, 0);
8839 tree arg0 = CALL_EXPR_ARG (exp, 1);
8840 tree arg1 = CALL_EXPR_ARG (exp, 2);
8841 rtx op0 = expand_normal (arg0);
8842 rtx op1 = expand_normal (arg1);
8843 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8844 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8845 int form_int;
8846 enum rtx_code code;
8848 if (TREE_CODE (form) != INTEGER_CST)
8850 error ("argument 1 of __builtin_spe_predicate must be a constant");
8851 return const0_rtx;
8853 else
8854 form_int = TREE_INT_CST_LOW (form);
8856 gcc_assert (mode0 == mode1);
8858 if (arg0 == error_mark_node || arg1 == error_mark_node)
8859 return const0_rtx;
8861 if (target == 0
8862 || GET_MODE (target) != SImode
8863 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
8864 target = gen_reg_rtx (SImode);
8866 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8867 op0 = copy_to_mode_reg (mode0, op0);
8868 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
8869 op1 = copy_to_mode_reg (mode1, op1);
8871 scratch = gen_reg_rtx (CCmode);
8873 pat = GEN_FCN (icode) (scratch, op0, op1);
8874 if (! pat)
8875 return const0_rtx;
8876 emit_insn (pat);
8878 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
8879 _lower_. We use one compare, but look in different bits of the
8880 CR for each variant.
8882 There are 2 elements in each SPE simd type (upper/lower). The CR
8883 bits are set as follows:
8885 BIT0 | BIT 1 | BIT 2 | BIT 3
8886 U | L | (U | L) | (U & L)
8888 So, for an "all" relationship, BIT 3 would be set.
8889 For an "any" relationship, BIT 2 would be set. Etc.
8891 Following traditional nomenclature, these bits map to:
8893 BIT0 | BIT 1 | BIT 2 | BIT 3
8894 LT | GT | EQ | OV
8896 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8899 switch (form_int)
8901 /* All variant. OV bit. */
8902 case 0:
8903 /* We need to get to the OV bit, which is the ORDERED bit. We
8904 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
8905 that's ugly and will make validate_condition_mode die.
8906 So let's just use another pattern. */
8907 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
8908 return target;
8909 /* Any variant. EQ bit. */
8910 case 1:
8911 code = EQ;
8912 break;
8913 /* Upper variant. LT bit. */
8914 case 2:
8915 code = LT;
8916 break;
8917 /* Lower variant. GT bit. */
8918 case 3:
8919 code = GT;
8920 break;
8921 default:
8922 error ("argument 1 of __builtin_spe_predicate is out of range");
8923 return const0_rtx;
8926 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8927 emit_move_insn (target, tmp);
8929 return target;
8932 /* The evsel builtins look like this:
8934 e = __builtin_spe_evsel_OP (a, b, c, d);
8936 and work like this:
8938 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8939 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8942 static rtx
8943 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
8945 rtx pat, scratch;
8946 tree arg0 = CALL_EXPR_ARG (exp, 0);
8947 tree arg1 = CALL_EXPR_ARG (exp, 1);
8948 tree arg2 = CALL_EXPR_ARG (exp, 2);
8949 tree arg3 = CALL_EXPR_ARG (exp, 3);
8950 rtx op0 = expand_normal (arg0);
8951 rtx op1 = expand_normal (arg1);
8952 rtx op2 = expand_normal (arg2);
8953 rtx op3 = expand_normal (arg3);
8954 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8955 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8957 gcc_assert (mode0 == mode1);
8959 if (arg0 == error_mark_node || arg1 == error_mark_node
8960 || arg2 == error_mark_node || arg3 == error_mark_node)
8961 return const0_rtx;
8963 if (target == 0
8964 || GET_MODE (target) != mode0
8965 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
8966 target = gen_reg_rtx (mode0);
8968 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8969 op0 = copy_to_mode_reg (mode0, op0);
8970 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
8971 op1 = copy_to_mode_reg (mode0, op1);
8972 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
8973 op2 = copy_to_mode_reg (mode0, op2);
8974 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
8975 op3 = copy_to_mode_reg (mode0, op3);
8977 /* Generate the compare. */
8978 scratch = gen_reg_rtx (CCmode);
8979 pat = GEN_FCN (icode) (scratch, op0, op1);
8980 if (! pat)
8981 return const0_rtx;
8982 emit_insn (pat);
8984 if (mode0 == V2SImode)
8985 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
8986 else
8987 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
8989 return target;
8992 /* Expand an expression EXP that calls a built-in function,
8993 with result going to TARGET if that's convenient
8994 (and in mode MODE if that's convenient).
8995 SUBTARGET may be used as the target for computing one of EXP's operands.
8996 IGNORE is nonzero if the value is to be ignored. */
8998 static rtx
8999 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
9000 enum machine_mode mode ATTRIBUTE_UNUSED,
9001 int ignore ATTRIBUTE_UNUSED)
9003 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9004 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9005 const struct builtin_description *d;
9006 size_t i;
9007 rtx ret;
9008 bool success;
9010 if (fcode == RS6000_BUILTIN_RECIP)
9011 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
9013 if (fcode == RS6000_BUILTIN_RECIPF)
9014 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
9016 if (fcode == RS6000_BUILTIN_RSQRTF)
9017 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
9019 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
9020 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
9022 int icode = (int) CODE_FOR_altivec_lvsr;
9023 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9024 enum machine_mode mode = insn_data[icode].operand[1].mode;
9025 tree arg;
9026 rtx op, addr, pat;
9028 gcc_assert (TARGET_ALTIVEC);
9030 arg = CALL_EXPR_ARG (exp, 0);
9031 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
9032 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
9033 addr = memory_address (mode, op);
9034 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
9035 op = addr;
9036 else
9038 /* For the load case need to negate the address. */
9039 op = gen_reg_rtx (GET_MODE (addr));
9040 emit_insn (gen_rtx_SET (VOIDmode, op,
9041 gen_rtx_NEG (GET_MODE (addr), addr)));
9043 op = gen_rtx_MEM (mode, op);
9045 if (target == 0
9046 || GET_MODE (target) != tmode
9047 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9048 target = gen_reg_rtx (tmode);
9050 /*pat = gen_altivec_lvsr (target, op);*/
9051 pat = GEN_FCN (icode) (target, op);
9052 if (!pat)
9053 return 0;
9054 emit_insn (pat);
9056 return target;
9059 /* FIXME: There's got to be a nicer way to handle this case than
9060 constructing a new CALL_EXPR. */
9061 if (fcode == ALTIVEC_BUILTIN_VCFUX
9062 || fcode == ALTIVEC_BUILTIN_VCFSX)
9064 if (call_expr_nargs (exp) == 1)
9065 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
9066 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
9069 if (TARGET_ALTIVEC)
9071 ret = altivec_expand_builtin (exp, target, &success);
9073 if (success)
9074 return ret;
9076 if (TARGET_SPE)
9078 ret = spe_expand_builtin (exp, target, &success);
9080 if (success)
9081 return ret;
9083 if (TARGET_PAIRED_FLOAT)
9085 ret = paired_expand_builtin (exp, target, &success);
9087 if (success)
9088 return ret;
9091 gcc_assert (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT);
9093 /* Handle simple unary operations. */
9094 d = (struct builtin_description *) bdesc_1arg;
9095 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
9096 if (d->code == fcode)
9097 return rs6000_expand_unop_builtin (d->icode, exp, target);
9099 /* Handle simple binary operations. */
9100 d = (struct builtin_description *) bdesc_2arg;
9101 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
9102 if (d->code == fcode)
9103 return rs6000_expand_binop_builtin (d->icode, exp, target);
9105 /* Handle simple ternary operations. */
9106 d = bdesc_3arg;
9107 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
9108 if (d->code == fcode)
9109 return rs6000_expand_ternop_builtin (d->icode, exp, target);
9111 gcc_unreachable ();
9114 static tree
9115 build_opaque_vector_type (tree node, int nunits)
9117 node = copy_node (node);
9118 TYPE_MAIN_VARIANT (node) = node;
9119 return build_vector_type (node, nunits);
9122 static void
9123 rs6000_init_builtins (void)
9125 V2SI_type_node = build_vector_type (intSI_type_node, 2);
9126 V2SF_type_node = build_vector_type (float_type_node, 2);
9127 V4HI_type_node = build_vector_type (intHI_type_node, 4);
9128 V4SI_type_node = build_vector_type (intSI_type_node, 4);
9129 V4SF_type_node = build_vector_type (float_type_node, 4);
9130 V8HI_type_node = build_vector_type (intHI_type_node, 8);
9131 V16QI_type_node = build_vector_type (intQI_type_node, 16);
9133 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
9134 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
9135 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
9137 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
9138 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
9139 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
9140 opaque_V4SI_type_node = copy_node (V4SI_type_node);
9142 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
9143 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
9144 'vector unsigned short'. */
9146 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
9147 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
9148 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
9149 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
9151 long_integer_type_internal_node = long_integer_type_node;
9152 long_unsigned_type_internal_node = long_unsigned_type_node;
9153 intQI_type_internal_node = intQI_type_node;
9154 uintQI_type_internal_node = unsigned_intQI_type_node;
9155 intHI_type_internal_node = intHI_type_node;
9156 uintHI_type_internal_node = unsigned_intHI_type_node;
9157 intSI_type_internal_node = intSI_type_node;
9158 uintSI_type_internal_node = unsigned_intSI_type_node;
9159 float_type_internal_node = float_type_node;
9160 void_type_internal_node = void_type_node;
9162 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9163 get_identifier ("__bool char"),
9164 bool_char_type_node));
9165 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9166 get_identifier ("__bool short"),
9167 bool_short_type_node));
9168 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9169 get_identifier ("__bool int"),
9170 bool_int_type_node));
9171 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9172 get_identifier ("__pixel"),
9173 pixel_type_node));
9175 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
9176 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
9177 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
9178 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
9180 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9181 get_identifier ("__vector unsigned char"),
9182 unsigned_V16QI_type_node));
9183 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9184 get_identifier ("__vector signed char"),
9185 V16QI_type_node));
9186 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9187 get_identifier ("__vector __bool char"),
9188 bool_V16QI_type_node));
9190 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9191 get_identifier ("__vector unsigned short"),
9192 unsigned_V8HI_type_node));
9193 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9194 get_identifier ("__vector signed short"),
9195 V8HI_type_node));
9196 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9197 get_identifier ("__vector __bool short"),
9198 bool_V8HI_type_node));
9200 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9201 get_identifier ("__vector unsigned int"),
9202 unsigned_V4SI_type_node));
9203 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9204 get_identifier ("__vector signed int"),
9205 V4SI_type_node));
9206 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9207 get_identifier ("__vector __bool int"),
9208 bool_V4SI_type_node));
9210 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9211 get_identifier ("__vector float"),
9212 V4SF_type_node));
9213 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
9214 get_identifier ("__vector __pixel"),
9215 pixel_V8HI_type_node));
9217 if (TARGET_PAIRED_FLOAT)
9218 paired_init_builtins ();
9219 if (TARGET_SPE)
9220 spe_init_builtins ();
9221 if (TARGET_ALTIVEC)
9222 altivec_init_builtins ();
9223 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT)
9224 rs6000_common_init_builtins ();
9225 if (TARGET_PPC_GFXOPT)
9227 tree ftype = build_function_type_list (float_type_node,
9228 float_type_node,
9229 float_type_node,
9230 NULL_TREE);
9231 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
9232 RS6000_BUILTIN_RECIPF);
9234 ftype = build_function_type_list (float_type_node,
9235 float_type_node,
9236 NULL_TREE);
9237 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
9238 RS6000_BUILTIN_RSQRTF);
9240 if (TARGET_POPCNTB)
9242 tree ftype = build_function_type_list (double_type_node,
9243 double_type_node,
9244 double_type_node,
9245 NULL_TREE);
9246 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
9247 RS6000_BUILTIN_RECIP);
9251 #if TARGET_XCOFF
9252 /* AIX libm provides clog as __clog. */
9253 if (built_in_decls [BUILT_IN_CLOG])
9254 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
9255 #endif
9257 #ifdef SUBTARGET_INIT_BUILTINS
9258 SUBTARGET_INIT_BUILTINS;
9259 #endif
9262 /* Search through a set of builtins and enable the mask bits.
9263 DESC is an array of builtins.
9264 SIZE is the total number of builtins.
9265 START is the builtin enum at which to start.
9266 END is the builtin enum at which to end. */
9267 static void
9268 enable_mask_for_builtins (struct builtin_description *desc, int size,
9269 enum rs6000_builtins start,
9270 enum rs6000_builtins end)
9272 int i;
9274 for (i = 0; i < size; ++i)
9275 if (desc[i].code == start)
9276 break;
9278 if (i == size)
9279 return;
9281 for (; i < size; ++i)
9283 /* Flip all the bits on. */
9284 desc[i].mask = target_flags;
9285 if (desc[i].code == end)
9286 break;
9290 static void
9291 spe_init_builtins (void)
9293 tree endlink = void_list_node;
9294 tree puint_type_node = build_pointer_type (unsigned_type_node);
9295 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
9296 struct builtin_description *d;
9297 size_t i;
9299 tree v2si_ftype_4_v2si
9300 = build_function_type
9301 (opaque_V2SI_type_node,
9302 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9303 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9304 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9305 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9306 endlink)))));
9308 tree v2sf_ftype_4_v2sf
9309 = build_function_type
9310 (opaque_V2SF_type_node,
9311 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9312 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9313 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9314 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9315 endlink)))));
9317 tree int_ftype_int_v2si_v2si
9318 = build_function_type
9319 (integer_type_node,
9320 tree_cons (NULL_TREE, integer_type_node,
9321 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9322 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9323 endlink))));
9325 tree int_ftype_int_v2sf_v2sf
9326 = build_function_type
9327 (integer_type_node,
9328 tree_cons (NULL_TREE, integer_type_node,
9329 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9330 tree_cons (NULL_TREE, opaque_V2SF_type_node,
9331 endlink))));
9333 tree void_ftype_v2si_puint_int
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 integer_type_node,
9339 endlink))));
9341 tree void_ftype_v2si_puint_char
9342 = build_function_type (void_type_node,
9343 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9344 tree_cons (NULL_TREE, puint_type_node,
9345 tree_cons (NULL_TREE,
9346 char_type_node,
9347 endlink))));
9349 tree void_ftype_v2si_pv2si_int
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 integer_type_node,
9355 endlink))));
9357 tree void_ftype_v2si_pv2si_char
9358 = build_function_type (void_type_node,
9359 tree_cons (NULL_TREE, opaque_V2SI_type_node,
9360 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
9361 tree_cons (NULL_TREE,
9362 char_type_node,
9363 endlink))));
9365 tree void_ftype_int
9366 = build_function_type (void_type_node,
9367 tree_cons (NULL_TREE, integer_type_node, endlink));
9369 tree int_ftype_void
9370 = build_function_type (integer_type_node, endlink);
9372 tree v2si_ftype_pv2si_int
9373 = build_function_type (opaque_V2SI_type_node,
9374 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
9375 tree_cons (NULL_TREE, integer_type_node,
9376 endlink)));
9378 tree v2si_ftype_puint_int
9379 = build_function_type (opaque_V2SI_type_node,
9380 tree_cons (NULL_TREE, puint_type_node,
9381 tree_cons (NULL_TREE, integer_type_node,
9382 endlink)));
9384 tree v2si_ftype_pushort_int
9385 = build_function_type (opaque_V2SI_type_node,
9386 tree_cons (NULL_TREE, pushort_type_node,
9387 tree_cons (NULL_TREE, integer_type_node,
9388 endlink)));
9390 tree v2si_ftype_signed_char
9391 = build_function_type (opaque_V2SI_type_node,
9392 tree_cons (NULL_TREE, signed_char_type_node,
9393 endlink));
9395 /* The initialization of the simple binary and unary builtins is
9396 done in rs6000_common_init_builtins, but we have to enable the
9397 mask bits here manually because we have run out of `target_flags'
9398 bits. We really need to redesign this mask business. */
9400 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
9401 ARRAY_SIZE (bdesc_2arg),
9402 SPE_BUILTIN_EVADDW,
9403 SPE_BUILTIN_EVXOR);
9404 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
9405 ARRAY_SIZE (bdesc_1arg),
9406 SPE_BUILTIN_EVABS,
9407 SPE_BUILTIN_EVSUBFUSIAAW);
9408 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
9409 ARRAY_SIZE (bdesc_spe_predicates),
9410 SPE_BUILTIN_EVCMPEQ,
9411 SPE_BUILTIN_EVFSTSTLT);
9412 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
9413 ARRAY_SIZE (bdesc_spe_evsel),
9414 SPE_BUILTIN_EVSEL_CMPGTS,
9415 SPE_BUILTIN_EVSEL_FSTSTEQ);
9417 (*lang_hooks.decls.pushdecl)
9418 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
9419 opaque_V2SI_type_node));
9421 /* Initialize irregular SPE builtins. */
9423 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
9424 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
9425 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
9426 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
9427 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
9428 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
9429 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
9430 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
9431 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
9432 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
9433 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
9434 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
9435 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
9436 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
9437 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
9438 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
9439 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
9440 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
9442 /* Loads. */
9443 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
9444 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
9445 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
9446 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
9447 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
9448 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
9449 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
9450 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
9451 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
9452 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
9453 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
9454 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
9455 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
9456 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
9457 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
9458 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
9459 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
9460 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
9461 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
9462 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
9463 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
9464 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
9466 /* Predicates. */
9467 d = (struct builtin_description *) bdesc_spe_predicates;
9468 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
9470 tree type;
9472 switch (insn_data[d->icode].operand[1].mode)
9474 case V2SImode:
9475 type = int_ftype_int_v2si_v2si;
9476 break;
9477 case V2SFmode:
9478 type = int_ftype_int_v2sf_v2sf;
9479 break;
9480 default:
9481 gcc_unreachable ();
9484 def_builtin (d->mask, d->name, type, d->code);
9487 /* Evsel predicates. */
9488 d = (struct builtin_description *) bdesc_spe_evsel;
9489 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
9491 tree type;
9493 switch (insn_data[d->icode].operand[1].mode)
9495 case V2SImode:
9496 type = v2si_ftype_4_v2si;
9497 break;
9498 case V2SFmode:
9499 type = v2sf_ftype_4_v2sf;
9500 break;
9501 default:
9502 gcc_unreachable ();
9505 def_builtin (d->mask, d->name, type, d->code);
9509 static void
9510 paired_init_builtins (void)
9512 const struct builtin_description *d;
9513 size_t i;
9514 tree endlink = void_list_node;
9516 tree int_ftype_int_v2sf_v2sf
9517 = build_function_type
9518 (integer_type_node,
9519 tree_cons (NULL_TREE, integer_type_node,
9520 tree_cons (NULL_TREE, V2SF_type_node,
9521 tree_cons (NULL_TREE, V2SF_type_node,
9522 endlink))));
9523 tree pcfloat_type_node =
9524 build_pointer_type (build_qualified_type
9525 (float_type_node, TYPE_QUAL_CONST));
9527 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
9528 long_integer_type_node,
9529 pcfloat_type_node,
9530 NULL_TREE);
9531 tree void_ftype_v2sf_long_pcfloat =
9532 build_function_type_list (void_type_node,
9533 V2SF_type_node,
9534 long_integer_type_node,
9535 pcfloat_type_node,
9536 NULL_TREE);
9539 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
9540 PAIRED_BUILTIN_LX);
9543 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
9544 PAIRED_BUILTIN_STX);
9546 /* Predicates. */
9547 d = bdesc_paired_preds;
9548 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
9550 tree type;
9552 switch (insn_data[d->icode].operand[1].mode)
9554 case V2SFmode:
9555 type = int_ftype_int_v2sf_v2sf;
9556 break;
9557 default:
9558 gcc_unreachable ();
9561 def_builtin (d->mask, d->name, type, d->code);
9565 static void
9566 altivec_init_builtins (void)
9568 const struct builtin_description *d;
9569 const struct builtin_description_predicates *dp;
9570 size_t i;
9571 tree ftype;
9573 tree pfloat_type_node = build_pointer_type (float_type_node);
9574 tree pint_type_node = build_pointer_type (integer_type_node);
9575 tree pshort_type_node = build_pointer_type (short_integer_type_node);
9576 tree pchar_type_node = build_pointer_type (char_type_node);
9578 tree pvoid_type_node = build_pointer_type (void_type_node);
9580 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
9581 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
9582 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
9583 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
9585 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
9587 tree int_ftype_opaque
9588 = build_function_type_list (integer_type_node,
9589 opaque_V4SI_type_node, NULL_TREE);
9591 tree opaque_ftype_opaque_int
9592 = build_function_type_list (opaque_V4SI_type_node,
9593 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
9594 tree opaque_ftype_opaque_opaque_int
9595 = build_function_type_list (opaque_V4SI_type_node,
9596 opaque_V4SI_type_node, opaque_V4SI_type_node,
9597 integer_type_node, NULL_TREE);
9598 tree int_ftype_int_opaque_opaque
9599 = build_function_type_list (integer_type_node,
9600 integer_type_node, opaque_V4SI_type_node,
9601 opaque_V4SI_type_node, NULL_TREE);
9602 tree int_ftype_int_v4si_v4si
9603 = build_function_type_list (integer_type_node,
9604 integer_type_node, V4SI_type_node,
9605 V4SI_type_node, NULL_TREE);
9606 tree v4sf_ftype_pcfloat
9607 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
9608 tree void_ftype_pfloat_v4sf
9609 = build_function_type_list (void_type_node,
9610 pfloat_type_node, V4SF_type_node, NULL_TREE);
9611 tree v4si_ftype_pcint
9612 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
9613 tree void_ftype_pint_v4si
9614 = build_function_type_list (void_type_node,
9615 pint_type_node, V4SI_type_node, NULL_TREE);
9616 tree v8hi_ftype_pcshort
9617 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
9618 tree void_ftype_pshort_v8hi
9619 = build_function_type_list (void_type_node,
9620 pshort_type_node, V8HI_type_node, NULL_TREE);
9621 tree v16qi_ftype_pcchar
9622 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
9623 tree void_ftype_pchar_v16qi
9624 = build_function_type_list (void_type_node,
9625 pchar_type_node, V16QI_type_node, NULL_TREE);
9626 tree void_ftype_v4si
9627 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
9628 tree v8hi_ftype_void
9629 = build_function_type (V8HI_type_node, void_list_node);
9630 tree void_ftype_void
9631 = build_function_type (void_type_node, void_list_node);
9632 tree void_ftype_int
9633 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
9635 tree opaque_ftype_long_pcvoid
9636 = build_function_type_list (opaque_V4SI_type_node,
9637 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9638 tree v16qi_ftype_long_pcvoid
9639 = build_function_type_list (V16QI_type_node,
9640 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9641 tree v8hi_ftype_long_pcvoid
9642 = build_function_type_list (V8HI_type_node,
9643 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9644 tree v4si_ftype_long_pcvoid
9645 = build_function_type_list (V4SI_type_node,
9646 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9648 tree void_ftype_opaque_long_pvoid
9649 = build_function_type_list (void_type_node,
9650 opaque_V4SI_type_node, long_integer_type_node,
9651 pvoid_type_node, NULL_TREE);
9652 tree void_ftype_v4si_long_pvoid
9653 = build_function_type_list (void_type_node,
9654 V4SI_type_node, long_integer_type_node,
9655 pvoid_type_node, NULL_TREE);
9656 tree void_ftype_v16qi_long_pvoid
9657 = build_function_type_list (void_type_node,
9658 V16QI_type_node, long_integer_type_node,
9659 pvoid_type_node, NULL_TREE);
9660 tree void_ftype_v8hi_long_pvoid
9661 = build_function_type_list (void_type_node,
9662 V8HI_type_node, long_integer_type_node,
9663 pvoid_type_node, NULL_TREE);
9664 tree int_ftype_int_v8hi_v8hi
9665 = build_function_type_list (integer_type_node,
9666 integer_type_node, V8HI_type_node,
9667 V8HI_type_node, NULL_TREE);
9668 tree int_ftype_int_v16qi_v16qi
9669 = build_function_type_list (integer_type_node,
9670 integer_type_node, V16QI_type_node,
9671 V16QI_type_node, NULL_TREE);
9672 tree int_ftype_int_v4sf_v4sf
9673 = build_function_type_list (integer_type_node,
9674 integer_type_node, V4SF_type_node,
9675 V4SF_type_node, NULL_TREE);
9676 tree v4si_ftype_v4si
9677 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
9678 tree v8hi_ftype_v8hi
9679 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
9680 tree v16qi_ftype_v16qi
9681 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
9682 tree v4sf_ftype_v4sf
9683 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
9684 tree void_ftype_pcvoid_int_int
9685 = build_function_type_list (void_type_node,
9686 pcvoid_type_node, integer_type_node,
9687 integer_type_node, NULL_TREE);
9689 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
9690 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
9691 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
9692 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
9693 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
9694 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
9695 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
9696 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
9697 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
9698 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
9699 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
9700 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
9701 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
9702 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
9703 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
9704 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
9705 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
9706 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
9707 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
9708 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
9709 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
9710 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
9711 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
9712 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
9713 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
9714 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
9715 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
9716 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
9717 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
9718 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
9719 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
9720 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
9721 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
9722 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
9723 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
9724 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
9725 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
9726 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
9727 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
9728 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
9729 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
9730 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
9731 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
9732 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
9733 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
9734 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
9736 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
9738 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
9739 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
9740 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
9741 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
9742 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
9743 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
9744 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
9745 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
9746 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
9747 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
9749 /* Add the DST variants. */
9750 d = bdesc_dst;
9751 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
9752 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
9754 /* Initialize the predicates. */
9755 dp = bdesc_altivec_preds;
9756 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
9758 enum machine_mode mode1;
9759 tree type;
9760 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9761 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9763 if (is_overloaded)
9764 mode1 = VOIDmode;
9765 else
9766 mode1 = insn_data[dp->icode].operand[1].mode;
9768 switch (mode1)
9770 case VOIDmode:
9771 type = int_ftype_int_opaque_opaque;
9772 break;
9773 case V4SImode:
9774 type = int_ftype_int_v4si_v4si;
9775 break;
9776 case V8HImode:
9777 type = int_ftype_int_v8hi_v8hi;
9778 break;
9779 case V16QImode:
9780 type = int_ftype_int_v16qi_v16qi;
9781 break;
9782 case V4SFmode:
9783 type = int_ftype_int_v4sf_v4sf;
9784 break;
9785 default:
9786 gcc_unreachable ();
9789 def_builtin (dp->mask, dp->name, type, dp->code);
9792 /* Initialize the abs* operators. */
9793 d = bdesc_abs;
9794 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
9796 enum machine_mode mode0;
9797 tree type;
9799 mode0 = insn_data[d->icode].operand[0].mode;
9801 switch (mode0)
9803 case V4SImode:
9804 type = v4si_ftype_v4si;
9805 break;
9806 case V8HImode:
9807 type = v8hi_ftype_v8hi;
9808 break;
9809 case V16QImode:
9810 type = v16qi_ftype_v16qi;
9811 break;
9812 case V4SFmode:
9813 type = v4sf_ftype_v4sf;
9814 break;
9815 default:
9816 gcc_unreachable ();
9819 def_builtin (d->mask, d->name, type, d->code);
9822 if (TARGET_ALTIVEC)
9824 tree decl;
9826 /* Initialize target builtin that implements
9827 targetm.vectorize.builtin_mask_for_load. */
9829 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
9830 v16qi_ftype_long_pcvoid,
9831 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
9832 BUILT_IN_MD, NULL, NULL_TREE);
9833 TREE_READONLY (decl) = 1;
9834 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
9835 altivec_builtin_mask_for_load = decl;
9838 /* Access to the vec_init patterns. */
9839 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
9840 integer_type_node, integer_type_node,
9841 integer_type_node, NULL_TREE);
9842 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
9843 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
9845 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
9846 short_integer_type_node,
9847 short_integer_type_node,
9848 short_integer_type_node,
9849 short_integer_type_node,
9850 short_integer_type_node,
9851 short_integer_type_node,
9852 short_integer_type_node, NULL_TREE);
9853 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
9854 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
9856 ftype = build_function_type_list (V16QI_type_node, char_type_node,
9857 char_type_node, char_type_node,
9858 char_type_node, char_type_node,
9859 char_type_node, char_type_node,
9860 char_type_node, char_type_node,
9861 char_type_node, char_type_node,
9862 char_type_node, char_type_node,
9863 char_type_node, char_type_node,
9864 char_type_node, NULL_TREE);
9865 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
9866 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
9868 ftype = build_function_type_list (V4SF_type_node, float_type_node,
9869 float_type_node, float_type_node,
9870 float_type_node, NULL_TREE);
9871 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
9872 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
9874 /* Access to the vec_set patterns. */
9875 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
9876 intSI_type_node,
9877 integer_type_node, NULL_TREE);
9878 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
9879 ALTIVEC_BUILTIN_VEC_SET_V4SI);
9881 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
9882 intHI_type_node,
9883 integer_type_node, NULL_TREE);
9884 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
9885 ALTIVEC_BUILTIN_VEC_SET_V8HI);
9887 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
9888 intQI_type_node,
9889 integer_type_node, NULL_TREE);
9890 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
9891 ALTIVEC_BUILTIN_VEC_SET_V16QI);
9893 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
9894 float_type_node,
9895 integer_type_node, NULL_TREE);
9896 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
9897 ALTIVEC_BUILTIN_VEC_SET_V4SF);
9899 /* Access to the vec_extract patterns. */
9900 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
9901 integer_type_node, NULL_TREE);
9902 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
9903 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
9905 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
9906 integer_type_node, NULL_TREE);
9907 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
9908 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
9910 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
9911 integer_type_node, NULL_TREE);
9912 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
9913 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
9915 ftype = build_function_type_list (float_type_node, V4SF_type_node,
9916 integer_type_node, NULL_TREE);
9917 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
9918 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
9921 static void
9922 rs6000_common_init_builtins (void)
9924 const struct builtin_description *d;
9925 size_t i;
9927 tree v2sf_ftype_v2sf_v2sf_v2sf
9928 = build_function_type_list (V2SF_type_node,
9929 V2SF_type_node, V2SF_type_node,
9930 V2SF_type_node, NULL_TREE);
9932 tree v4sf_ftype_v4sf_v4sf_v16qi
9933 = build_function_type_list (V4SF_type_node,
9934 V4SF_type_node, V4SF_type_node,
9935 V16QI_type_node, NULL_TREE);
9936 tree v4si_ftype_v4si_v4si_v16qi
9937 = build_function_type_list (V4SI_type_node,
9938 V4SI_type_node, V4SI_type_node,
9939 V16QI_type_node, NULL_TREE);
9940 tree v8hi_ftype_v8hi_v8hi_v16qi
9941 = build_function_type_list (V8HI_type_node,
9942 V8HI_type_node, V8HI_type_node,
9943 V16QI_type_node, NULL_TREE);
9944 tree v16qi_ftype_v16qi_v16qi_v16qi
9945 = build_function_type_list (V16QI_type_node,
9946 V16QI_type_node, V16QI_type_node,
9947 V16QI_type_node, NULL_TREE);
9948 tree v4si_ftype_int
9949 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
9950 tree v8hi_ftype_int
9951 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
9952 tree v16qi_ftype_int
9953 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
9954 tree v8hi_ftype_v16qi
9955 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
9956 tree v4sf_ftype_v4sf
9957 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
9959 tree v2si_ftype_v2si_v2si
9960 = build_function_type_list (opaque_V2SI_type_node,
9961 opaque_V2SI_type_node,
9962 opaque_V2SI_type_node, NULL_TREE);
9964 tree v2sf_ftype_v2sf_v2sf_spe
9965 = build_function_type_list (opaque_V2SF_type_node,
9966 opaque_V2SF_type_node,
9967 opaque_V2SF_type_node, NULL_TREE);
9969 tree v2sf_ftype_v2sf_v2sf
9970 = build_function_type_list (V2SF_type_node,
9971 V2SF_type_node,
9972 V2SF_type_node, NULL_TREE);
9975 tree v2si_ftype_int_int
9976 = build_function_type_list (opaque_V2SI_type_node,
9977 integer_type_node, integer_type_node,
9978 NULL_TREE);
9980 tree opaque_ftype_opaque
9981 = build_function_type_list (opaque_V4SI_type_node,
9982 opaque_V4SI_type_node, NULL_TREE);
9984 tree v2si_ftype_v2si
9985 = build_function_type_list (opaque_V2SI_type_node,
9986 opaque_V2SI_type_node, NULL_TREE);
9988 tree v2sf_ftype_v2sf_spe
9989 = build_function_type_list (opaque_V2SF_type_node,
9990 opaque_V2SF_type_node, NULL_TREE);
9992 tree v2sf_ftype_v2sf
9993 = build_function_type_list (V2SF_type_node,
9994 V2SF_type_node, NULL_TREE);
9996 tree v2sf_ftype_v2si
9997 = build_function_type_list (opaque_V2SF_type_node,
9998 opaque_V2SI_type_node, NULL_TREE);
10000 tree v2si_ftype_v2sf
10001 = build_function_type_list (opaque_V2SI_type_node,
10002 opaque_V2SF_type_node, NULL_TREE);
10004 tree v2si_ftype_v2si_char
10005 = build_function_type_list (opaque_V2SI_type_node,
10006 opaque_V2SI_type_node,
10007 char_type_node, NULL_TREE);
10009 tree v2si_ftype_int_char
10010 = build_function_type_list (opaque_V2SI_type_node,
10011 integer_type_node, char_type_node, NULL_TREE);
10013 tree v2si_ftype_char
10014 = build_function_type_list (opaque_V2SI_type_node,
10015 char_type_node, NULL_TREE);
10017 tree int_ftype_int_int
10018 = build_function_type_list (integer_type_node,
10019 integer_type_node, integer_type_node,
10020 NULL_TREE);
10022 tree opaque_ftype_opaque_opaque
10023 = build_function_type_list (opaque_V4SI_type_node,
10024 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
10025 tree v4si_ftype_v4si_v4si
10026 = build_function_type_list (V4SI_type_node,
10027 V4SI_type_node, V4SI_type_node, NULL_TREE);
10028 tree v4sf_ftype_v4si_int
10029 = build_function_type_list (V4SF_type_node,
10030 V4SI_type_node, integer_type_node, NULL_TREE);
10031 tree v4si_ftype_v4sf_int
10032 = build_function_type_list (V4SI_type_node,
10033 V4SF_type_node, integer_type_node, NULL_TREE);
10034 tree v4si_ftype_v4si_int
10035 = build_function_type_list (V4SI_type_node,
10036 V4SI_type_node, integer_type_node, NULL_TREE);
10037 tree v8hi_ftype_v8hi_int
10038 = build_function_type_list (V8HI_type_node,
10039 V8HI_type_node, integer_type_node, NULL_TREE);
10040 tree v16qi_ftype_v16qi_int
10041 = build_function_type_list (V16QI_type_node,
10042 V16QI_type_node, integer_type_node, NULL_TREE);
10043 tree v16qi_ftype_v16qi_v16qi_int
10044 = build_function_type_list (V16QI_type_node,
10045 V16QI_type_node, V16QI_type_node,
10046 integer_type_node, NULL_TREE);
10047 tree v8hi_ftype_v8hi_v8hi_int
10048 = build_function_type_list (V8HI_type_node,
10049 V8HI_type_node, V8HI_type_node,
10050 integer_type_node, NULL_TREE);
10051 tree v4si_ftype_v4si_v4si_int
10052 = build_function_type_list (V4SI_type_node,
10053 V4SI_type_node, V4SI_type_node,
10054 integer_type_node, NULL_TREE);
10055 tree v4sf_ftype_v4sf_v4sf_int
10056 = build_function_type_list (V4SF_type_node,
10057 V4SF_type_node, V4SF_type_node,
10058 integer_type_node, NULL_TREE);
10059 tree v4sf_ftype_v4sf_v4sf
10060 = build_function_type_list (V4SF_type_node,
10061 V4SF_type_node, V4SF_type_node, NULL_TREE);
10062 tree opaque_ftype_opaque_opaque_opaque
10063 = build_function_type_list (opaque_V4SI_type_node,
10064 opaque_V4SI_type_node, opaque_V4SI_type_node,
10065 opaque_V4SI_type_node, NULL_TREE);
10066 tree v4sf_ftype_v4sf_v4sf_v4si
10067 = build_function_type_list (V4SF_type_node,
10068 V4SF_type_node, V4SF_type_node,
10069 V4SI_type_node, NULL_TREE);
10070 tree v4sf_ftype_v4sf_v4sf_v4sf
10071 = build_function_type_list (V4SF_type_node,
10072 V4SF_type_node, V4SF_type_node,
10073 V4SF_type_node, NULL_TREE);
10074 tree v4si_ftype_v4si_v4si_v4si
10075 = build_function_type_list (V4SI_type_node,
10076 V4SI_type_node, V4SI_type_node,
10077 V4SI_type_node, NULL_TREE);
10078 tree v8hi_ftype_v8hi_v8hi
10079 = build_function_type_list (V8HI_type_node,
10080 V8HI_type_node, V8HI_type_node, NULL_TREE);
10081 tree v8hi_ftype_v8hi_v8hi_v8hi
10082 = build_function_type_list (V8HI_type_node,
10083 V8HI_type_node, V8HI_type_node,
10084 V8HI_type_node, NULL_TREE);
10085 tree v4si_ftype_v8hi_v8hi_v4si
10086 = build_function_type_list (V4SI_type_node,
10087 V8HI_type_node, V8HI_type_node,
10088 V4SI_type_node, NULL_TREE);
10089 tree v4si_ftype_v16qi_v16qi_v4si
10090 = build_function_type_list (V4SI_type_node,
10091 V16QI_type_node, V16QI_type_node,
10092 V4SI_type_node, NULL_TREE);
10093 tree v16qi_ftype_v16qi_v16qi
10094 = build_function_type_list (V16QI_type_node,
10095 V16QI_type_node, V16QI_type_node, NULL_TREE);
10096 tree v4si_ftype_v4sf_v4sf
10097 = build_function_type_list (V4SI_type_node,
10098 V4SF_type_node, V4SF_type_node, NULL_TREE);
10099 tree v8hi_ftype_v16qi_v16qi
10100 = build_function_type_list (V8HI_type_node,
10101 V16QI_type_node, V16QI_type_node, NULL_TREE);
10102 tree v4si_ftype_v8hi_v8hi
10103 = build_function_type_list (V4SI_type_node,
10104 V8HI_type_node, V8HI_type_node, NULL_TREE);
10105 tree v8hi_ftype_v4si_v4si
10106 = build_function_type_list (V8HI_type_node,
10107 V4SI_type_node, V4SI_type_node, NULL_TREE);
10108 tree v16qi_ftype_v8hi_v8hi
10109 = build_function_type_list (V16QI_type_node,
10110 V8HI_type_node, V8HI_type_node, NULL_TREE);
10111 tree v4si_ftype_v16qi_v4si
10112 = build_function_type_list (V4SI_type_node,
10113 V16QI_type_node, V4SI_type_node, NULL_TREE);
10114 tree v4si_ftype_v16qi_v16qi
10115 = build_function_type_list (V4SI_type_node,
10116 V16QI_type_node, V16QI_type_node, NULL_TREE);
10117 tree v4si_ftype_v8hi_v4si
10118 = build_function_type_list (V4SI_type_node,
10119 V8HI_type_node, V4SI_type_node, NULL_TREE);
10120 tree v4si_ftype_v8hi
10121 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
10122 tree int_ftype_v4si_v4si
10123 = build_function_type_list (integer_type_node,
10124 V4SI_type_node, V4SI_type_node, NULL_TREE);
10125 tree int_ftype_v4sf_v4sf
10126 = build_function_type_list (integer_type_node,
10127 V4SF_type_node, V4SF_type_node, NULL_TREE);
10128 tree int_ftype_v16qi_v16qi
10129 = build_function_type_list (integer_type_node,
10130 V16QI_type_node, V16QI_type_node, NULL_TREE);
10131 tree int_ftype_v8hi_v8hi
10132 = build_function_type_list (integer_type_node,
10133 V8HI_type_node, V8HI_type_node, NULL_TREE);
10135 /* Add the simple ternary operators. */
10136 d = bdesc_3arg;
10137 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10139 enum machine_mode mode0, mode1, mode2, mode3;
10140 tree type;
10141 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10142 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
10144 if (is_overloaded)
10146 mode0 = VOIDmode;
10147 mode1 = VOIDmode;
10148 mode2 = VOIDmode;
10149 mode3 = VOIDmode;
10151 else
10153 if (d->name == 0 || d->icode == CODE_FOR_nothing)
10154 continue;
10156 mode0 = insn_data[d->icode].operand[0].mode;
10157 mode1 = insn_data[d->icode].operand[1].mode;
10158 mode2 = insn_data[d->icode].operand[2].mode;
10159 mode3 = insn_data[d->icode].operand[3].mode;
10162 /* When all four are of the same mode. */
10163 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
10165 switch (mode0)
10167 case VOIDmode:
10168 type = opaque_ftype_opaque_opaque_opaque;
10169 break;
10170 case V4SImode:
10171 type = v4si_ftype_v4si_v4si_v4si;
10172 break;
10173 case V4SFmode:
10174 type = v4sf_ftype_v4sf_v4sf_v4sf;
10175 break;
10176 case V8HImode:
10177 type = v8hi_ftype_v8hi_v8hi_v8hi;
10178 break;
10179 case V16QImode:
10180 type = v16qi_ftype_v16qi_v16qi_v16qi;
10181 break;
10182 case V2SFmode:
10183 type = v2sf_ftype_v2sf_v2sf_v2sf;
10184 break;
10185 default:
10186 gcc_unreachable ();
10189 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
10191 switch (mode0)
10193 case V4SImode:
10194 type = v4si_ftype_v4si_v4si_v16qi;
10195 break;
10196 case V4SFmode:
10197 type = v4sf_ftype_v4sf_v4sf_v16qi;
10198 break;
10199 case V8HImode:
10200 type = v8hi_ftype_v8hi_v8hi_v16qi;
10201 break;
10202 case V16QImode:
10203 type = v16qi_ftype_v16qi_v16qi_v16qi;
10204 break;
10205 default:
10206 gcc_unreachable ();
10209 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
10210 && mode3 == V4SImode)
10211 type = v4si_ftype_v16qi_v16qi_v4si;
10212 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
10213 && mode3 == V4SImode)
10214 type = v4si_ftype_v8hi_v8hi_v4si;
10215 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
10216 && mode3 == V4SImode)
10217 type = v4sf_ftype_v4sf_v4sf_v4si;
10219 /* vchar, vchar, vchar, 4-bit literal. */
10220 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
10221 && mode3 == QImode)
10222 type = v16qi_ftype_v16qi_v16qi_int;
10224 /* vshort, vshort, vshort, 4-bit literal. */
10225 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
10226 && mode3 == QImode)
10227 type = v8hi_ftype_v8hi_v8hi_int;
10229 /* vint, vint, vint, 4-bit literal. */
10230 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
10231 && mode3 == QImode)
10232 type = v4si_ftype_v4si_v4si_int;
10234 /* vfloat, vfloat, vfloat, 4-bit literal. */
10235 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
10236 && mode3 == QImode)
10237 type = v4sf_ftype_v4sf_v4sf_int;
10239 else
10240 gcc_unreachable ();
10242 def_builtin (d->mask, d->name, type, d->code);
10245 /* Add the simple binary operators. */
10246 d = (struct builtin_description *) bdesc_2arg;
10247 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10249 enum machine_mode mode0, mode1, mode2;
10250 tree type;
10251 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10252 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
10254 if (is_overloaded)
10256 mode0 = VOIDmode;
10257 mode1 = VOIDmode;
10258 mode2 = VOIDmode;
10260 else
10262 if (d->name == 0 || d->icode == CODE_FOR_nothing)
10263 continue;
10265 mode0 = insn_data[d->icode].operand[0].mode;
10266 mode1 = insn_data[d->icode].operand[1].mode;
10267 mode2 = insn_data[d->icode].operand[2].mode;
10270 /* When all three operands are of the same mode. */
10271 if (mode0 == mode1 && mode1 == mode2)
10273 switch (mode0)
10275 case VOIDmode:
10276 type = opaque_ftype_opaque_opaque;
10277 break;
10278 case V4SFmode:
10279 type = v4sf_ftype_v4sf_v4sf;
10280 break;
10281 case V4SImode:
10282 type = v4si_ftype_v4si_v4si;
10283 break;
10284 case V16QImode:
10285 type = v16qi_ftype_v16qi_v16qi;
10286 break;
10287 case V8HImode:
10288 type = v8hi_ftype_v8hi_v8hi;
10289 break;
10290 case V2SImode:
10291 type = v2si_ftype_v2si_v2si;
10292 break;
10293 case V2SFmode:
10294 if (TARGET_PAIRED_FLOAT)
10295 type = v2sf_ftype_v2sf_v2sf;
10296 else
10297 type = v2sf_ftype_v2sf_v2sf_spe;
10298 break;
10299 case SImode:
10300 type = int_ftype_int_int;
10301 break;
10302 default:
10303 gcc_unreachable ();
10307 /* A few other combos we really don't want to do manually. */
10309 /* vint, vfloat, vfloat. */
10310 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
10311 type = v4si_ftype_v4sf_v4sf;
10313 /* vshort, vchar, vchar. */
10314 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
10315 type = v8hi_ftype_v16qi_v16qi;
10317 /* vint, vshort, vshort. */
10318 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
10319 type = v4si_ftype_v8hi_v8hi;
10321 /* vshort, vint, vint. */
10322 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
10323 type = v8hi_ftype_v4si_v4si;
10325 /* vchar, vshort, vshort. */
10326 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
10327 type = v16qi_ftype_v8hi_v8hi;
10329 /* vint, vchar, vint. */
10330 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
10331 type = v4si_ftype_v16qi_v4si;
10333 /* vint, vchar, vchar. */
10334 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
10335 type = v4si_ftype_v16qi_v16qi;
10337 /* vint, vshort, vint. */
10338 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
10339 type = v4si_ftype_v8hi_v4si;
10341 /* vint, vint, 5-bit literal. */
10342 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
10343 type = v4si_ftype_v4si_int;
10345 /* vshort, vshort, 5-bit literal. */
10346 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
10347 type = v8hi_ftype_v8hi_int;
10349 /* vchar, vchar, 5-bit literal. */
10350 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
10351 type = v16qi_ftype_v16qi_int;
10353 /* vfloat, vint, 5-bit literal. */
10354 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
10355 type = v4sf_ftype_v4si_int;
10357 /* vint, vfloat, 5-bit literal. */
10358 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
10359 type = v4si_ftype_v4sf_int;
10361 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
10362 type = v2si_ftype_int_int;
10364 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
10365 type = v2si_ftype_v2si_char;
10367 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
10368 type = v2si_ftype_int_char;
10370 else
10372 /* int, x, x. */
10373 gcc_assert (mode0 == SImode);
10374 switch (mode1)
10376 case V4SImode:
10377 type = int_ftype_v4si_v4si;
10378 break;
10379 case V4SFmode:
10380 type = int_ftype_v4sf_v4sf;
10381 break;
10382 case V16QImode:
10383 type = int_ftype_v16qi_v16qi;
10384 break;
10385 case V8HImode:
10386 type = int_ftype_v8hi_v8hi;
10387 break;
10388 default:
10389 gcc_unreachable ();
10393 def_builtin (d->mask, d->name, type, d->code);
10396 /* Add the simple unary operators. */
10397 d = (struct builtin_description *) bdesc_1arg;
10398 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10400 enum machine_mode mode0, mode1;
10401 tree type;
10402 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10403 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
10405 if (is_overloaded)
10407 mode0 = VOIDmode;
10408 mode1 = VOIDmode;
10410 else
10412 if (d->name == 0 || d->icode == CODE_FOR_nothing)
10413 continue;
10415 mode0 = insn_data[d->icode].operand[0].mode;
10416 mode1 = insn_data[d->icode].operand[1].mode;
10419 if (mode0 == V4SImode && mode1 == QImode)
10420 type = v4si_ftype_int;
10421 else if (mode0 == V8HImode && mode1 == QImode)
10422 type = v8hi_ftype_int;
10423 else if (mode0 == V16QImode && mode1 == QImode)
10424 type = v16qi_ftype_int;
10425 else if (mode0 == VOIDmode && mode1 == VOIDmode)
10426 type = opaque_ftype_opaque;
10427 else if (mode0 == V4SFmode && mode1 == V4SFmode)
10428 type = v4sf_ftype_v4sf;
10429 else if (mode0 == V8HImode && mode1 == V16QImode)
10430 type = v8hi_ftype_v16qi;
10431 else if (mode0 == V4SImode && mode1 == V8HImode)
10432 type = v4si_ftype_v8hi;
10433 else if (mode0 == V2SImode && mode1 == V2SImode)
10434 type = v2si_ftype_v2si;
10435 else if (mode0 == V2SFmode && mode1 == V2SFmode)
10437 if (TARGET_PAIRED_FLOAT)
10438 type = v2sf_ftype_v2sf;
10439 else
10440 type = v2sf_ftype_v2sf_spe;
10442 else if (mode0 == V2SFmode && mode1 == V2SImode)
10443 type = v2sf_ftype_v2si;
10444 else if (mode0 == V2SImode && mode1 == V2SFmode)
10445 type = v2si_ftype_v2sf;
10446 else if (mode0 == V2SImode && mode1 == QImode)
10447 type = v2si_ftype_char;
10448 else
10449 gcc_unreachable ();
10451 def_builtin (d->mask, d->name, type, d->code);
10455 static void
10456 rs6000_init_libfuncs (void)
10458 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
10459 && !TARGET_POWER2 && !TARGET_POWERPC)
10461 /* AIX library routines for float->int conversion. */
10462 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
10463 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
10464 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
10465 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
10468 if (!TARGET_IEEEQUAD)
10469 /* AIX/Darwin/64-bit Linux quad floating point routines. */
10470 if (!TARGET_XL_COMPAT)
10472 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
10473 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
10474 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
10475 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
10477 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
10479 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
10480 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
10481 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
10482 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
10483 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
10484 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
10485 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
10487 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
10488 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
10489 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
10490 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
10491 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
10492 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
10493 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
10494 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
10497 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
10498 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
10500 else
10502 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
10503 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
10504 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
10505 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
10507 else
10509 /* 32-bit SVR4 quad floating point routines. */
10511 set_optab_libfunc (add_optab, TFmode, "_q_add");
10512 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
10513 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
10514 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
10515 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
10516 if (TARGET_PPC_GPOPT || TARGET_POWER2)
10517 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
10519 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
10520 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
10521 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
10522 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
10523 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
10524 set_optab_libfunc (le_optab, TFmode, "_q_fle");
10526 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
10527 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
10528 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
10529 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
10530 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
10531 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
10532 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
10533 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
10538 /* Expand a block clear operation, and return 1 if successful. Return 0
10539 if we should let the compiler generate normal code.
10541 operands[0] is the destination
10542 operands[1] is the length
10543 operands[3] is the alignment */
10546 expand_block_clear (rtx operands[])
10548 rtx orig_dest = operands[0];
10549 rtx bytes_rtx = operands[1];
10550 rtx align_rtx = operands[3];
10551 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
10552 HOST_WIDE_INT align;
10553 HOST_WIDE_INT bytes;
10554 int offset;
10555 int clear_bytes;
10556 int clear_step;
10558 /* If this is not a fixed size move, just call memcpy */
10559 if (! constp)
10560 return 0;
10562 /* This must be a fixed size alignment */
10563 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
10564 align = INTVAL (align_rtx) * BITS_PER_UNIT;
10566 /* Anything to clear? */
10567 bytes = INTVAL (bytes_rtx);
10568 if (bytes <= 0)
10569 return 1;
10571 /* Use the builtin memset after a point, to avoid huge code bloat.
10572 When optimize_size, avoid any significant code bloat; calling
10573 memset is about 4 instructions, so allow for one instruction to
10574 load zero and three to do clearing. */
10575 if (TARGET_ALTIVEC && align >= 128)
10576 clear_step = 16;
10577 else if (TARGET_POWERPC64 && align >= 32)
10578 clear_step = 8;
10579 else if (TARGET_SPE && align >= 64)
10580 clear_step = 8;
10581 else
10582 clear_step = 4;
10584 if (optimize_size && bytes > 3 * clear_step)
10585 return 0;
10586 if (! optimize_size && bytes > 8 * clear_step)
10587 return 0;
10589 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
10591 enum machine_mode mode = BLKmode;
10592 rtx dest;
10594 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
10596 clear_bytes = 16;
10597 mode = V4SImode;
10599 else if (bytes >= 8 && TARGET_SPE && align >= 64)
10601 clear_bytes = 8;
10602 mode = V2SImode;
10604 else if (bytes >= 8 && TARGET_POWERPC64
10605 /* 64-bit loads and stores require word-aligned
10606 displacements. */
10607 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
10609 clear_bytes = 8;
10610 mode = DImode;
10612 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
10613 { /* move 4 bytes */
10614 clear_bytes = 4;
10615 mode = SImode;
10617 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
10618 { /* move 2 bytes */
10619 clear_bytes = 2;
10620 mode = HImode;
10622 else /* move 1 byte at a time */
10624 clear_bytes = 1;
10625 mode = QImode;
10628 dest = adjust_address (orig_dest, mode, offset);
10630 emit_move_insn (dest, CONST0_RTX (mode));
10633 return 1;
10637 /* Expand a block move operation, and return 1 if successful. Return 0
10638 if we should let the compiler generate normal code.
10640 operands[0] is the destination
10641 operands[1] is the source
10642 operands[2] is the length
10643 operands[3] is the alignment */
10645 #define MAX_MOVE_REG 4
10648 expand_block_move (rtx operands[])
10650 rtx orig_dest = operands[0];
10651 rtx orig_src = operands[1];
10652 rtx bytes_rtx = operands[2];
10653 rtx align_rtx = operands[3];
10654 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
10655 int align;
10656 int bytes;
10657 int offset;
10658 int move_bytes;
10659 rtx stores[MAX_MOVE_REG];
10660 int num_reg = 0;
10662 /* If this is not a fixed size move, just call memcpy */
10663 if (! constp)
10664 return 0;
10666 /* This must be a fixed size alignment */
10667 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
10668 align = INTVAL (align_rtx) * BITS_PER_UNIT;
10670 /* Anything to move? */
10671 bytes = INTVAL (bytes_rtx);
10672 if (bytes <= 0)
10673 return 1;
10675 /* store_one_arg depends on expand_block_move to handle at least the size of
10676 reg_parm_stack_space. */
10677 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
10678 return 0;
10680 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
10682 union {
10683 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
10684 rtx (*mov) (rtx, rtx);
10685 } gen_func;
10686 enum machine_mode mode = BLKmode;
10687 rtx src, dest;
10689 /* Altivec first, since it will be faster than a string move
10690 when it applies, and usually not significantly larger. */
10691 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
10693 move_bytes = 16;
10694 mode = V4SImode;
10695 gen_func.mov = gen_movv4si;
10697 else if (TARGET_SPE && bytes >= 8 && align >= 64)
10699 move_bytes = 8;
10700 mode = V2SImode;
10701 gen_func.mov = gen_movv2si;
10703 else if (TARGET_STRING
10704 && bytes > 24 /* move up to 32 bytes at a time */
10705 && ! fixed_regs[5]
10706 && ! fixed_regs[6]
10707 && ! fixed_regs[7]
10708 && ! fixed_regs[8]
10709 && ! fixed_regs[9]
10710 && ! fixed_regs[10]
10711 && ! fixed_regs[11]
10712 && ! fixed_regs[12])
10714 move_bytes = (bytes > 32) ? 32 : bytes;
10715 gen_func.movmemsi = gen_movmemsi_8reg;
10717 else if (TARGET_STRING
10718 && bytes > 16 /* move up to 24 bytes at a time */
10719 && ! fixed_regs[5]
10720 && ! fixed_regs[6]
10721 && ! fixed_regs[7]
10722 && ! fixed_regs[8]
10723 && ! fixed_regs[9]
10724 && ! fixed_regs[10])
10726 move_bytes = (bytes > 24) ? 24 : bytes;
10727 gen_func.movmemsi = gen_movmemsi_6reg;
10729 else if (TARGET_STRING
10730 && bytes > 8 /* move up to 16 bytes at a time */
10731 && ! fixed_regs[5]
10732 && ! fixed_regs[6]
10733 && ! fixed_regs[7]
10734 && ! fixed_regs[8])
10736 move_bytes = (bytes > 16) ? 16 : bytes;
10737 gen_func.movmemsi = gen_movmemsi_4reg;
10739 else if (bytes >= 8 && TARGET_POWERPC64
10740 /* 64-bit loads and stores require word-aligned
10741 displacements. */
10742 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
10744 move_bytes = 8;
10745 mode = DImode;
10746 gen_func.mov = gen_movdi;
10748 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
10749 { /* move up to 8 bytes at a time */
10750 move_bytes = (bytes > 8) ? 8 : bytes;
10751 gen_func.movmemsi = gen_movmemsi_2reg;
10753 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
10754 { /* move 4 bytes */
10755 move_bytes = 4;
10756 mode = SImode;
10757 gen_func.mov = gen_movsi;
10759 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
10760 { /* move 2 bytes */
10761 move_bytes = 2;
10762 mode = HImode;
10763 gen_func.mov = gen_movhi;
10765 else if (TARGET_STRING && bytes > 1)
10766 { /* move up to 4 bytes at a time */
10767 move_bytes = (bytes > 4) ? 4 : bytes;
10768 gen_func.movmemsi = gen_movmemsi_1reg;
10770 else /* move 1 byte at a time */
10772 move_bytes = 1;
10773 mode = QImode;
10774 gen_func.mov = gen_movqi;
10777 src = adjust_address (orig_src, mode, offset);
10778 dest = adjust_address (orig_dest, mode, offset);
10780 if (mode != BLKmode)
10782 rtx tmp_reg = gen_reg_rtx (mode);
10784 emit_insn ((*gen_func.mov) (tmp_reg, src));
10785 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
10788 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
10790 int i;
10791 for (i = 0; i < num_reg; i++)
10792 emit_insn (stores[i]);
10793 num_reg = 0;
10796 if (mode == BLKmode)
10798 /* Move the address into scratch registers. The movmemsi
10799 patterns require zero offset. */
10800 if (!REG_P (XEXP (src, 0)))
10802 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
10803 src = replace_equiv_address (src, src_reg);
10805 set_mem_size (src, GEN_INT (move_bytes));
10807 if (!REG_P (XEXP (dest, 0)))
10809 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
10810 dest = replace_equiv_address (dest, dest_reg);
10812 set_mem_size (dest, GEN_INT (move_bytes));
10814 emit_insn ((*gen_func.movmemsi) (dest, src,
10815 GEN_INT (move_bytes & 31),
10816 align_rtx));
10820 return 1;
10824 /* Return a string to perform a load_multiple operation.
10825 operands[0] is the vector.
10826 operands[1] is the source address.
10827 operands[2] is the first destination register. */
10829 const char *
10830 rs6000_output_load_multiple (rtx operands[3])
10832 /* We have to handle the case where the pseudo used to contain the address
10833 is assigned to one of the output registers. */
10834 int i, j;
10835 int words = XVECLEN (operands[0], 0);
10836 rtx xop[10];
10838 if (XVECLEN (operands[0], 0) == 1)
10839 return "{l|lwz} %2,0(%1)";
10841 for (i = 0; i < words; i++)
10842 if (refers_to_regno_p (REGNO (operands[2]) + i,
10843 REGNO (operands[2]) + i + 1, operands[1], 0))
10845 if (i == words-1)
10847 xop[0] = GEN_INT (4 * (words-1));
10848 xop[1] = operands[1];
10849 xop[2] = operands[2];
10850 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
10851 return "";
10853 else if (i == 0)
10855 xop[0] = GEN_INT (4 * (words-1));
10856 xop[1] = operands[1];
10857 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
10858 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);
10859 return "";
10861 else
10863 for (j = 0; j < words; j++)
10864 if (j != i)
10866 xop[0] = GEN_INT (j * 4);
10867 xop[1] = operands[1];
10868 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
10869 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
10871 xop[0] = GEN_INT (i * 4);
10872 xop[1] = operands[1];
10873 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
10874 return "";
10878 return "{lsi|lswi} %2,%1,%N0";
10882 /* A validation routine: say whether CODE, a condition code, and MODE
10883 match. The other alternatives either don't make sense or should
10884 never be generated. */
10886 void
10887 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
10889 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
10890 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
10891 && GET_MODE_CLASS (mode) == MODE_CC);
10893 /* These don't make sense. */
10894 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
10895 || mode != CCUNSmode);
10897 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
10898 || mode == CCUNSmode);
10900 gcc_assert (mode == CCFPmode
10901 || (code != ORDERED && code != UNORDERED
10902 && code != UNEQ && code != LTGT
10903 && code != UNGT && code != UNLT
10904 && code != UNGE && code != UNLE));
10906 /* These should never be generated except for
10907 flag_finite_math_only. */
10908 gcc_assert (mode != CCFPmode
10909 || flag_finite_math_only
10910 || (code != LE && code != GE
10911 && code != UNEQ && code != LTGT
10912 && code != UNGT && code != UNLT));
10914 /* These are invalid; the information is not there. */
10915 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
10919 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
10920 mask required to convert the result of a rotate insn into a shift
10921 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
10924 includes_lshift_p (rtx shiftop, rtx andop)
10926 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
10928 shift_mask <<= INTVAL (shiftop);
10930 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
10933 /* Similar, but for right shift. */
10936 includes_rshift_p (rtx shiftop, rtx andop)
10938 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
10940 shift_mask >>= INTVAL (shiftop);
10942 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
10945 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
10946 to perform a left shift. It must have exactly SHIFTOP least
10947 significant 0's, then one or more 1's, then zero or more 0's. */
10950 includes_rldic_lshift_p (rtx shiftop, rtx andop)
10952 if (GET_CODE (andop) == CONST_INT)
10954 HOST_WIDE_INT c, lsb, shift_mask;
10956 c = INTVAL (andop);
10957 if (c == 0 || c == ~0)
10958 return 0;
10960 shift_mask = ~0;
10961 shift_mask <<= INTVAL (shiftop);
10963 /* Find the least significant one bit. */
10964 lsb = c & -c;
10966 /* It must coincide with the LSB of the shift mask. */
10967 if (-lsb != shift_mask)
10968 return 0;
10970 /* Invert to look for the next transition (if any). */
10971 c = ~c;
10973 /* Remove the low group of ones (originally low group of zeros). */
10974 c &= -lsb;
10976 /* Again find the lsb, and check we have all 1's above. */
10977 lsb = c & -c;
10978 return c == -lsb;
10980 else if (GET_CODE (andop) == CONST_DOUBLE
10981 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
10983 HOST_WIDE_INT low, high, lsb;
10984 HOST_WIDE_INT shift_mask_low, shift_mask_high;
10986 low = CONST_DOUBLE_LOW (andop);
10987 if (HOST_BITS_PER_WIDE_INT < 64)
10988 high = CONST_DOUBLE_HIGH (andop);
10990 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
10991 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
10992 return 0;
10994 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
10996 shift_mask_high = ~0;
10997 if (INTVAL (shiftop) > 32)
10998 shift_mask_high <<= INTVAL (shiftop) - 32;
11000 lsb = high & -high;
11002 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
11003 return 0;
11005 high = ~high;
11006 high &= -lsb;
11008 lsb = high & -high;
11009 return high == -lsb;
11012 shift_mask_low = ~0;
11013 shift_mask_low <<= INTVAL (shiftop);
11015 lsb = low & -low;
11017 if (-lsb != shift_mask_low)
11018 return 0;
11020 if (HOST_BITS_PER_WIDE_INT < 64)
11021 high = ~high;
11022 low = ~low;
11023 low &= -lsb;
11025 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
11027 lsb = high & -high;
11028 return high == -lsb;
11031 lsb = low & -low;
11032 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
11034 else
11035 return 0;
11038 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
11039 to perform a left shift. It must have SHIFTOP or more least
11040 significant 0's, with the remainder of the word 1's. */
11043 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
11045 if (GET_CODE (andop) == CONST_INT)
11047 HOST_WIDE_INT c, lsb, shift_mask;
11049 shift_mask = ~0;
11050 shift_mask <<= INTVAL (shiftop);
11051 c = INTVAL (andop);
11053 /* Find the least significant one bit. */
11054 lsb = c & -c;
11056 /* It must be covered by the shift mask.
11057 This test also rejects c == 0. */
11058 if ((lsb & shift_mask) == 0)
11059 return 0;
11061 /* Check we have all 1's above the transition, and reject all 1's. */
11062 return c == -lsb && lsb != 1;
11064 else if (GET_CODE (andop) == CONST_DOUBLE
11065 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
11067 HOST_WIDE_INT low, lsb, shift_mask_low;
11069 low = CONST_DOUBLE_LOW (andop);
11071 if (HOST_BITS_PER_WIDE_INT < 64)
11073 HOST_WIDE_INT high, shift_mask_high;
11075 high = CONST_DOUBLE_HIGH (andop);
11077 if (low == 0)
11079 shift_mask_high = ~0;
11080 if (INTVAL (shiftop) > 32)
11081 shift_mask_high <<= INTVAL (shiftop) - 32;
11083 lsb = high & -high;
11085 if ((lsb & shift_mask_high) == 0)
11086 return 0;
11088 return high == -lsb;
11090 if (high != ~0)
11091 return 0;
11094 shift_mask_low = ~0;
11095 shift_mask_low <<= INTVAL (shiftop);
11097 lsb = low & -low;
11099 if ((lsb & shift_mask_low) == 0)
11100 return 0;
11102 return low == -lsb && lsb != 1;
11104 else
11105 return 0;
11108 /* Return 1 if operands will generate a valid arguments to rlwimi
11109 instruction for insert with right shift in 64-bit mode. The mask may
11110 not start on the first bit or stop on the last bit because wrap-around
11111 effects of instruction do not correspond to semantics of RTL insn. */
11114 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
11116 if (INTVAL (startop) > 32
11117 && INTVAL (startop) < 64
11118 && INTVAL (sizeop) > 1
11119 && INTVAL (sizeop) + INTVAL (startop) < 64
11120 && INTVAL (shiftop) > 0
11121 && INTVAL (sizeop) + INTVAL (shiftop) < 32
11122 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
11123 return 1;
11125 return 0;
11128 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
11129 for lfq and stfq insns iff the registers are hard registers. */
11132 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
11134 /* We might have been passed a SUBREG. */
11135 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
11136 return 0;
11138 /* We might have been passed non floating point registers. */
11139 if (!FP_REGNO_P (REGNO (reg1))
11140 || !FP_REGNO_P (REGNO (reg2)))
11141 return 0;
11143 return (REGNO (reg1) == REGNO (reg2) - 1);
11146 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
11147 addr1 and addr2 must be in consecutive memory locations
11148 (addr2 == addr1 + 8). */
11151 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
11153 rtx addr1, addr2;
11154 unsigned int reg1, reg2;
11155 int offset1, offset2;
11157 /* The mems cannot be volatile. */
11158 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
11159 return 0;
11161 addr1 = XEXP (mem1, 0);
11162 addr2 = XEXP (mem2, 0);
11164 /* Extract an offset (if used) from the first addr. */
11165 if (GET_CODE (addr1) == PLUS)
11167 /* If not a REG, return zero. */
11168 if (GET_CODE (XEXP (addr1, 0)) != REG)
11169 return 0;
11170 else
11172 reg1 = REGNO (XEXP (addr1, 0));
11173 /* The offset must be constant! */
11174 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
11175 return 0;
11176 offset1 = INTVAL (XEXP (addr1, 1));
11179 else if (GET_CODE (addr1) != REG)
11180 return 0;
11181 else
11183 reg1 = REGNO (addr1);
11184 /* This was a simple (mem (reg)) expression. Offset is 0. */
11185 offset1 = 0;
11188 /* And now for the second addr. */
11189 if (GET_CODE (addr2) == PLUS)
11191 /* If not a REG, return zero. */
11192 if (GET_CODE (XEXP (addr2, 0)) != REG)
11193 return 0;
11194 else
11196 reg2 = REGNO (XEXP (addr2, 0));
11197 /* The offset must be constant. */
11198 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
11199 return 0;
11200 offset2 = INTVAL (XEXP (addr2, 1));
11203 else if (GET_CODE (addr2) != REG)
11204 return 0;
11205 else
11207 reg2 = REGNO (addr2);
11208 /* This was a simple (mem (reg)) expression. Offset is 0. */
11209 offset2 = 0;
11212 /* Both of these must have the same base register. */
11213 if (reg1 != reg2)
11214 return 0;
11216 /* The offset for the second addr must be 8 more than the first addr. */
11217 if (offset2 != offset1 + 8)
11218 return 0;
11220 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
11221 instructions. */
11222 return 1;
11227 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
11229 static bool eliminated = false;
11230 if (mode != SDmode)
11231 return assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
11232 else
11234 rtx mem = cfun->machine->sdmode_stack_slot;
11235 gcc_assert (mem != NULL_RTX);
11237 if (!eliminated)
11239 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
11240 cfun->machine->sdmode_stack_slot = mem;
11241 eliminated = true;
11243 return mem;
11247 static tree
11248 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
11250 /* Don't walk into types. */
11251 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
11253 *walk_subtrees = 0;
11254 return NULL_TREE;
11257 switch (TREE_CODE (*tp))
11259 case VAR_DECL:
11260 case PARM_DECL:
11261 case FIELD_DECL:
11262 case RESULT_DECL:
11263 case REAL_CST:
11264 case INDIRECT_REF:
11265 case ALIGN_INDIRECT_REF:
11266 case MISALIGNED_INDIRECT_REF:
11267 case VIEW_CONVERT_EXPR:
11268 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
11269 return *tp;
11270 break;
11271 default:
11272 break;
11275 return NULL_TREE;
11279 /* Allocate a 64-bit stack slot to be used for copying SDmode
11280 values through if this function has any SDmode references. */
11282 static void
11283 rs6000_alloc_sdmode_stack_slot (void)
11285 tree t;
11286 basic_block bb;
11287 block_stmt_iterator bsi;
11289 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
11291 FOR_EACH_BB (bb)
11292 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
11294 tree ret = walk_tree_without_duplicates (bsi_stmt_ptr (bsi),
11295 rs6000_check_sdmode, NULL);
11296 if (ret)
11298 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
11299 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
11300 SDmode, 0);
11301 return;
11305 /* Check for any SDmode parameters of the function. */
11306 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
11308 if (TREE_TYPE (t) == error_mark_node)
11309 continue;
11311 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
11312 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
11314 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
11315 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
11316 SDmode, 0);
11317 return;
11322 static void
11323 rs6000_instantiate_decls (void)
11325 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
11326 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
11329 /* Return the register class of a scratch register needed to copy IN into
11330 or out of a register in CLASS in MODE. If it can be done directly,
11331 NO_REGS is returned. */
11333 enum reg_class
11334 rs6000_secondary_reload_class (enum reg_class class,
11335 enum machine_mode mode ATTRIBUTE_UNUSED,
11336 rtx in)
11338 int regno;
11340 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
11341 #if TARGET_MACHO
11342 && MACHOPIC_INDIRECT
11343 #endif
11346 /* We cannot copy a symbolic operand directly into anything
11347 other than BASE_REGS for TARGET_ELF. So indicate that a
11348 register from BASE_REGS is needed as an intermediate
11349 register.
11351 On Darwin, pic addresses require a load from memory, which
11352 needs a base register. */
11353 if (class != BASE_REGS
11354 && (GET_CODE (in) == SYMBOL_REF
11355 || GET_CODE (in) == HIGH
11356 || GET_CODE (in) == LABEL_REF
11357 || GET_CODE (in) == CONST))
11358 return BASE_REGS;
11361 if (GET_CODE (in) == REG)
11363 regno = REGNO (in);
11364 if (regno >= FIRST_PSEUDO_REGISTER)
11366 regno = true_regnum (in);
11367 if (regno >= FIRST_PSEUDO_REGISTER)
11368 regno = -1;
11371 else if (GET_CODE (in) == SUBREG)
11373 regno = true_regnum (in);
11374 if (regno >= FIRST_PSEUDO_REGISTER)
11375 regno = -1;
11377 else
11378 regno = -1;
11380 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
11381 into anything. */
11382 if (class == GENERAL_REGS || class == BASE_REGS
11383 || (regno >= 0 && INT_REGNO_P (regno)))
11384 return NO_REGS;
11386 /* Constants, memory, and FP registers can go into FP registers. */
11387 if ((regno == -1 || FP_REGNO_P (regno))
11388 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
11389 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
11391 /* Memory, and AltiVec registers can go into AltiVec registers. */
11392 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
11393 && class == ALTIVEC_REGS)
11394 return NO_REGS;
11396 /* We can copy among the CR registers. */
11397 if ((class == CR_REGS || class == CR0_REGS)
11398 && regno >= 0 && CR_REGNO_P (regno))
11399 return NO_REGS;
11401 /* Otherwise, we need GENERAL_REGS. */
11402 return GENERAL_REGS;
11405 /* Given a comparison operation, return the bit number in CCR to test. We
11406 know this is a valid comparison.
11408 SCC_P is 1 if this is for an scc. That means that %D will have been
11409 used instead of %C, so the bits will be in different places.
11411 Return -1 if OP isn't a valid comparison for some reason. */
11414 ccr_bit (rtx op, int scc_p)
11416 enum rtx_code code = GET_CODE (op);
11417 enum machine_mode cc_mode;
11418 int cc_regnum;
11419 int base_bit;
11420 rtx reg;
11422 if (!COMPARISON_P (op))
11423 return -1;
11425 reg = XEXP (op, 0);
11427 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
11429 cc_mode = GET_MODE (reg);
11430 cc_regnum = REGNO (reg);
11431 base_bit = 4 * (cc_regnum - CR0_REGNO);
11433 validate_condition_mode (code, cc_mode);
11435 /* When generating a sCOND operation, only positive conditions are
11436 allowed. */
11437 gcc_assert (!scc_p
11438 || code == EQ || code == GT || code == LT || code == UNORDERED
11439 || code == GTU || code == LTU);
11441 switch (code)
11443 case NE:
11444 return scc_p ? base_bit + 3 : base_bit + 2;
11445 case EQ:
11446 return base_bit + 2;
11447 case GT: case GTU: case UNLE:
11448 return base_bit + 1;
11449 case LT: case LTU: case UNGE:
11450 return base_bit;
11451 case ORDERED: case UNORDERED:
11452 return base_bit + 3;
11454 case GE: case GEU:
11455 /* If scc, we will have done a cror to put the bit in the
11456 unordered position. So test that bit. For integer, this is ! LT
11457 unless this is an scc insn. */
11458 return scc_p ? base_bit + 3 : base_bit;
11460 case LE: case LEU:
11461 return scc_p ? base_bit + 3 : base_bit + 1;
11463 default:
11464 gcc_unreachable ();
11468 /* Return the GOT register. */
11471 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
11473 /* The second flow pass currently (June 1999) can't update
11474 regs_ever_live without disturbing other parts of the compiler, so
11475 update it here to make the prolog/epilogue code happy. */
11476 if (!can_create_pseudo_p ()
11477 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
11478 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
11480 crtl->uses_pic_offset_table = 1;
11482 return pic_offset_table_rtx;
11485 /* Function to init struct machine_function.
11486 This will be called, via a pointer variable,
11487 from push_function_context. */
11489 static struct machine_function *
11490 rs6000_init_machine_status (void)
11492 return ggc_alloc_cleared (sizeof (machine_function));
11495 /* These macros test for integers and extract the low-order bits. */
11496 #define INT_P(X) \
11497 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
11498 && GET_MODE (X) == VOIDmode)
11500 #define INT_LOWPART(X) \
11501 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
11504 extract_MB (rtx op)
11506 int i;
11507 unsigned long val = INT_LOWPART (op);
11509 /* If the high bit is zero, the value is the first 1 bit we find
11510 from the left. */
11511 if ((val & 0x80000000) == 0)
11513 gcc_assert (val & 0xffffffff);
11515 i = 1;
11516 while (((val <<= 1) & 0x80000000) == 0)
11517 ++i;
11518 return i;
11521 /* If the high bit is set and the low bit is not, or the mask is all
11522 1's, the value is zero. */
11523 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
11524 return 0;
11526 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11527 from the right. */
11528 i = 31;
11529 while (((val >>= 1) & 1) != 0)
11530 --i;
11532 return i;
11536 extract_ME (rtx op)
11538 int i;
11539 unsigned long val = INT_LOWPART (op);
11541 /* If the low bit is zero, the value is the first 1 bit we find from
11542 the right. */
11543 if ((val & 1) == 0)
11545 gcc_assert (val & 0xffffffff);
11547 i = 30;
11548 while (((val >>= 1) & 1) == 0)
11549 --i;
11551 return i;
11554 /* If the low bit is set and the high bit is not, or the mask is all
11555 1's, the value is 31. */
11556 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
11557 return 31;
11559 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11560 from the left. */
11561 i = 0;
11562 while (((val <<= 1) & 0x80000000) != 0)
11563 ++i;
11565 return i;
11568 /* Locate some local-dynamic symbol still in use by this function
11569 so that we can print its name in some tls_ld pattern. */
11571 static const char *
11572 rs6000_get_some_local_dynamic_name (void)
11574 rtx insn;
11576 if (cfun->machine->some_ld_name)
11577 return cfun->machine->some_ld_name;
11579 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
11580 if (INSN_P (insn)
11581 && for_each_rtx (&PATTERN (insn),
11582 rs6000_get_some_local_dynamic_name_1, 0))
11583 return cfun->machine->some_ld_name;
11585 gcc_unreachable ();
11588 /* Helper function for rs6000_get_some_local_dynamic_name. */
11590 static int
11591 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
11593 rtx x = *px;
11595 if (GET_CODE (x) == SYMBOL_REF)
11597 const char *str = XSTR (x, 0);
11598 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
11600 cfun->machine->some_ld_name = str;
11601 return 1;
11605 return 0;
11608 /* Write out a function code label. */
11610 void
11611 rs6000_output_function_entry (FILE *file, const char *fname)
11613 if (fname[0] != '.')
11615 switch (DEFAULT_ABI)
11617 default:
11618 gcc_unreachable ();
11620 case ABI_AIX:
11621 if (DOT_SYMBOLS)
11622 putc ('.', file);
11623 else
11624 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
11625 break;
11627 case ABI_V4:
11628 case ABI_DARWIN:
11629 break;
11632 if (TARGET_AIX)
11633 RS6000_OUTPUT_BASENAME (file, fname);
11634 else
11635 assemble_name (file, fname);
11638 /* Print an operand. Recognize special options, documented below. */
11640 #if TARGET_ELF
11641 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
11642 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
11643 #else
11644 #define SMALL_DATA_RELOC "sda21"
11645 #define SMALL_DATA_REG 0
11646 #endif
11648 void
11649 print_operand (FILE *file, rtx x, int code)
11651 int i;
11652 HOST_WIDE_INT val;
11653 unsigned HOST_WIDE_INT uval;
11655 switch (code)
11657 case '.':
11658 /* Write out an instruction after the call which may be replaced
11659 with glue code by the loader. This depends on the AIX version. */
11660 asm_fprintf (file, RS6000_CALL_GLUE);
11661 return;
11663 /* %a is output_address. */
11665 case 'A':
11666 /* If X is a constant integer whose low-order 5 bits are zero,
11667 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
11668 in the AIX assembler where "sri" with a zero shift count
11669 writes a trash instruction. */
11670 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
11671 putc ('l', file);
11672 else
11673 putc ('r', file);
11674 return;
11676 case 'b':
11677 /* If constant, low-order 16 bits of constant, unsigned.
11678 Otherwise, write normally. */
11679 if (INT_P (x))
11680 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
11681 else
11682 print_operand (file, x, 0);
11683 return;
11685 case 'B':
11686 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
11687 for 64-bit mask direction. */
11688 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
11689 return;
11691 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
11692 output_operand. */
11694 case 'c':
11695 /* X is a CR register. Print the number of the GT bit of the CR. */
11696 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11697 output_operand_lossage ("invalid %%E value");
11698 else
11699 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
11700 return;
11702 case 'D':
11703 /* Like 'J' but get to the GT bit only. */
11704 gcc_assert (GET_CODE (x) == REG);
11706 /* Bit 1 is GT bit. */
11707 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
11709 /* Add one for shift count in rlinm for scc. */
11710 fprintf (file, "%d", i + 1);
11711 return;
11713 case 'E':
11714 /* X is a CR register. Print the number of the EQ bit of the CR */
11715 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11716 output_operand_lossage ("invalid %%E value");
11717 else
11718 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
11719 return;
11721 case 'f':
11722 /* X is a CR register. Print the shift count needed to move it
11723 to the high-order four bits. */
11724 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11725 output_operand_lossage ("invalid %%f value");
11726 else
11727 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
11728 return;
11730 case 'F':
11731 /* Similar, but print the count for the rotate in the opposite
11732 direction. */
11733 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11734 output_operand_lossage ("invalid %%F value");
11735 else
11736 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
11737 return;
11739 case 'G':
11740 /* X is a constant integer. If it is negative, print "m",
11741 otherwise print "z". This is to make an aze or ame insn. */
11742 if (GET_CODE (x) != CONST_INT)
11743 output_operand_lossage ("invalid %%G value");
11744 else if (INTVAL (x) >= 0)
11745 putc ('z', file);
11746 else
11747 putc ('m', file);
11748 return;
11750 case 'h':
11751 /* If constant, output low-order five bits. Otherwise, write
11752 normally. */
11753 if (INT_P (x))
11754 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
11755 else
11756 print_operand (file, x, 0);
11757 return;
11759 case 'H':
11760 /* If constant, output low-order six bits. Otherwise, write
11761 normally. */
11762 if (INT_P (x))
11763 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
11764 else
11765 print_operand (file, x, 0);
11766 return;
11768 case 'I':
11769 /* Print `i' if this is a constant, else nothing. */
11770 if (INT_P (x))
11771 putc ('i', file);
11772 return;
11774 case 'j':
11775 /* Write the bit number in CCR for jump. */
11776 i = ccr_bit (x, 0);
11777 if (i == -1)
11778 output_operand_lossage ("invalid %%j code");
11779 else
11780 fprintf (file, "%d", i);
11781 return;
11783 case 'J':
11784 /* Similar, but add one for shift count in rlinm for scc and pass
11785 scc flag to `ccr_bit'. */
11786 i = ccr_bit (x, 1);
11787 if (i == -1)
11788 output_operand_lossage ("invalid %%J code");
11789 else
11790 /* If we want bit 31, write a shift count of zero, not 32. */
11791 fprintf (file, "%d", i == 31 ? 0 : i + 1);
11792 return;
11794 case 'k':
11795 /* X must be a constant. Write the 1's complement of the
11796 constant. */
11797 if (! INT_P (x))
11798 output_operand_lossage ("invalid %%k value");
11799 else
11800 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
11801 return;
11803 case 'K':
11804 /* X must be a symbolic constant on ELF. Write an
11805 expression suitable for an 'addi' that adds in the low 16
11806 bits of the MEM. */
11807 if (GET_CODE (x) != CONST)
11809 print_operand_address (file, x);
11810 fputs ("@l", file);
11812 else
11814 if (GET_CODE (XEXP (x, 0)) != PLUS
11815 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
11816 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
11817 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
11818 output_operand_lossage ("invalid %%K value");
11819 print_operand_address (file, XEXP (XEXP (x, 0), 0));
11820 fputs ("@l", file);
11821 /* For GNU as, there must be a non-alphanumeric character
11822 between 'l' and the number. The '-' is added by
11823 print_operand() already. */
11824 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
11825 fputs ("+", file);
11826 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
11828 return;
11830 /* %l is output_asm_label. */
11832 case 'L':
11833 /* Write second word of DImode or DFmode reference. Works on register
11834 or non-indexed memory only. */
11835 if (GET_CODE (x) == REG)
11836 fputs (reg_names[REGNO (x) + 1], file);
11837 else if (GET_CODE (x) == MEM)
11839 /* Handle possible auto-increment. Since it is pre-increment and
11840 we have already done it, we can just use an offset of word. */
11841 if (GET_CODE (XEXP (x, 0)) == PRE_INC
11842 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
11843 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
11844 UNITS_PER_WORD));
11845 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
11846 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
11847 UNITS_PER_WORD));
11848 else
11849 output_address (XEXP (adjust_address_nv (x, SImode,
11850 UNITS_PER_WORD),
11851 0));
11853 if (small_data_operand (x, GET_MODE (x)))
11854 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11855 reg_names[SMALL_DATA_REG]);
11857 return;
11859 case 'm':
11860 /* MB value for a mask operand. */
11861 if (! mask_operand (x, SImode))
11862 output_operand_lossage ("invalid %%m value");
11864 fprintf (file, "%d", extract_MB (x));
11865 return;
11867 case 'M':
11868 /* ME value for a mask operand. */
11869 if (! mask_operand (x, SImode))
11870 output_operand_lossage ("invalid %%M value");
11872 fprintf (file, "%d", extract_ME (x));
11873 return;
11875 /* %n outputs the negative of its operand. */
11877 case 'N':
11878 /* Write the number of elements in the vector times 4. */
11879 if (GET_CODE (x) != PARALLEL)
11880 output_operand_lossage ("invalid %%N value");
11881 else
11882 fprintf (file, "%d", XVECLEN (x, 0) * 4);
11883 return;
11885 case 'O':
11886 /* Similar, but subtract 1 first. */
11887 if (GET_CODE (x) != PARALLEL)
11888 output_operand_lossage ("invalid %%O value");
11889 else
11890 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
11891 return;
11893 case 'p':
11894 /* X is a CONST_INT that is a power of two. Output the logarithm. */
11895 if (! INT_P (x)
11896 || INT_LOWPART (x) < 0
11897 || (i = exact_log2 (INT_LOWPART (x))) < 0)
11898 output_operand_lossage ("invalid %%p value");
11899 else
11900 fprintf (file, "%d", i);
11901 return;
11903 case 'P':
11904 /* The operand must be an indirect memory reference. The result
11905 is the register name. */
11906 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
11907 || REGNO (XEXP (x, 0)) >= 32)
11908 output_operand_lossage ("invalid %%P value");
11909 else
11910 fputs (reg_names[REGNO (XEXP (x, 0))], file);
11911 return;
11913 case 'q':
11914 /* This outputs the logical code corresponding to a boolean
11915 expression. The expression may have one or both operands
11916 negated (if one, only the first one). For condition register
11917 logical operations, it will also treat the negated
11918 CR codes as NOTs, but not handle NOTs of them. */
11920 const char *const *t = 0;
11921 const char *s;
11922 enum rtx_code code = GET_CODE (x);
11923 static const char * const tbl[3][3] = {
11924 { "and", "andc", "nor" },
11925 { "or", "orc", "nand" },
11926 { "xor", "eqv", "xor" } };
11928 if (code == AND)
11929 t = tbl[0];
11930 else if (code == IOR)
11931 t = tbl[1];
11932 else if (code == XOR)
11933 t = tbl[2];
11934 else
11935 output_operand_lossage ("invalid %%q value");
11937 if (GET_CODE (XEXP (x, 0)) != NOT)
11938 s = t[0];
11939 else
11941 if (GET_CODE (XEXP (x, 1)) == NOT)
11942 s = t[2];
11943 else
11944 s = t[1];
11947 fputs (s, file);
11949 return;
11951 case 'Q':
11952 if (TARGET_MFCRF)
11953 fputc (',', file);
11954 /* FALLTHRU */
11955 else
11956 return;
11958 case 'R':
11959 /* X is a CR register. Print the mask for `mtcrf'. */
11960 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11961 output_operand_lossage ("invalid %%R value");
11962 else
11963 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
11964 return;
11966 case 's':
11967 /* Low 5 bits of 32 - value */
11968 if (! INT_P (x))
11969 output_operand_lossage ("invalid %%s value");
11970 else
11971 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
11972 return;
11974 case 'S':
11975 /* PowerPC64 mask position. All 0's is excluded.
11976 CONST_INT 32-bit mask is considered sign-extended so any
11977 transition must occur within the CONST_INT, not on the boundary. */
11978 if (! mask64_operand (x, DImode))
11979 output_operand_lossage ("invalid %%S value");
11981 uval = INT_LOWPART (x);
11983 if (uval & 1) /* Clear Left */
11985 #if HOST_BITS_PER_WIDE_INT > 64
11986 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
11987 #endif
11988 i = 64;
11990 else /* Clear Right */
11992 uval = ~uval;
11993 #if HOST_BITS_PER_WIDE_INT > 64
11994 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
11995 #endif
11996 i = 63;
11998 while (uval != 0)
11999 --i, uval >>= 1;
12000 gcc_assert (i >= 0);
12001 fprintf (file, "%d", i);
12002 return;
12004 case 't':
12005 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
12006 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
12008 /* Bit 3 is OV bit. */
12009 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
12011 /* If we want bit 31, write a shift count of zero, not 32. */
12012 fprintf (file, "%d", i == 31 ? 0 : i + 1);
12013 return;
12015 case 'T':
12016 /* Print the symbolic name of a branch target register. */
12017 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
12018 && REGNO (x) != CTR_REGNO))
12019 output_operand_lossage ("invalid %%T value");
12020 else if (REGNO (x) == LR_REGNO)
12021 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
12022 else
12023 fputs ("ctr", file);
12024 return;
12026 case 'u':
12027 /* High-order 16 bits of constant for use in unsigned operand. */
12028 if (! INT_P (x))
12029 output_operand_lossage ("invalid %%u value");
12030 else
12031 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
12032 (INT_LOWPART (x) >> 16) & 0xffff);
12033 return;
12035 case 'v':
12036 /* High-order 16 bits of constant for use in signed operand. */
12037 if (! INT_P (x))
12038 output_operand_lossage ("invalid %%v value");
12039 else
12040 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
12041 (INT_LOWPART (x) >> 16) & 0xffff);
12042 return;
12044 case 'U':
12045 /* Print `u' if this has an auto-increment or auto-decrement. */
12046 if (GET_CODE (x) == MEM
12047 && (GET_CODE (XEXP (x, 0)) == PRE_INC
12048 || GET_CODE (XEXP (x, 0)) == PRE_DEC
12049 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
12050 putc ('u', file);
12051 return;
12053 case 'V':
12054 /* Print the trap code for this operand. */
12055 switch (GET_CODE (x))
12057 case EQ:
12058 fputs ("eq", file); /* 4 */
12059 break;
12060 case NE:
12061 fputs ("ne", file); /* 24 */
12062 break;
12063 case LT:
12064 fputs ("lt", file); /* 16 */
12065 break;
12066 case LE:
12067 fputs ("le", file); /* 20 */
12068 break;
12069 case GT:
12070 fputs ("gt", file); /* 8 */
12071 break;
12072 case GE:
12073 fputs ("ge", file); /* 12 */
12074 break;
12075 case LTU:
12076 fputs ("llt", file); /* 2 */
12077 break;
12078 case LEU:
12079 fputs ("lle", file); /* 6 */
12080 break;
12081 case GTU:
12082 fputs ("lgt", file); /* 1 */
12083 break;
12084 case GEU:
12085 fputs ("lge", file); /* 5 */
12086 break;
12087 default:
12088 gcc_unreachable ();
12090 break;
12092 case 'w':
12093 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
12094 normally. */
12095 if (INT_P (x))
12096 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
12097 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
12098 else
12099 print_operand (file, x, 0);
12100 return;
12102 case 'W':
12103 /* MB value for a PowerPC64 rldic operand. */
12104 val = (GET_CODE (x) == CONST_INT
12105 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
12107 if (val < 0)
12108 i = -1;
12109 else
12110 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
12111 if ((val <<= 1) < 0)
12112 break;
12114 #if HOST_BITS_PER_WIDE_INT == 32
12115 if (GET_CODE (x) == CONST_INT && i >= 0)
12116 i += 32; /* zero-extend high-part was all 0's */
12117 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
12119 val = CONST_DOUBLE_LOW (x);
12121 gcc_assert (val);
12122 if (val < 0)
12123 --i;
12124 else
12125 for ( ; i < 64; i++)
12126 if ((val <<= 1) < 0)
12127 break;
12129 #endif
12131 fprintf (file, "%d", i + 1);
12132 return;
12134 case 'X':
12135 if (GET_CODE (x) == MEM
12136 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
12137 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
12138 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
12139 putc ('x', file);
12140 return;
12142 case 'Y':
12143 /* Like 'L', for third word of TImode */
12144 if (GET_CODE (x) == REG)
12145 fputs (reg_names[REGNO (x) + 2], file);
12146 else if (GET_CODE (x) == MEM)
12148 if (GET_CODE (XEXP (x, 0)) == PRE_INC
12149 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
12150 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
12151 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
12152 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
12153 else
12154 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
12155 if (small_data_operand (x, GET_MODE (x)))
12156 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
12157 reg_names[SMALL_DATA_REG]);
12159 return;
12161 case 'z':
12162 /* X is a SYMBOL_REF. Write out the name preceded by a
12163 period and without any trailing data in brackets. Used for function
12164 names. If we are configured for System V (or the embedded ABI) on
12165 the PowerPC, do not emit the period, since those systems do not use
12166 TOCs and the like. */
12167 gcc_assert (GET_CODE (x) == SYMBOL_REF);
12169 /* Mark the decl as referenced so that cgraph will output the
12170 function. */
12171 if (SYMBOL_REF_DECL (x))
12172 mark_decl_referenced (SYMBOL_REF_DECL (x));
12174 /* For macho, check to see if we need a stub. */
12175 if (TARGET_MACHO)
12177 const char *name = XSTR (x, 0);
12178 #if TARGET_MACHO
12179 if (MACHOPIC_INDIRECT
12180 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
12181 name = machopic_indirection_name (x, /*stub_p=*/true);
12182 #endif
12183 assemble_name (file, name);
12185 else if (!DOT_SYMBOLS)
12186 assemble_name (file, XSTR (x, 0));
12187 else
12188 rs6000_output_function_entry (file, XSTR (x, 0));
12189 return;
12191 case 'Z':
12192 /* Like 'L', for last word of TImode. */
12193 if (GET_CODE (x) == REG)
12194 fputs (reg_names[REGNO (x) + 3], file);
12195 else if (GET_CODE (x) == MEM)
12197 if (GET_CODE (XEXP (x, 0)) == PRE_INC
12198 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
12199 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
12200 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
12201 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
12202 else
12203 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
12204 if (small_data_operand (x, GET_MODE (x)))
12205 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
12206 reg_names[SMALL_DATA_REG]);
12208 return;
12210 /* Print AltiVec or SPE memory operand. */
12211 case 'y':
12213 rtx tmp;
12215 gcc_assert (GET_CODE (x) == MEM);
12217 tmp = XEXP (x, 0);
12219 /* Ugly hack because %y is overloaded. */
12220 if ((TARGET_SPE || TARGET_E500_DOUBLE)
12221 && (GET_MODE_SIZE (GET_MODE (x)) == 8
12222 || GET_MODE (x) == TFmode
12223 || GET_MODE (x) == TImode))
12225 /* Handle [reg]. */
12226 if (GET_CODE (tmp) == REG)
12228 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
12229 break;
12231 /* Handle [reg+UIMM]. */
12232 else if (GET_CODE (tmp) == PLUS &&
12233 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
12235 int x;
12237 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
12239 x = INTVAL (XEXP (tmp, 1));
12240 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
12241 break;
12244 /* Fall through. Must be [reg+reg]. */
12246 if (TARGET_ALTIVEC
12247 && GET_CODE (tmp) == AND
12248 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
12249 && INTVAL (XEXP (tmp, 1)) == -16)
12250 tmp = XEXP (tmp, 0);
12251 if (GET_CODE (tmp) == REG)
12252 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
12253 else
12255 gcc_assert (GET_CODE (tmp) == PLUS
12256 && REG_P (XEXP (tmp, 0))
12257 && REG_P (XEXP (tmp, 1)));
12259 if (REGNO (XEXP (tmp, 0)) == 0)
12260 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
12261 reg_names[ REGNO (XEXP (tmp, 0)) ]);
12262 else
12263 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
12264 reg_names[ REGNO (XEXP (tmp, 1)) ]);
12266 break;
12269 case 0:
12270 if (GET_CODE (x) == REG)
12271 fprintf (file, "%s", reg_names[REGNO (x)]);
12272 else if (GET_CODE (x) == MEM)
12274 /* We need to handle PRE_INC and PRE_DEC here, since we need to
12275 know the width from the mode. */
12276 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
12277 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
12278 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
12279 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
12280 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
12281 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
12282 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
12283 output_address (XEXP (XEXP (x, 0), 1));
12284 else
12285 output_address (XEXP (x, 0));
12287 else
12288 output_addr_const (file, x);
12289 return;
12291 case '&':
12292 assemble_name (file, rs6000_get_some_local_dynamic_name ());
12293 return;
12295 default:
12296 output_operand_lossage ("invalid %%xn code");
12300 /* Print the address of an operand. */
12302 void
12303 print_operand_address (FILE *file, rtx x)
12305 if (GET_CODE (x) == REG)
12306 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
12307 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
12308 || GET_CODE (x) == LABEL_REF)
12310 output_addr_const (file, x);
12311 if (small_data_operand (x, GET_MODE (x)))
12312 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
12313 reg_names[SMALL_DATA_REG]);
12314 else
12315 gcc_assert (!TARGET_TOC);
12317 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
12319 gcc_assert (REG_P (XEXP (x, 0)));
12320 if (REGNO (XEXP (x, 0)) == 0)
12321 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
12322 reg_names[ REGNO (XEXP (x, 0)) ]);
12323 else
12324 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
12325 reg_names[ REGNO (XEXP (x, 1)) ]);
12327 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
12328 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
12329 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
12330 #if TARGET_ELF
12331 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
12332 && CONSTANT_P (XEXP (x, 1)))
12334 output_addr_const (file, XEXP (x, 1));
12335 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
12337 #endif
12338 #if TARGET_MACHO
12339 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
12340 && CONSTANT_P (XEXP (x, 1)))
12342 fprintf (file, "lo16(");
12343 output_addr_const (file, XEXP (x, 1));
12344 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
12346 #endif
12347 else if (legitimate_constant_pool_address_p (x))
12349 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
12351 rtx contains_minus = XEXP (x, 1);
12352 rtx minus, symref;
12353 const char *name;
12355 /* Find the (minus (sym) (toc)) buried in X, and temporarily
12356 turn it into (sym) for output_addr_const. */
12357 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
12358 contains_minus = XEXP (contains_minus, 0);
12360 minus = XEXP (contains_minus, 0);
12361 symref = XEXP (minus, 0);
12362 XEXP (contains_minus, 0) = symref;
12363 if (TARGET_ELF)
12365 char *newname;
12367 name = XSTR (symref, 0);
12368 newname = alloca (strlen (name) + sizeof ("@toc"));
12369 strcpy (newname, name);
12370 strcat (newname, "@toc");
12371 XSTR (symref, 0) = newname;
12373 output_addr_const (file, XEXP (x, 1));
12374 if (TARGET_ELF)
12375 XSTR (symref, 0) = name;
12376 XEXP (contains_minus, 0) = minus;
12378 else
12379 output_addr_const (file, XEXP (x, 1));
12381 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
12383 else
12384 gcc_unreachable ();
12387 /* Target hook for assembling integer objects. The PowerPC version has
12388 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
12389 is defined. It also needs to handle DI-mode objects on 64-bit
12390 targets. */
12392 static bool
12393 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
12395 #ifdef RELOCATABLE_NEEDS_FIXUP
12396 /* Special handling for SI values. */
12397 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
12399 static int recurse = 0;
12401 /* For -mrelocatable, we mark all addresses that need to be fixed up
12402 in the .fixup section. */
12403 if (TARGET_RELOCATABLE
12404 && in_section != toc_section
12405 && in_section != text_section
12406 && !unlikely_text_section_p (in_section)
12407 && !recurse
12408 && GET_CODE (x) != CONST_INT
12409 && GET_CODE (x) != CONST_DOUBLE
12410 && CONSTANT_P (x))
12412 char buf[256];
12414 recurse = 1;
12415 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
12416 fixuplabelno++;
12417 ASM_OUTPUT_LABEL (asm_out_file, buf);
12418 fprintf (asm_out_file, "\t.long\t(");
12419 output_addr_const (asm_out_file, x);
12420 fprintf (asm_out_file, ")@fixup\n");
12421 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
12422 ASM_OUTPUT_ALIGN (asm_out_file, 2);
12423 fprintf (asm_out_file, "\t.long\t");
12424 assemble_name (asm_out_file, buf);
12425 fprintf (asm_out_file, "\n\t.previous\n");
12426 recurse = 0;
12427 return true;
12429 /* Remove initial .'s to turn a -mcall-aixdesc function
12430 address into the address of the descriptor, not the function
12431 itself. */
12432 else if (GET_CODE (x) == SYMBOL_REF
12433 && XSTR (x, 0)[0] == '.'
12434 && DEFAULT_ABI == ABI_AIX)
12436 const char *name = XSTR (x, 0);
12437 while (*name == '.')
12438 name++;
12440 fprintf (asm_out_file, "\t.long\t%s\n", name);
12441 return true;
12444 #endif /* RELOCATABLE_NEEDS_FIXUP */
12445 return default_assemble_integer (x, size, aligned_p);
12448 #ifdef HAVE_GAS_HIDDEN
12449 /* Emit an assembler directive to set symbol visibility for DECL to
12450 VISIBILITY_TYPE. */
12452 static void
12453 rs6000_assemble_visibility (tree decl, int vis)
12455 /* Functions need to have their entry point symbol visibility set as
12456 well as their descriptor symbol visibility. */
12457 if (DEFAULT_ABI == ABI_AIX
12458 && DOT_SYMBOLS
12459 && TREE_CODE (decl) == FUNCTION_DECL)
12461 static const char * const visibility_types[] = {
12462 NULL, "internal", "hidden", "protected"
12465 const char *name, *type;
12467 name = ((* targetm.strip_name_encoding)
12468 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
12469 type = visibility_types[vis];
12471 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
12472 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
12474 else
12475 default_assemble_visibility (decl, vis);
12477 #endif
12479 enum rtx_code
12480 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
12482 /* Reversal of FP compares takes care -- an ordered compare
12483 becomes an unordered compare and vice versa. */
12484 if (mode == CCFPmode
12485 && (!flag_finite_math_only
12486 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
12487 || code == UNEQ || code == LTGT))
12488 return reverse_condition_maybe_unordered (code);
12489 else
12490 return reverse_condition (code);
12493 /* Generate a compare for CODE. Return a brand-new rtx that
12494 represents the result of the compare. */
12496 static rtx
12497 rs6000_generate_compare (enum rtx_code code)
12499 enum machine_mode comp_mode;
12500 rtx compare_result;
12502 if (rs6000_compare_fp_p)
12503 comp_mode = CCFPmode;
12504 else if (code == GTU || code == LTU
12505 || code == GEU || code == LEU)
12506 comp_mode = CCUNSmode;
12507 else if ((code == EQ || code == NE)
12508 && GET_CODE (rs6000_compare_op0) == SUBREG
12509 && GET_CODE (rs6000_compare_op1) == SUBREG
12510 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
12511 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
12512 /* These are unsigned values, perhaps there will be a later
12513 ordering compare that can be shared with this one.
12514 Unfortunately we cannot detect the signedness of the operands
12515 for non-subregs. */
12516 comp_mode = CCUNSmode;
12517 else
12518 comp_mode = CCmode;
12520 /* First, the compare. */
12521 compare_result = gen_reg_rtx (comp_mode);
12523 /* E500 FP compare instructions on the GPRs. Yuck! */
12524 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
12525 && rs6000_compare_fp_p)
12527 rtx cmp, or_result, compare_result2;
12528 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
12530 if (op_mode == VOIDmode)
12531 op_mode = GET_MODE (rs6000_compare_op1);
12533 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
12534 This explains the following mess. */
12536 switch (code)
12538 case EQ: case UNEQ: case NE: case LTGT:
12539 switch (op_mode)
12541 case SFmode:
12542 cmp = flag_unsafe_math_optimizations
12543 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
12544 rs6000_compare_op1)
12545 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
12546 rs6000_compare_op1);
12547 break;
12549 case DFmode:
12550 cmp = flag_unsafe_math_optimizations
12551 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
12552 rs6000_compare_op1)
12553 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
12554 rs6000_compare_op1);
12555 break;
12557 case TFmode:
12558 cmp = flag_unsafe_math_optimizations
12559 ? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
12560 rs6000_compare_op1)
12561 : gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
12562 rs6000_compare_op1);
12563 break;
12565 default:
12566 gcc_unreachable ();
12568 break;
12570 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
12571 switch (op_mode)
12573 case SFmode:
12574 cmp = flag_unsafe_math_optimizations
12575 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
12576 rs6000_compare_op1)
12577 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
12578 rs6000_compare_op1);
12579 break;
12581 case DFmode:
12582 cmp = flag_unsafe_math_optimizations
12583 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
12584 rs6000_compare_op1)
12585 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
12586 rs6000_compare_op1);
12587 break;
12589 case TFmode:
12590 cmp = flag_unsafe_math_optimizations
12591 ? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
12592 rs6000_compare_op1)
12593 : gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
12594 rs6000_compare_op1);
12595 break;
12597 default:
12598 gcc_unreachable ();
12600 break;
12602 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
12603 switch (op_mode)
12605 case SFmode:
12606 cmp = flag_unsafe_math_optimizations
12607 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
12608 rs6000_compare_op1)
12609 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
12610 rs6000_compare_op1);
12611 break;
12613 case DFmode:
12614 cmp = flag_unsafe_math_optimizations
12615 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
12616 rs6000_compare_op1)
12617 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
12618 rs6000_compare_op1);
12619 break;
12621 case TFmode:
12622 cmp = flag_unsafe_math_optimizations
12623 ? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
12624 rs6000_compare_op1)
12625 : gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
12626 rs6000_compare_op1);
12627 break;
12629 default:
12630 gcc_unreachable ();
12632 break;
12633 default:
12634 gcc_unreachable ();
12637 /* Synthesize LE and GE from LT/GT || EQ. */
12638 if (code == LE || code == GE || code == LEU || code == GEU)
12640 emit_insn (cmp);
12642 switch (code)
12644 case LE: code = LT; break;
12645 case GE: code = GT; break;
12646 case LEU: code = LT; break;
12647 case GEU: code = GT; break;
12648 default: gcc_unreachable ();
12651 compare_result2 = gen_reg_rtx (CCFPmode);
12653 /* Do the EQ. */
12654 switch (op_mode)
12656 case SFmode:
12657 cmp = flag_unsafe_math_optimizations
12658 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
12659 rs6000_compare_op1)
12660 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
12661 rs6000_compare_op1);
12662 break;
12664 case DFmode:
12665 cmp = flag_unsafe_math_optimizations
12666 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
12667 rs6000_compare_op1)
12668 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
12669 rs6000_compare_op1);
12670 break;
12672 case TFmode:
12673 cmp = flag_unsafe_math_optimizations
12674 ? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
12675 rs6000_compare_op1)
12676 : gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
12677 rs6000_compare_op1);
12678 break;
12680 default:
12681 gcc_unreachable ();
12683 emit_insn (cmp);
12685 /* OR them together. */
12686 or_result = gen_reg_rtx (CCFPmode);
12687 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
12688 compare_result2);
12689 compare_result = or_result;
12690 code = EQ;
12692 else
12694 if (code == NE || code == LTGT)
12695 code = NE;
12696 else
12697 code = EQ;
12700 emit_insn (cmp);
12702 else
12704 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
12705 CLOBBERs to match cmptf_internal2 pattern. */
12706 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
12707 && GET_MODE (rs6000_compare_op0) == TFmode
12708 && !TARGET_IEEEQUAD
12709 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
12710 emit_insn (gen_rtx_PARALLEL (VOIDmode,
12711 gen_rtvec (9,
12712 gen_rtx_SET (VOIDmode,
12713 compare_result,
12714 gen_rtx_COMPARE (comp_mode,
12715 rs6000_compare_op0,
12716 rs6000_compare_op1)),
12717 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12718 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12719 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12720 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12721 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12722 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12723 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12724 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
12725 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
12726 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
12728 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
12729 comp_mode = CCEQmode;
12730 compare_result = gen_reg_rtx (CCEQmode);
12731 if (TARGET_64BIT)
12732 emit_insn (gen_stack_protect_testdi (compare_result,
12733 rs6000_compare_op0, op1));
12734 else
12735 emit_insn (gen_stack_protect_testsi (compare_result,
12736 rs6000_compare_op0, op1));
12738 else
12739 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
12740 gen_rtx_COMPARE (comp_mode,
12741 rs6000_compare_op0,
12742 rs6000_compare_op1)));
12745 /* Some kinds of FP comparisons need an OR operation;
12746 under flag_finite_math_only we don't bother. */
12747 if (rs6000_compare_fp_p
12748 && !flag_finite_math_only
12749 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
12750 && (code == LE || code == GE
12751 || code == UNEQ || code == LTGT
12752 || code == UNGT || code == UNLT))
12754 enum rtx_code or1, or2;
12755 rtx or1_rtx, or2_rtx, compare2_rtx;
12756 rtx or_result = gen_reg_rtx (CCEQmode);
12758 switch (code)
12760 case LE: or1 = LT; or2 = EQ; break;
12761 case GE: or1 = GT; or2 = EQ; break;
12762 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
12763 case LTGT: or1 = LT; or2 = GT; break;
12764 case UNGT: or1 = UNORDERED; or2 = GT; break;
12765 case UNLT: or1 = UNORDERED; or2 = LT; break;
12766 default: gcc_unreachable ();
12768 validate_condition_mode (or1, comp_mode);
12769 validate_condition_mode (or2, comp_mode);
12770 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
12771 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
12772 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
12773 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
12774 const_true_rtx);
12775 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
12777 compare_result = or_result;
12778 code = EQ;
12781 validate_condition_mode (code, GET_MODE (compare_result));
12783 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
12787 /* Emit the RTL for an sCOND pattern. */
12789 void
12790 rs6000_emit_sCOND (enum rtx_code code, rtx result)
12792 rtx condition_rtx;
12793 enum machine_mode op_mode;
12794 enum rtx_code cond_code;
12796 condition_rtx = rs6000_generate_compare (code);
12797 cond_code = GET_CODE (condition_rtx);
12799 if (rs6000_compare_fp_p
12800 && !TARGET_FPRS && TARGET_HARD_FLOAT)
12802 rtx t;
12804 PUT_MODE (condition_rtx, SImode);
12805 t = XEXP (condition_rtx, 0);
12807 gcc_assert (cond_code == NE || cond_code == EQ);
12809 if (cond_code == NE)
12810 emit_insn (gen_e500_flip_gt_bit (t, t));
12812 emit_insn (gen_move_from_CR_gt_bit (result, t));
12813 return;
12816 if (cond_code == NE
12817 || cond_code == GE || cond_code == LE
12818 || cond_code == GEU || cond_code == LEU
12819 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
12821 rtx not_result = gen_reg_rtx (CCEQmode);
12822 rtx not_op, rev_cond_rtx;
12823 enum machine_mode cc_mode;
12825 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
12827 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
12828 SImode, XEXP (condition_rtx, 0), const0_rtx);
12829 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
12830 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
12831 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
12834 op_mode = GET_MODE (rs6000_compare_op0);
12835 if (op_mode == VOIDmode)
12836 op_mode = GET_MODE (rs6000_compare_op1);
12838 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
12840 PUT_MODE (condition_rtx, DImode);
12841 convert_move (result, condition_rtx, 0);
12843 else
12845 PUT_MODE (condition_rtx, SImode);
12846 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
12850 /* Emit a branch of kind CODE to location LOC. */
12852 void
12853 rs6000_emit_cbranch (enum rtx_code code, rtx loc)
12855 rtx condition_rtx, loc_ref;
12857 condition_rtx = rs6000_generate_compare (code);
12858 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
12859 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
12860 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
12861 loc_ref, pc_rtx)));
12864 /* Return the string to output a conditional branch to LABEL, which is
12865 the operand number of the label, or -1 if the branch is really a
12866 conditional return.
12868 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
12869 condition code register and its mode specifies what kind of
12870 comparison we made.
12872 REVERSED is nonzero if we should reverse the sense of the comparison.
12874 INSN is the insn. */
12876 char *
12877 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
12879 static char string[64];
12880 enum rtx_code code = GET_CODE (op);
12881 rtx cc_reg = XEXP (op, 0);
12882 enum machine_mode mode = GET_MODE (cc_reg);
12883 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
12884 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12885 int really_reversed = reversed ^ need_longbranch;
12886 char *s = string;
12887 const char *ccode;
12888 const char *pred;
12889 rtx note;
12891 validate_condition_mode (code, mode);
12893 /* Work out which way this really branches. We could use
12894 reverse_condition_maybe_unordered here always but this
12895 makes the resulting assembler clearer. */
12896 if (really_reversed)
12898 /* Reversal of FP compares takes care -- an ordered compare
12899 becomes an unordered compare and vice versa. */
12900 if (mode == CCFPmode)
12901 code = reverse_condition_maybe_unordered (code);
12902 else
12903 code = reverse_condition (code);
12906 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
12908 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
12909 to the GT bit. */
12910 switch (code)
12912 case EQ:
12913 /* Opposite of GT. */
12914 code = GT;
12915 break;
12917 case NE:
12918 code = UNLE;
12919 break;
12921 default:
12922 gcc_unreachable ();
12926 switch (code)
12928 /* Not all of these are actually distinct opcodes, but
12929 we distinguish them for clarity of the resulting assembler. */
12930 case NE: case LTGT:
12931 ccode = "ne"; break;
12932 case EQ: case UNEQ:
12933 ccode = "eq"; break;
12934 case GE: case GEU:
12935 ccode = "ge"; break;
12936 case GT: case GTU: case UNGT:
12937 ccode = "gt"; break;
12938 case LE: case LEU:
12939 ccode = "le"; break;
12940 case LT: case LTU: case UNLT:
12941 ccode = "lt"; break;
12942 case UNORDERED: ccode = "un"; break;
12943 case ORDERED: ccode = "nu"; break;
12944 case UNGE: ccode = "nl"; break;
12945 case UNLE: ccode = "ng"; break;
12946 default:
12947 gcc_unreachable ();
12950 /* Maybe we have a guess as to how likely the branch is.
12951 The old mnemonics don't have a way to specify this information. */
12952 pred = "";
12953 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
12954 if (note != NULL_RTX)
12956 /* PROB is the difference from 50%. */
12957 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
12959 /* Only hint for highly probable/improbable branches on newer
12960 cpus as static prediction overrides processor dynamic
12961 prediction. For older cpus we may as well always hint, but
12962 assume not taken for branches that are very close to 50% as a
12963 mispredicted taken branch is more expensive than a
12964 mispredicted not-taken branch. */
12965 if (rs6000_always_hint
12966 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
12967 && br_prob_note_reliable_p (note)))
12969 if (abs (prob) > REG_BR_PROB_BASE / 20
12970 && ((prob > 0) ^ need_longbranch))
12971 pred = "+";
12972 else
12973 pred = "-";
12977 if (label == NULL)
12978 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12979 else
12980 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12982 /* We need to escape any '%' characters in the reg_names string.
12983 Assume they'd only be the first character.... */
12984 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
12985 *s++ = '%';
12986 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12988 if (label != NULL)
12990 /* If the branch distance was too far, we may have to use an
12991 unconditional branch to go the distance. */
12992 if (need_longbranch)
12993 s += sprintf (s, ",$+8\n\tb %s", label);
12994 else
12995 s += sprintf (s, ",%s", label);
12998 return string;
13001 /* Return the string to flip the GT bit on a CR. */
13002 char *
13003 output_e500_flip_gt_bit (rtx dst, rtx src)
13005 static char string[64];
13006 int a, b;
13008 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
13009 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
13011 /* GT bit. */
13012 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
13013 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
13015 sprintf (string, "crnot %d,%d", a, b);
13016 return string;
13019 /* Return insn index for the vector compare instruction for given CODE,
13020 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
13021 not available. */
13023 static int
13024 get_vec_cmp_insn (enum rtx_code code,
13025 enum machine_mode dest_mode,
13026 enum machine_mode op_mode)
13028 if (!TARGET_ALTIVEC)
13029 return INSN_NOT_AVAILABLE;
13031 switch (code)
13033 case EQ:
13034 if (dest_mode == V16QImode && op_mode == V16QImode)
13035 return UNSPEC_VCMPEQUB;
13036 if (dest_mode == V8HImode && op_mode == V8HImode)
13037 return UNSPEC_VCMPEQUH;
13038 if (dest_mode == V4SImode && op_mode == V4SImode)
13039 return UNSPEC_VCMPEQUW;
13040 if (dest_mode == V4SImode && op_mode == V4SFmode)
13041 return UNSPEC_VCMPEQFP;
13042 break;
13043 case GE:
13044 if (dest_mode == V4SImode && op_mode == V4SFmode)
13045 return UNSPEC_VCMPGEFP;
13046 case GT:
13047 if (dest_mode == V16QImode && op_mode == V16QImode)
13048 return UNSPEC_VCMPGTSB;
13049 if (dest_mode == V8HImode && op_mode == V8HImode)
13050 return UNSPEC_VCMPGTSH;
13051 if (dest_mode == V4SImode && op_mode == V4SImode)
13052 return UNSPEC_VCMPGTSW;
13053 if (dest_mode == V4SImode && op_mode == V4SFmode)
13054 return UNSPEC_VCMPGTFP;
13055 break;
13056 case GTU:
13057 if (dest_mode == V16QImode && op_mode == V16QImode)
13058 return UNSPEC_VCMPGTUB;
13059 if (dest_mode == V8HImode && op_mode == V8HImode)
13060 return UNSPEC_VCMPGTUH;
13061 if (dest_mode == V4SImode && op_mode == V4SImode)
13062 return UNSPEC_VCMPGTUW;
13063 break;
13064 default:
13065 break;
13067 return INSN_NOT_AVAILABLE;
13070 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
13071 DMODE is expected destination mode. This is a recursive function. */
13073 static rtx
13074 rs6000_emit_vector_compare (enum rtx_code rcode,
13075 rtx op0, rtx op1,
13076 enum machine_mode dmode)
13078 int vec_cmp_insn;
13079 rtx mask;
13080 enum machine_mode dest_mode;
13081 enum machine_mode op_mode = GET_MODE (op1);
13083 gcc_assert (TARGET_ALTIVEC);
13084 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
13086 /* Floating point vector compare instructions uses destination V4SImode.
13087 Move destination to appropriate mode later. */
13088 if (dmode == V4SFmode)
13089 dest_mode = V4SImode;
13090 else
13091 dest_mode = dmode;
13093 mask = gen_reg_rtx (dest_mode);
13094 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
13096 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
13098 bool swap_operands = false;
13099 bool try_again = false;
13100 switch (rcode)
13102 case LT:
13103 rcode = GT;
13104 swap_operands = true;
13105 try_again = true;
13106 break;
13107 case LTU:
13108 rcode = GTU;
13109 swap_operands = true;
13110 try_again = true;
13111 break;
13112 case NE:
13113 case UNLE:
13114 case UNLT:
13115 case UNGE:
13116 case UNGT:
13117 /* Invert condition and try again.
13118 e.g., A != B becomes ~(A==B). */
13120 enum rtx_code rev_code;
13121 enum insn_code nor_code;
13122 rtx eq_rtx;
13124 rev_code = reverse_condition_maybe_unordered (rcode);
13125 eq_rtx = rs6000_emit_vector_compare (rev_code, op0, op1,
13126 dest_mode);
13128 nor_code = optab_handler (one_cmpl_optab, (int)dest_mode)->insn_code;
13129 gcc_assert (nor_code != CODE_FOR_nothing);
13130 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
13132 if (dmode != dest_mode)
13134 rtx temp = gen_reg_rtx (dest_mode);
13135 convert_move (temp, mask, 0);
13136 return temp;
13138 return mask;
13140 break;
13141 case GE:
13142 case GEU:
13143 case LE:
13144 case LEU:
13145 /* Try GT/GTU/LT/LTU OR EQ */
13147 rtx c_rtx, eq_rtx;
13148 enum insn_code ior_code;
13149 enum rtx_code new_code;
13151 switch (rcode)
13153 case GE:
13154 new_code = GT;
13155 break;
13157 case GEU:
13158 new_code = GTU;
13159 break;
13161 case LE:
13162 new_code = LT;
13163 break;
13165 case LEU:
13166 new_code = LTU;
13167 break;
13169 default:
13170 gcc_unreachable ();
13173 c_rtx = rs6000_emit_vector_compare (new_code,
13174 op0, op1, dest_mode);
13175 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
13176 dest_mode);
13178 ior_code = optab_handler (ior_optab, (int)dest_mode)->insn_code;
13179 gcc_assert (ior_code != CODE_FOR_nothing);
13180 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
13181 if (dmode != dest_mode)
13183 rtx temp = gen_reg_rtx (dest_mode);
13184 convert_move (temp, mask, 0);
13185 return temp;
13187 return mask;
13189 break;
13190 default:
13191 gcc_unreachable ();
13194 if (try_again)
13196 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
13197 /* You only get two chances. */
13198 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
13201 if (swap_operands)
13203 rtx tmp;
13204 tmp = op0;
13205 op0 = op1;
13206 op1 = tmp;
13210 emit_insn (gen_rtx_SET (VOIDmode, mask,
13211 gen_rtx_UNSPEC (dest_mode,
13212 gen_rtvec (2, op0, op1),
13213 vec_cmp_insn)));
13214 if (dmode != dest_mode)
13216 rtx temp = gen_reg_rtx (dest_mode);
13217 convert_move (temp, mask, 0);
13218 return temp;
13220 return mask;
13223 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
13224 valid insn doesn exist for given mode. */
13226 static int
13227 get_vsel_insn (enum machine_mode mode)
13229 switch (mode)
13231 case V4SImode:
13232 return UNSPEC_VSEL4SI;
13233 break;
13234 case V4SFmode:
13235 return UNSPEC_VSEL4SF;
13236 break;
13237 case V8HImode:
13238 return UNSPEC_VSEL8HI;
13239 break;
13240 case V16QImode:
13241 return UNSPEC_VSEL16QI;
13242 break;
13243 default:
13244 return INSN_NOT_AVAILABLE;
13245 break;
13247 return INSN_NOT_AVAILABLE;
13250 /* Emit vector select insn where DEST is destination using
13251 operands OP1, OP2 and MASK. */
13253 static void
13254 rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
13256 rtx t, temp;
13257 enum machine_mode dest_mode = GET_MODE (dest);
13258 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
13260 temp = gen_reg_rtx (dest_mode);
13262 /* For each vector element, select op1 when mask is 1 otherwise
13263 select op2. */
13264 t = gen_rtx_SET (VOIDmode, temp,
13265 gen_rtx_UNSPEC (dest_mode,
13266 gen_rtvec (3, op2, op1, mask),
13267 vsel_insn_index));
13268 emit_insn (t);
13269 emit_move_insn (dest, temp);
13270 return;
13273 /* Emit vector conditional expression.
13274 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
13275 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
13278 rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
13279 rtx cond, rtx cc_op0, rtx cc_op1)
13281 enum machine_mode dest_mode = GET_MODE (dest);
13282 enum rtx_code rcode = GET_CODE (cond);
13283 rtx mask;
13285 if (!TARGET_ALTIVEC)
13286 return 0;
13288 /* Get the vector mask for the given relational operations. */
13289 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
13291 rs6000_emit_vector_select (dest, op1, op2, mask);
13293 return 1;
13296 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
13297 operands of the last comparison is nonzero/true, FALSE_COND if it
13298 is zero/false. Return 0 if the hardware has no such operation. */
13301 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
13303 enum rtx_code code = GET_CODE (op);
13304 rtx op0 = rs6000_compare_op0;
13305 rtx op1 = rs6000_compare_op1;
13306 REAL_VALUE_TYPE c1;
13307 enum machine_mode compare_mode = GET_MODE (op0);
13308 enum machine_mode result_mode = GET_MODE (dest);
13309 rtx temp;
13310 bool is_against_zero;
13312 /* These modes should always match. */
13313 if (GET_MODE (op1) != compare_mode
13314 /* In the isel case however, we can use a compare immediate, so
13315 op1 may be a small constant. */
13316 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
13317 return 0;
13318 if (GET_MODE (true_cond) != result_mode)
13319 return 0;
13320 if (GET_MODE (false_cond) != result_mode)
13321 return 0;
13323 /* First, work out if the hardware can do this at all, or
13324 if it's too slow.... */
13325 if (! rs6000_compare_fp_p)
13327 if (TARGET_ISEL)
13328 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
13329 return 0;
13331 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
13332 && SCALAR_FLOAT_MODE_P (compare_mode))
13333 return 0;
13335 is_against_zero = op1 == CONST0_RTX (compare_mode);
13337 /* A floating-point subtract might overflow, underflow, or produce
13338 an inexact result, thus changing the floating-point flags, so it
13339 can't be generated if we care about that. It's safe if one side
13340 of the construct is zero, since then no subtract will be
13341 generated. */
13342 if (SCALAR_FLOAT_MODE_P (compare_mode)
13343 && flag_trapping_math && ! is_against_zero)
13344 return 0;
13346 /* Eliminate half of the comparisons by switching operands, this
13347 makes the remaining code simpler. */
13348 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
13349 || code == LTGT || code == LT || code == UNLE)
13351 code = reverse_condition_maybe_unordered (code);
13352 temp = true_cond;
13353 true_cond = false_cond;
13354 false_cond = temp;
13357 /* UNEQ and LTGT take four instructions for a comparison with zero,
13358 it'll probably be faster to use a branch here too. */
13359 if (code == UNEQ && HONOR_NANS (compare_mode))
13360 return 0;
13362 if (GET_CODE (op1) == CONST_DOUBLE)
13363 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
13365 /* We're going to try to implement comparisons by performing
13366 a subtract, then comparing against zero. Unfortunately,
13367 Inf - Inf is NaN which is not zero, and so if we don't
13368 know that the operand is finite and the comparison
13369 would treat EQ different to UNORDERED, we can't do it. */
13370 if (HONOR_INFINITIES (compare_mode)
13371 && code != GT && code != UNGE
13372 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
13373 /* Constructs of the form (a OP b ? a : b) are safe. */
13374 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
13375 || (! rtx_equal_p (op0, true_cond)
13376 && ! rtx_equal_p (op1, true_cond))))
13377 return 0;
13379 /* At this point we know we can use fsel. */
13381 /* Reduce the comparison to a comparison against zero. */
13382 if (! is_against_zero)
13384 temp = gen_reg_rtx (compare_mode);
13385 emit_insn (gen_rtx_SET (VOIDmode, temp,
13386 gen_rtx_MINUS (compare_mode, op0, op1)));
13387 op0 = temp;
13388 op1 = CONST0_RTX (compare_mode);
13391 /* If we don't care about NaNs we can reduce some of the comparisons
13392 down to faster ones. */
13393 if (! HONOR_NANS (compare_mode))
13394 switch (code)
13396 case GT:
13397 code = LE;
13398 temp = true_cond;
13399 true_cond = false_cond;
13400 false_cond = temp;
13401 break;
13402 case UNGE:
13403 code = GE;
13404 break;
13405 case UNEQ:
13406 code = EQ;
13407 break;
13408 default:
13409 break;
13412 /* Now, reduce everything down to a GE. */
13413 switch (code)
13415 case GE:
13416 break;
13418 case LE:
13419 temp = gen_reg_rtx (compare_mode);
13420 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
13421 op0 = temp;
13422 break;
13424 case ORDERED:
13425 temp = gen_reg_rtx (compare_mode);
13426 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
13427 op0 = temp;
13428 break;
13430 case EQ:
13431 temp = gen_reg_rtx (compare_mode);
13432 emit_insn (gen_rtx_SET (VOIDmode, temp,
13433 gen_rtx_NEG (compare_mode,
13434 gen_rtx_ABS (compare_mode, op0))));
13435 op0 = temp;
13436 break;
13438 case UNGE:
13439 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
13440 temp = gen_reg_rtx (result_mode);
13441 emit_insn (gen_rtx_SET (VOIDmode, temp,
13442 gen_rtx_IF_THEN_ELSE (result_mode,
13443 gen_rtx_GE (VOIDmode,
13444 op0, op1),
13445 true_cond, false_cond)));
13446 false_cond = true_cond;
13447 true_cond = temp;
13449 temp = gen_reg_rtx (compare_mode);
13450 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
13451 op0 = temp;
13452 break;
13454 case GT:
13455 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
13456 temp = gen_reg_rtx (result_mode);
13457 emit_insn (gen_rtx_SET (VOIDmode, temp,
13458 gen_rtx_IF_THEN_ELSE (result_mode,
13459 gen_rtx_GE (VOIDmode,
13460 op0, op1),
13461 true_cond, false_cond)));
13462 true_cond = false_cond;
13463 false_cond = temp;
13465 temp = gen_reg_rtx (compare_mode);
13466 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
13467 op0 = temp;
13468 break;
13470 default:
13471 gcc_unreachable ();
13474 emit_insn (gen_rtx_SET (VOIDmode, dest,
13475 gen_rtx_IF_THEN_ELSE (result_mode,
13476 gen_rtx_GE (VOIDmode,
13477 op0, op1),
13478 true_cond, false_cond)));
13479 return 1;
13482 /* Same as above, but for ints (isel). */
13484 static int
13485 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
13487 rtx condition_rtx, cr;
13489 /* All isel implementations thus far are 32-bits. */
13490 if (GET_MODE (rs6000_compare_op0) != SImode)
13491 return 0;
13493 /* We still have to do the compare, because isel doesn't do a
13494 compare, it just looks at the CRx bits set by a previous compare
13495 instruction. */
13496 condition_rtx = rs6000_generate_compare (GET_CODE (op));
13497 cr = XEXP (condition_rtx, 0);
13499 if (GET_MODE (cr) == CCmode)
13500 emit_insn (gen_isel_signed (dest, condition_rtx,
13501 true_cond, false_cond, cr));
13502 else
13503 emit_insn (gen_isel_unsigned (dest, condition_rtx,
13504 true_cond, false_cond, cr));
13506 return 1;
13509 const char *
13510 output_isel (rtx *operands)
13512 enum rtx_code code;
13514 code = GET_CODE (operands[1]);
13515 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
13517 PUT_CODE (operands[1], reverse_condition (code));
13518 return "isel %0,%3,%2,%j1";
13520 else
13521 return "isel %0,%2,%3,%j1";
13524 void
13525 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
13527 enum machine_mode mode = GET_MODE (op0);
13528 enum rtx_code c;
13529 rtx target;
13531 if (code == SMAX || code == SMIN)
13532 c = GE;
13533 else
13534 c = GEU;
13536 if (code == SMAX || code == UMAX)
13537 target = emit_conditional_move (dest, c, op0, op1, mode,
13538 op0, op1, mode, 0);
13539 else
13540 target = emit_conditional_move (dest, c, op0, op1, mode,
13541 op1, op0, mode, 0);
13542 gcc_assert (target);
13543 if (target != dest)
13544 emit_move_insn (dest, target);
13547 /* Emit instructions to perform a load-reserved/store-conditional operation.
13548 The operation performed is an atomic
13549 (set M (CODE:MODE M OP))
13550 If not NULL, BEFORE is atomically set to M before the operation, and
13551 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
13552 If SYNC_P then a memory barrier is emitted before the operation.
13553 Either OP or M may be wrapped in a NOT operation. */
13555 void
13556 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
13557 rtx m, rtx op, rtx before_param, rtx after_param,
13558 bool sync_p)
13560 enum machine_mode used_mode;
13561 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
13562 rtx used_m;
13563 rtvec vec;
13564 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
13565 rtx shift = NULL_RTX;
13567 if (sync_p)
13568 emit_insn (gen_memory_barrier ());
13570 if (GET_CODE (m) == NOT)
13571 used_m = XEXP (m, 0);
13572 else
13573 used_m = m;
13575 /* If this is smaller than SImode, we'll have to use SImode with
13576 adjustments. */
13577 if (mode == QImode || mode == HImode)
13579 rtx newop, oldop;
13581 if (MEM_ALIGN (used_m) >= 32)
13583 int ishift = 0;
13584 if (BYTES_BIG_ENDIAN)
13585 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
13587 shift = GEN_INT (ishift);
13588 used_m = change_address (used_m, SImode, 0);
13590 else
13592 rtx addrSI, aligned_addr;
13593 int shift_mask = mode == QImode ? 0x18 : 0x10;
13595 addrSI = gen_lowpart_common (SImode,
13596 force_reg (Pmode, XEXP (used_m, 0)));
13597 addrSI = force_reg (SImode, addrSI);
13598 shift = gen_reg_rtx (SImode);
13600 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
13601 GEN_INT (shift_mask)));
13602 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
13604 aligned_addr = expand_binop (Pmode, and_optab,
13605 XEXP (used_m, 0),
13606 GEN_INT (-4), NULL_RTX,
13607 1, OPTAB_LIB_WIDEN);
13608 used_m = change_address (used_m, SImode, aligned_addr);
13609 set_mem_align (used_m, 32);
13611 /* It's safe to keep the old alias set of USED_M, because
13612 the operation is atomic and only affects the original
13613 USED_M. */
13614 if (GET_CODE (m) == NOT)
13615 m = gen_rtx_NOT (SImode, used_m);
13616 else
13617 m = used_m;
13619 if (GET_CODE (op) == NOT)
13621 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
13622 oldop = gen_rtx_NOT (SImode, oldop);
13624 else
13625 oldop = lowpart_subreg (SImode, op, mode);
13627 switch (code)
13629 case IOR:
13630 case XOR:
13631 newop = expand_binop (SImode, and_optab,
13632 oldop, GEN_INT (imask), NULL_RTX,
13633 1, OPTAB_LIB_WIDEN);
13634 emit_insn (gen_ashlsi3 (newop, newop, shift));
13635 break;
13637 case AND:
13638 newop = expand_binop (SImode, ior_optab,
13639 oldop, GEN_INT (~imask), NULL_RTX,
13640 1, OPTAB_LIB_WIDEN);
13641 emit_insn (gen_rotlsi3 (newop, newop, shift));
13642 break;
13644 case PLUS:
13645 case MINUS:
13647 rtx mask;
13649 newop = expand_binop (SImode, and_optab,
13650 oldop, GEN_INT (imask), NULL_RTX,
13651 1, OPTAB_LIB_WIDEN);
13652 emit_insn (gen_ashlsi3 (newop, newop, shift));
13654 mask = gen_reg_rtx (SImode);
13655 emit_move_insn (mask, GEN_INT (imask));
13656 emit_insn (gen_ashlsi3 (mask, mask, shift));
13658 if (code == PLUS)
13659 newop = gen_rtx_PLUS (SImode, m, newop);
13660 else
13661 newop = gen_rtx_MINUS (SImode, m, newop);
13662 newop = gen_rtx_AND (SImode, newop, mask);
13663 newop = gen_rtx_IOR (SImode, newop,
13664 gen_rtx_AND (SImode,
13665 gen_rtx_NOT (SImode, mask),
13666 m));
13667 break;
13670 default:
13671 gcc_unreachable ();
13674 if (GET_CODE (m) == NOT)
13676 rtx mask, xorm;
13678 mask = gen_reg_rtx (SImode);
13679 emit_move_insn (mask, GEN_INT (imask));
13680 emit_insn (gen_ashlsi3 (mask, mask, shift));
13682 xorm = gen_rtx_XOR (SImode, used_m, mask);
13683 /* Depending on the value of 'op', the XOR or the operation might
13684 be able to be simplified away. */
13685 newop = simplify_gen_binary (code, SImode, xorm, newop);
13687 op = newop;
13688 used_mode = SImode;
13689 before = gen_reg_rtx (used_mode);
13690 after = gen_reg_rtx (used_mode);
13692 else
13694 used_mode = mode;
13695 before = before_param;
13696 after = after_param;
13698 if (before == NULL_RTX)
13699 before = gen_reg_rtx (used_mode);
13700 if (after == NULL_RTX)
13701 after = gen_reg_rtx (used_mode);
13704 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
13705 && used_mode != mode)
13706 the_op = op; /* Computed above. */
13707 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
13708 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
13709 else
13710 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
13712 set_after = gen_rtx_SET (VOIDmode, after, the_op);
13713 set_before = gen_rtx_SET (VOIDmode, before, used_m);
13714 set_atomic = gen_rtx_SET (VOIDmode, used_m,
13715 gen_rtx_UNSPEC (used_mode,
13716 gen_rtvec (1, the_op),
13717 UNSPEC_SYNC_OP));
13718 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
13720 if ((code == PLUS || code == MINUS) && used_mode != mode)
13721 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
13722 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
13723 else
13724 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
13725 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
13727 /* Shift and mask the return values properly. */
13728 if (used_mode != mode && before_param)
13730 emit_insn (gen_lshrsi3 (before, before, shift));
13731 convert_move (before_param, before, 1);
13734 if (used_mode != mode && after_param)
13736 emit_insn (gen_lshrsi3 (after, after, shift));
13737 convert_move (after_param, after, 1);
13740 /* The previous sequence will end with a branch that's dependent on
13741 the conditional store, so placing an isync will ensure that no
13742 other instructions (especially, no load or store instructions)
13743 can start before the atomic operation completes. */
13744 if (sync_p)
13745 emit_insn (gen_isync ());
13748 /* A subroutine of the atomic operation splitters. Jump to LABEL if
13749 COND is true. Mark the jump as unlikely to be taken. */
13751 static void
13752 emit_unlikely_jump (rtx cond, rtx label)
13754 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
13755 rtx x;
13757 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
13758 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
13759 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
13762 /* A subroutine of the atomic operation splitters. Emit a load-locked
13763 instruction in MODE. */
13765 static void
13766 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
13768 rtx (*fn) (rtx, rtx) = NULL;
13769 if (mode == SImode)
13770 fn = gen_load_locked_si;
13771 else if (mode == DImode)
13772 fn = gen_load_locked_di;
13773 emit_insn (fn (reg, mem));
13776 /* A subroutine of the atomic operation splitters. Emit a store-conditional
13777 instruction in MODE. */
13779 static void
13780 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
13782 rtx (*fn) (rtx, rtx, rtx) = NULL;
13783 if (mode == SImode)
13784 fn = gen_store_conditional_si;
13785 else if (mode == DImode)
13786 fn = gen_store_conditional_di;
13788 /* Emit sync before stwcx. to address PPC405 Erratum. */
13789 if (PPC405_ERRATUM77)
13790 emit_insn (gen_memory_barrier ());
13792 emit_insn (fn (res, mem, val));
13795 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
13796 to perform. MEM is the memory on which to operate. VAL is the second
13797 operand of the binary operator. BEFORE and AFTER are optional locations to
13798 return the value of MEM either before of after the operation. SCRATCH is
13799 a scratch register. */
13801 void
13802 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
13803 rtx before, rtx after, rtx scratch)
13805 enum machine_mode mode = GET_MODE (mem);
13806 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13808 emit_insn (gen_memory_barrier ());
13810 label = gen_label_rtx ();
13811 emit_label (label);
13812 label = gen_rtx_LABEL_REF (VOIDmode, label);
13814 if (before == NULL_RTX)
13815 before = scratch;
13816 emit_load_locked (mode, before, mem);
13818 if (code == NOT)
13819 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
13820 else if (code == AND)
13821 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
13822 else
13823 x = gen_rtx_fmt_ee (code, mode, before, val);
13825 if (after != NULL_RTX)
13826 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
13827 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
13829 emit_store_conditional (mode, cond, mem, scratch);
13831 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13832 emit_unlikely_jump (x, label);
13834 emit_insn (gen_isync ());
13837 /* Expand an atomic compare and swap operation. MEM is the memory on which
13838 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
13839 value to be stored. SCRATCH is a scratch GPR. */
13841 void
13842 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
13843 rtx scratch)
13845 enum machine_mode mode = GET_MODE (mem);
13846 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13848 emit_insn (gen_memory_barrier ());
13850 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13851 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13852 emit_label (XEXP (label1, 0));
13854 emit_load_locked (mode, retval, mem);
13856 x = gen_rtx_COMPARE (CCmode, retval, oldval);
13857 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
13859 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13860 emit_unlikely_jump (x, label2);
13862 emit_move_insn (scratch, newval);
13863 emit_store_conditional (mode, cond, mem, scratch);
13865 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13866 emit_unlikely_jump (x, label1);
13868 emit_insn (gen_isync ());
13869 emit_label (XEXP (label2, 0));
13872 /* Expand an atomic test and set operation. MEM is the memory on which
13873 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
13875 void
13876 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
13878 enum machine_mode mode = GET_MODE (mem);
13879 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13881 emit_insn (gen_memory_barrier ());
13883 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13884 emit_label (XEXP (label, 0));
13886 emit_load_locked (mode, retval, mem);
13887 emit_move_insn (scratch, val);
13888 emit_store_conditional (mode, cond, mem, scratch);
13890 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13891 emit_unlikely_jump (x, label);
13893 emit_insn (gen_isync ());
13896 void
13897 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
13899 enum machine_mode mode = GET_MODE (mem);
13900 rtx addrSI, align, wdst, shift, mask;
13901 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
13902 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
13904 /* Shift amount for subword relative to aligned word. */
13905 addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0)));
13906 shift = gen_reg_rtx (SImode);
13907 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
13908 GEN_INT (shift_mask)));
13909 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
13911 /* Shift and mask old value into position within word. */
13912 oldval = convert_modes (SImode, mode, oldval, 1);
13913 oldval = expand_binop (SImode, and_optab,
13914 oldval, GEN_INT (imask), NULL_RTX,
13915 1, OPTAB_LIB_WIDEN);
13916 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
13918 /* Shift and mask new value into position within word. */
13919 newval = convert_modes (SImode, mode, newval, 1);
13920 newval = expand_binop (SImode, and_optab,
13921 newval, GEN_INT (imask), NULL_RTX,
13922 1, OPTAB_LIB_WIDEN);
13923 emit_insn (gen_ashlsi3 (newval, newval, shift));
13925 /* Mask for insertion. */
13926 mask = gen_reg_rtx (SImode);
13927 emit_move_insn (mask, GEN_INT (imask));
13928 emit_insn (gen_ashlsi3 (mask, mask, shift));
13930 /* Address of aligned word containing subword. */
13931 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
13932 NULL_RTX, 1, OPTAB_LIB_WIDEN);
13933 mem = change_address (mem, SImode, align);
13934 set_mem_align (mem, 32);
13935 MEM_VOLATILE_P (mem) = 1;
13937 wdst = gen_reg_rtx (SImode);
13938 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
13939 oldval, newval, mem));
13941 /* Shift the result back. */
13942 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
13944 emit_move_insn (dst, gen_lowpart (mode, wdst));
13947 void
13948 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
13949 rtx oldval, rtx newval, rtx mem,
13950 rtx scratch)
13952 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13954 emit_insn (gen_memory_barrier ());
13955 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13956 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13957 emit_label (XEXP (label1, 0));
13959 emit_load_locked (SImode, scratch, mem);
13961 /* Mask subword within loaded value for comparison with oldval.
13962 Use UNSPEC_AND to avoid clobber.*/
13963 emit_insn (gen_rtx_SET (SImode, dest,
13964 gen_rtx_UNSPEC (SImode,
13965 gen_rtvec (2, scratch, mask),
13966 UNSPEC_AND)));
13968 x = gen_rtx_COMPARE (CCmode, dest, oldval);
13969 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
13971 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13972 emit_unlikely_jump (x, label2);
13974 /* Clear subword within loaded value for insertion of new value. */
13975 emit_insn (gen_rtx_SET (SImode, scratch,
13976 gen_rtx_AND (SImode,
13977 gen_rtx_NOT (SImode, mask), scratch)));
13978 emit_insn (gen_iorsi3 (scratch, scratch, newval));
13979 emit_store_conditional (SImode, cond, mem, scratch);
13981 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13982 emit_unlikely_jump (x, label1);
13984 emit_insn (gen_isync ());
13985 emit_label (XEXP (label2, 0));
13989 /* Emit instructions to move SRC to DST. Called by splitters for
13990 multi-register moves. It will emit at most one instruction for
13991 each register that is accessed; that is, it won't emit li/lis pairs
13992 (or equivalent for 64-bit code). One of SRC or DST must be a hard
13993 register. */
13995 void
13996 rs6000_split_multireg_move (rtx dst, rtx src)
13998 /* The register number of the first register being moved. */
13999 int reg;
14000 /* The mode that is to be moved. */
14001 enum machine_mode mode;
14002 /* The mode that the move is being done in, and its size. */
14003 enum machine_mode reg_mode;
14004 int reg_mode_size;
14005 /* The number of registers that will be moved. */
14006 int nregs;
14008 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
14009 mode = GET_MODE (dst);
14010 nregs = hard_regno_nregs[reg][mode];
14011 if (FP_REGNO_P (reg))
14012 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
14013 else if (ALTIVEC_REGNO_P (reg))
14014 reg_mode = V16QImode;
14015 else if (TARGET_E500_DOUBLE && (mode == TFmode || mode == TDmode))
14016 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
14017 else
14018 reg_mode = word_mode;
14019 reg_mode_size = GET_MODE_SIZE (reg_mode);
14021 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
14023 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
14025 /* Move register range backwards, if we might have destructive
14026 overlap. */
14027 int i;
14028 for (i = nregs - 1; i >= 0; i--)
14029 emit_insn (gen_rtx_SET (VOIDmode,
14030 simplify_gen_subreg (reg_mode, dst, mode,
14031 i * reg_mode_size),
14032 simplify_gen_subreg (reg_mode, src, mode,
14033 i * reg_mode_size)));
14035 else
14037 int i;
14038 int j = -1;
14039 bool used_update = false;
14041 if (MEM_P (src) && INT_REGNO_P (reg))
14043 rtx breg;
14045 if (GET_CODE (XEXP (src, 0)) == PRE_INC
14046 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
14048 rtx delta_rtx;
14049 breg = XEXP (XEXP (src, 0), 0);
14050 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
14051 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
14052 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
14053 emit_insn (TARGET_32BIT
14054 ? gen_addsi3 (breg, breg, delta_rtx)
14055 : gen_adddi3 (breg, breg, delta_rtx));
14056 src = replace_equiv_address (src, breg);
14058 else if (! rs6000_offsettable_memref_p (src))
14060 rtx basereg;
14061 basereg = gen_rtx_REG (Pmode, reg);
14062 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
14063 src = replace_equiv_address (src, basereg);
14066 breg = XEXP (src, 0);
14067 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
14068 breg = XEXP (breg, 0);
14070 /* If the base register we are using to address memory is
14071 also a destination reg, then change that register last. */
14072 if (REG_P (breg)
14073 && REGNO (breg) >= REGNO (dst)
14074 && REGNO (breg) < REGNO (dst) + nregs)
14075 j = REGNO (breg) - REGNO (dst);
14078 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
14080 rtx breg;
14082 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
14083 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
14085 rtx delta_rtx;
14086 breg = XEXP (XEXP (dst, 0), 0);
14087 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
14088 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
14089 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
14091 /* We have to update the breg before doing the store.
14092 Use store with update, if available. */
14094 if (TARGET_UPDATE)
14096 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
14097 emit_insn (TARGET_32BIT
14098 ? (TARGET_POWERPC64
14099 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
14100 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
14101 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
14102 used_update = true;
14104 else
14105 emit_insn (TARGET_32BIT
14106 ? gen_addsi3 (breg, breg, delta_rtx)
14107 : gen_adddi3 (breg, breg, delta_rtx));
14108 dst = replace_equiv_address (dst, breg);
14110 else
14111 gcc_assert (rs6000_offsettable_memref_p (dst));
14114 for (i = 0; i < nregs; i++)
14116 /* Calculate index to next subword. */
14117 ++j;
14118 if (j == nregs)
14119 j = 0;
14121 /* If compiler already emitted move of first word by
14122 store with update, no need to do anything. */
14123 if (j == 0 && used_update)
14124 continue;
14126 emit_insn (gen_rtx_SET (VOIDmode,
14127 simplify_gen_subreg (reg_mode, dst, mode,
14128 j * reg_mode_size),
14129 simplify_gen_subreg (reg_mode, src, mode,
14130 j * reg_mode_size)));
14136 /* This page contains routines that are used to determine what the
14137 function prologue and epilogue code will do and write them out. */
14139 /* Return the first fixed-point register that is required to be
14140 saved. 32 if none. */
14143 first_reg_to_save (void)
14145 int first_reg;
14147 /* Find lowest numbered live register. */
14148 for (first_reg = 13; first_reg <= 31; first_reg++)
14149 if (df_regs_ever_live_p (first_reg)
14150 && (! call_used_regs[first_reg]
14151 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
14152 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14153 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
14154 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
14155 break;
14157 #if TARGET_MACHO
14158 if (flag_pic
14159 && crtl->uses_pic_offset_table
14160 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
14161 return RS6000_PIC_OFFSET_TABLE_REGNUM;
14162 #endif
14164 return first_reg;
14167 /* Similar, for FP regs. */
14170 first_fp_reg_to_save (void)
14172 int first_reg;
14174 /* Find lowest numbered live register. */
14175 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
14176 if (df_regs_ever_live_p (first_reg))
14177 break;
14179 return first_reg;
14182 /* Similar, for AltiVec regs. */
14184 static int
14185 first_altivec_reg_to_save (void)
14187 int i;
14189 /* Stack frame remains as is unless we are in AltiVec ABI. */
14190 if (! TARGET_ALTIVEC_ABI)
14191 return LAST_ALTIVEC_REGNO + 1;
14193 /* On Darwin, the unwind routines are compiled without
14194 TARGET_ALTIVEC, and use save_world to save/restore the
14195 altivec registers when necessary. */
14196 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
14197 && ! TARGET_ALTIVEC)
14198 return FIRST_ALTIVEC_REGNO + 20;
14200 /* Find lowest numbered live register. */
14201 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
14202 if (df_regs_ever_live_p (i))
14203 break;
14205 return i;
14208 /* Return a 32-bit mask of the AltiVec registers we need to set in
14209 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
14210 the 32-bit word is 0. */
14212 static unsigned int
14213 compute_vrsave_mask (void)
14215 unsigned int i, mask = 0;
14217 /* On Darwin, the unwind routines are compiled without
14218 TARGET_ALTIVEC, and use save_world to save/restore the
14219 call-saved altivec registers when necessary. */
14220 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
14221 && ! TARGET_ALTIVEC)
14222 mask |= 0xFFF;
14224 /* First, find out if we use _any_ altivec registers. */
14225 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
14226 if (df_regs_ever_live_p (i))
14227 mask |= ALTIVEC_REG_BIT (i);
14229 if (mask == 0)
14230 return mask;
14232 /* Next, remove the argument registers from the set. These must
14233 be in the VRSAVE mask set by the caller, so we don't need to add
14234 them in again. More importantly, the mask we compute here is
14235 used to generate CLOBBERs in the set_vrsave insn, and we do not
14236 wish the argument registers to die. */
14237 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
14238 mask &= ~ALTIVEC_REG_BIT (i);
14240 /* Similarly, remove the return value from the set. */
14242 bool yes = false;
14243 diddle_return_value (is_altivec_return_reg, &yes);
14244 if (yes)
14245 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
14248 return mask;
14251 /* For a very restricted set of circumstances, we can cut down the
14252 size of prologues/epilogues by calling our own save/restore-the-world
14253 routines. */
14255 static void
14256 compute_save_world_info (rs6000_stack_t *info_ptr)
14258 info_ptr->world_save_p = 1;
14259 info_ptr->world_save_p
14260 = (WORLD_SAVE_P (info_ptr)
14261 && DEFAULT_ABI == ABI_DARWIN
14262 && ! (cfun->calls_setjmp && flag_exceptions)
14263 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
14264 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
14265 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
14266 && info_ptr->cr_save_p);
14268 /* This will not work in conjunction with sibcalls. Make sure there
14269 are none. (This check is expensive, but seldom executed.) */
14270 if (WORLD_SAVE_P (info_ptr))
14272 rtx insn;
14273 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
14274 if ( GET_CODE (insn) == CALL_INSN
14275 && SIBLING_CALL_P (insn))
14277 info_ptr->world_save_p = 0;
14278 break;
14282 if (WORLD_SAVE_P (info_ptr))
14284 /* Even if we're not touching VRsave, make sure there's room on the
14285 stack for it, if it looks like we're calling SAVE_WORLD, which
14286 will attempt to save it. */
14287 info_ptr->vrsave_size = 4;
14289 /* If we are going to save the world, we need to save the link register too. */
14290 info_ptr->lr_save_p = 1;
14292 /* "Save" the VRsave register too if we're saving the world. */
14293 if (info_ptr->vrsave_mask == 0)
14294 info_ptr->vrsave_mask = compute_vrsave_mask ();
14296 /* Because the Darwin register save/restore routines only handle
14297 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
14298 check. */
14299 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
14300 && (info_ptr->first_altivec_reg_save
14301 >= FIRST_SAVED_ALTIVEC_REGNO));
14303 return;
14307 static void
14308 is_altivec_return_reg (rtx reg, void *xyes)
14310 bool *yes = (bool *) xyes;
14311 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
14312 *yes = true;
14316 /* Calculate the stack information for the current function. This is
14317 complicated by having two separate calling sequences, the AIX calling
14318 sequence and the V.4 calling sequence.
14320 AIX (and Darwin/Mac OS X) stack frames look like:
14321 32-bit 64-bit
14322 SP----> +---------------------------------------+
14323 | back chain to caller | 0 0
14324 +---------------------------------------+
14325 | saved CR | 4 8 (8-11)
14326 +---------------------------------------+
14327 | saved LR | 8 16
14328 +---------------------------------------+
14329 | reserved for compilers | 12 24
14330 +---------------------------------------+
14331 | reserved for binders | 16 32
14332 +---------------------------------------+
14333 | saved TOC pointer | 20 40
14334 +---------------------------------------+
14335 | Parameter save area (P) | 24 48
14336 +---------------------------------------+
14337 | Alloca space (A) | 24+P etc.
14338 +---------------------------------------+
14339 | Local variable space (L) | 24+P+A
14340 +---------------------------------------+
14341 | Float/int conversion temporary (X) | 24+P+A+L
14342 +---------------------------------------+
14343 | Save area for AltiVec registers (W) | 24+P+A+L+X
14344 +---------------------------------------+
14345 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
14346 +---------------------------------------+
14347 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
14348 +---------------------------------------+
14349 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
14350 +---------------------------------------+
14351 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
14352 +---------------------------------------+
14353 old SP->| back chain to caller's caller |
14354 +---------------------------------------+
14356 The required alignment for AIX configurations is two words (i.e., 8
14357 or 16 bytes).
14360 V.4 stack frames look like:
14362 SP----> +---------------------------------------+
14363 | back chain to caller | 0
14364 +---------------------------------------+
14365 | caller's saved LR | 4
14366 +---------------------------------------+
14367 | Parameter save area (P) | 8
14368 +---------------------------------------+
14369 | Alloca space (A) | 8+P
14370 +---------------------------------------+
14371 | Varargs save area (V) | 8+P+A
14372 +---------------------------------------+
14373 | Local variable space (L) | 8+P+A+V
14374 +---------------------------------------+
14375 | Float/int conversion temporary (X) | 8+P+A+V+L
14376 +---------------------------------------+
14377 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
14378 +---------------------------------------+
14379 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
14380 +---------------------------------------+
14381 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
14382 +---------------------------------------+
14383 | SPE: area for 64-bit GP registers |
14384 +---------------------------------------+
14385 | SPE alignment padding |
14386 +---------------------------------------+
14387 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
14388 +---------------------------------------+
14389 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
14390 +---------------------------------------+
14391 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
14392 +---------------------------------------+
14393 old SP->| back chain to caller's caller |
14394 +---------------------------------------+
14396 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
14397 given. (But note below and in sysv4.h that we require only 8 and
14398 may round up the size of our stack frame anyways. The historical
14399 reason is early versions of powerpc-linux which didn't properly
14400 align the stack at program startup. A happy side-effect is that
14401 -mno-eabi libraries can be used with -meabi programs.)
14403 The EABI configuration defaults to the V.4 layout. However,
14404 the stack alignment requirements may differ. If -mno-eabi is not
14405 given, the required stack alignment is 8 bytes; if -mno-eabi is
14406 given, the required alignment is 16 bytes. (But see V.4 comment
14407 above.) */
14409 #ifndef ABI_STACK_BOUNDARY
14410 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
14411 #endif
14413 static rs6000_stack_t *
14414 rs6000_stack_info (void)
14416 static rs6000_stack_t info;
14417 rs6000_stack_t *info_ptr = &info;
14418 int reg_size = TARGET_32BIT ? 4 : 8;
14419 int ehrd_size;
14420 int save_align;
14421 int first_gp;
14422 HOST_WIDE_INT non_fixed_size;
14424 memset (&info, 0, sizeof (info));
14426 if (TARGET_SPE)
14428 /* Cache value so we don't rescan instruction chain over and over. */
14429 if (cfun->machine->insn_chain_scanned_p == 0)
14430 cfun->machine->insn_chain_scanned_p
14431 = spe_func_has_64bit_regs_p () + 1;
14432 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
14435 /* Select which calling sequence. */
14436 info_ptr->abi = DEFAULT_ABI;
14438 /* Calculate which registers need to be saved & save area size. */
14439 info_ptr->first_gp_reg_save = first_reg_to_save ();
14440 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
14441 even if it currently looks like we won't. Reload may need it to
14442 get at a constant; if so, it will have already created a constant
14443 pool entry for it. */
14444 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
14445 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
14446 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
14447 && crtl->uses_const_pool
14448 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
14449 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
14450 else
14451 first_gp = info_ptr->first_gp_reg_save;
14453 info_ptr->gp_size = reg_size * (32 - first_gp);
14455 /* For the SPE, we have an additional upper 32-bits on each GPR.
14456 Ideally we should save the entire 64-bits only when the upper
14457 half is used in SIMD instructions. Since we only record
14458 registers live (not the size they are used in), this proves
14459 difficult because we'd have to traverse the instruction chain at
14460 the right time, taking reload into account. This is a real pain,
14461 so we opt to save the GPRs in 64-bits always if but one register
14462 gets used in 64-bits. Otherwise, all the registers in the frame
14463 get saved in 32-bits.
14465 So... since when we save all GPRs (except the SP) in 64-bits, the
14466 traditional GP save area will be empty. */
14467 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
14468 info_ptr->gp_size = 0;
14470 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
14471 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
14473 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
14474 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
14475 - info_ptr->first_altivec_reg_save);
14477 /* Does this function call anything? */
14478 info_ptr->calls_p = (! current_function_is_leaf
14479 || cfun->machine->ra_needs_full_frame);
14481 /* Determine if we need to save the link register. */
14482 if ((DEFAULT_ABI == ABI_AIX
14483 && crtl->profile
14484 && !TARGET_PROFILE_KERNEL)
14485 #ifdef TARGET_RELOCATABLE
14486 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
14487 #endif
14488 || (info_ptr->first_fp_reg_save != 64
14489 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
14490 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
14491 || info_ptr->calls_p
14492 || rs6000_ra_ever_killed ())
14494 info_ptr->lr_save_p = 1;
14495 df_set_regs_ever_live (LR_REGNO, true);
14498 /* Determine if we need to save the condition code registers. */
14499 if (df_regs_ever_live_p (CR2_REGNO)
14500 || df_regs_ever_live_p (CR3_REGNO)
14501 || df_regs_ever_live_p (CR4_REGNO))
14503 info_ptr->cr_save_p = 1;
14504 if (DEFAULT_ABI == ABI_V4)
14505 info_ptr->cr_size = reg_size;
14508 /* If the current function calls __builtin_eh_return, then we need
14509 to allocate stack space for registers that will hold data for
14510 the exception handler. */
14511 if (crtl->calls_eh_return)
14513 unsigned int i;
14514 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
14515 continue;
14517 /* SPE saves EH registers in 64-bits. */
14518 ehrd_size = i * (TARGET_SPE_ABI
14519 && info_ptr->spe_64bit_regs_used != 0
14520 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
14522 else
14523 ehrd_size = 0;
14525 /* Determine various sizes. */
14526 info_ptr->reg_size = reg_size;
14527 info_ptr->fixed_size = RS6000_SAVE_AREA;
14528 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
14529 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
14530 TARGET_ALTIVEC ? 16 : 8);
14531 if (FRAME_GROWS_DOWNWARD)
14532 info_ptr->vars_size
14533 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
14534 + info_ptr->parm_size,
14535 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
14536 - (info_ptr->fixed_size + info_ptr->vars_size
14537 + info_ptr->parm_size);
14539 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
14540 info_ptr->spe_gp_size = 8 * (32 - first_gp);
14541 else
14542 info_ptr->spe_gp_size = 0;
14544 if (TARGET_ALTIVEC_ABI)
14545 info_ptr->vrsave_mask = compute_vrsave_mask ();
14546 else
14547 info_ptr->vrsave_mask = 0;
14549 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
14550 info_ptr->vrsave_size = 4;
14551 else
14552 info_ptr->vrsave_size = 0;
14554 compute_save_world_info (info_ptr);
14556 /* Calculate the offsets. */
14557 switch (DEFAULT_ABI)
14559 case ABI_NONE:
14560 default:
14561 gcc_unreachable ();
14563 case ABI_AIX:
14564 case ABI_DARWIN:
14565 info_ptr->fp_save_offset = - info_ptr->fp_size;
14566 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
14568 if (TARGET_ALTIVEC_ABI)
14570 info_ptr->vrsave_save_offset
14571 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
14573 /* Align stack so vector save area is on a quadword boundary.
14574 The padding goes above the vectors. */
14575 if (info_ptr->altivec_size != 0)
14576 info_ptr->altivec_padding_size
14577 = info_ptr->vrsave_save_offset & 0xF;
14578 else
14579 info_ptr->altivec_padding_size = 0;
14581 info_ptr->altivec_save_offset
14582 = info_ptr->vrsave_save_offset
14583 - info_ptr->altivec_padding_size
14584 - info_ptr->altivec_size;
14585 gcc_assert (info_ptr->altivec_size == 0
14586 || info_ptr->altivec_save_offset % 16 == 0);
14588 /* Adjust for AltiVec case. */
14589 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
14591 else
14592 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
14593 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
14594 info_ptr->lr_save_offset = 2*reg_size;
14595 break;
14597 case ABI_V4:
14598 info_ptr->fp_save_offset = - info_ptr->fp_size;
14599 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
14600 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
14602 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
14604 /* Align stack so SPE GPR save area is aligned on a
14605 double-word boundary. */
14606 if (info_ptr->spe_gp_size != 0)
14607 info_ptr->spe_padding_size
14608 = 8 - (-info_ptr->cr_save_offset % 8);
14609 else
14610 info_ptr->spe_padding_size = 0;
14612 info_ptr->spe_gp_save_offset
14613 = info_ptr->cr_save_offset
14614 - info_ptr->spe_padding_size
14615 - info_ptr->spe_gp_size;
14617 /* Adjust for SPE case. */
14618 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
14620 else if (TARGET_ALTIVEC_ABI)
14622 info_ptr->vrsave_save_offset
14623 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
14625 /* Align stack so vector save area is on a quadword boundary. */
14626 if (info_ptr->altivec_size != 0)
14627 info_ptr->altivec_padding_size
14628 = 16 - (-info_ptr->vrsave_save_offset % 16);
14629 else
14630 info_ptr->altivec_padding_size = 0;
14632 info_ptr->altivec_save_offset
14633 = info_ptr->vrsave_save_offset
14634 - info_ptr->altivec_padding_size
14635 - info_ptr->altivec_size;
14637 /* Adjust for AltiVec case. */
14638 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
14640 else
14641 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
14642 info_ptr->ehrd_offset -= ehrd_size;
14643 info_ptr->lr_save_offset = reg_size;
14644 break;
14647 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
14648 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
14649 + info_ptr->gp_size
14650 + info_ptr->altivec_size
14651 + info_ptr->altivec_padding_size
14652 + info_ptr->spe_gp_size
14653 + info_ptr->spe_padding_size
14654 + ehrd_size
14655 + info_ptr->cr_size
14656 + info_ptr->vrsave_size,
14657 save_align);
14659 non_fixed_size = (info_ptr->vars_size
14660 + info_ptr->parm_size
14661 + info_ptr->save_size);
14663 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
14664 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
14666 /* Determine if we need to allocate any stack frame:
14668 For AIX we need to push the stack if a frame pointer is needed
14669 (because the stack might be dynamically adjusted), if we are
14670 debugging, if we make calls, or if the sum of fp_save, gp_save,
14671 and local variables are more than the space needed to save all
14672 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
14673 + 18*8 = 288 (GPR13 reserved).
14675 For V.4 we don't have the stack cushion that AIX uses, but assume
14676 that the debugger can handle stackless frames. */
14678 if (info_ptr->calls_p)
14679 info_ptr->push_p = 1;
14681 else if (DEFAULT_ABI == ABI_V4)
14682 info_ptr->push_p = non_fixed_size != 0;
14684 else if (frame_pointer_needed)
14685 info_ptr->push_p = 1;
14687 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
14688 info_ptr->push_p = 1;
14690 else
14691 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
14693 /* Zero offsets if we're not saving those registers. */
14694 if (info_ptr->fp_size == 0)
14695 info_ptr->fp_save_offset = 0;
14697 if (info_ptr->gp_size == 0)
14698 info_ptr->gp_save_offset = 0;
14700 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
14701 info_ptr->altivec_save_offset = 0;
14703 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
14704 info_ptr->vrsave_save_offset = 0;
14706 if (! TARGET_SPE_ABI
14707 || info_ptr->spe_64bit_regs_used == 0
14708 || info_ptr->spe_gp_size == 0)
14709 info_ptr->spe_gp_save_offset = 0;
14711 if (! info_ptr->lr_save_p)
14712 info_ptr->lr_save_offset = 0;
14714 if (! info_ptr->cr_save_p)
14715 info_ptr->cr_save_offset = 0;
14717 return info_ptr;
14720 /* Return true if the current function uses any GPRs in 64-bit SIMD
14721 mode. */
14723 static bool
14724 spe_func_has_64bit_regs_p (void)
14726 rtx insns, insn;
14728 /* Functions that save and restore all the call-saved registers will
14729 need to save/restore the registers in 64-bits. */
14730 if (crtl->calls_eh_return
14731 || cfun->calls_setjmp
14732 || crtl->has_nonlocal_goto)
14733 return true;
14735 insns = get_insns ();
14737 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
14739 if (INSN_P (insn))
14741 rtx i;
14743 /* FIXME: This should be implemented with attributes...
14745 (set_attr "spe64" "true")....then,
14746 if (get_spe64(insn)) return true;
14748 It's the only reliable way to do the stuff below. */
14750 i = PATTERN (insn);
14751 if (GET_CODE (i) == SET)
14753 enum machine_mode mode = GET_MODE (SET_SRC (i));
14755 if (SPE_VECTOR_MODE (mode))
14756 return true;
14757 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
14758 || mode == DDmode || mode == TDmode))
14759 return true;
14764 return false;
14767 static void
14768 debug_stack_info (rs6000_stack_t *info)
14770 const char *abi_string;
14772 if (! info)
14773 info = rs6000_stack_info ();
14775 fprintf (stderr, "\nStack information for function %s:\n",
14776 ((current_function_decl && DECL_NAME (current_function_decl))
14777 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
14778 : "<unknown>"));
14780 switch (info->abi)
14782 default: abi_string = "Unknown"; break;
14783 case ABI_NONE: abi_string = "NONE"; break;
14784 case ABI_AIX: abi_string = "AIX"; break;
14785 case ABI_DARWIN: abi_string = "Darwin"; break;
14786 case ABI_V4: abi_string = "V.4"; break;
14789 fprintf (stderr, "\tABI = %5s\n", abi_string);
14791 if (TARGET_ALTIVEC_ABI)
14792 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
14794 if (TARGET_SPE_ABI)
14795 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
14797 if (info->first_gp_reg_save != 32)
14798 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
14800 if (info->first_fp_reg_save != 64)
14801 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
14803 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
14804 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
14805 info->first_altivec_reg_save);
14807 if (info->lr_save_p)
14808 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
14810 if (info->cr_save_p)
14811 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
14813 if (info->vrsave_mask)
14814 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
14816 if (info->push_p)
14817 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
14819 if (info->calls_p)
14820 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
14822 if (info->gp_save_offset)
14823 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
14825 if (info->fp_save_offset)
14826 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
14828 if (info->altivec_save_offset)
14829 fprintf (stderr, "\taltivec_save_offset = %5d\n",
14830 info->altivec_save_offset);
14832 if (info->spe_gp_save_offset)
14833 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
14834 info->spe_gp_save_offset);
14836 if (info->vrsave_save_offset)
14837 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
14838 info->vrsave_save_offset);
14840 if (info->lr_save_offset)
14841 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
14843 if (info->cr_save_offset)
14844 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
14846 if (info->varargs_save_offset)
14847 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
14849 if (info->total_size)
14850 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
14851 info->total_size);
14853 if (info->vars_size)
14854 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
14855 info->vars_size);
14857 if (info->parm_size)
14858 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
14860 if (info->fixed_size)
14861 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
14863 if (info->gp_size)
14864 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
14866 if (info->spe_gp_size)
14867 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
14869 if (info->fp_size)
14870 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
14872 if (info->altivec_size)
14873 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
14875 if (info->vrsave_size)
14876 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
14878 if (info->altivec_padding_size)
14879 fprintf (stderr, "\taltivec_padding_size= %5d\n",
14880 info->altivec_padding_size);
14882 if (info->spe_padding_size)
14883 fprintf (stderr, "\tspe_padding_size = %5d\n",
14884 info->spe_padding_size);
14886 if (info->cr_size)
14887 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
14889 if (info->save_size)
14890 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
14892 if (info->reg_size != 4)
14893 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
14895 fprintf (stderr, "\n");
14899 rs6000_return_addr (int count, rtx frame)
14901 /* Currently we don't optimize very well between prolog and body
14902 code and for PIC code the code can be actually quite bad, so
14903 don't try to be too clever here. */
14904 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
14906 cfun->machine->ra_needs_full_frame = 1;
14908 return
14909 gen_rtx_MEM
14910 (Pmode,
14911 memory_address
14912 (Pmode,
14913 plus_constant (copy_to_reg
14914 (gen_rtx_MEM (Pmode,
14915 memory_address (Pmode, frame))),
14916 RETURN_ADDRESS_OFFSET)));
14919 cfun->machine->ra_need_lr = 1;
14920 return get_hard_reg_initial_val (Pmode, LR_REGNO);
14923 /* Say whether a function is a candidate for sibcall handling or not.
14924 We do not allow indirect calls to be optimized into sibling calls.
14925 Also, we can't do it if there are any vector parameters; there's
14926 nowhere to put the VRsave code so it works; note that functions with
14927 vector parameters are required to have a prototype, so the argument
14928 type info must be available here. (The tail recursion case can work
14929 with vector parameters, but there's no way to distinguish here.) */
14930 static bool
14931 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
14933 tree type;
14934 if (decl)
14936 if (TARGET_ALTIVEC_VRSAVE)
14938 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
14939 type; type = TREE_CHAIN (type))
14941 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
14942 return false;
14945 if (DEFAULT_ABI == ABI_DARWIN
14946 || ((*targetm.binds_local_p) (decl)
14947 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
14949 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
14951 if (!lookup_attribute ("longcall", attr_list)
14952 || lookup_attribute ("shortcall", attr_list))
14953 return true;
14956 return false;
14959 /* NULL if INSN insn is valid within a low-overhead loop.
14960 Otherwise return why doloop cannot be applied.
14961 PowerPC uses the COUNT register for branch on table instructions. */
14963 static const char *
14964 rs6000_invalid_within_doloop (const_rtx insn)
14966 if (CALL_P (insn))
14967 return "Function call in the loop.";
14969 if (JUMP_P (insn)
14970 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
14971 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
14972 return "Computed branch in the loop.";
14974 return NULL;
14977 static int
14978 rs6000_ra_ever_killed (void)
14980 rtx top;
14981 rtx reg;
14982 rtx insn;
14984 if (crtl->is_thunk)
14985 return 0;
14987 /* regs_ever_live has LR marked as used if any sibcalls are present,
14988 but this should not force saving and restoring in the
14989 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
14990 clobbers LR, so that is inappropriate. */
14992 /* Also, the prologue can generate a store into LR that
14993 doesn't really count, like this:
14995 move LR->R0
14996 bcl to set PIC register
14997 move LR->R31
14998 move R0->LR
15000 When we're called from the epilogue, we need to avoid counting
15001 this as a store. */
15003 push_topmost_sequence ();
15004 top = get_insns ();
15005 pop_topmost_sequence ();
15006 reg = gen_rtx_REG (Pmode, LR_REGNO);
15008 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
15010 if (INSN_P (insn))
15012 if (CALL_P (insn))
15014 if (!SIBLING_CALL_P (insn))
15015 return 1;
15017 else if (find_regno_note (insn, REG_INC, LR_REGNO))
15018 return 1;
15019 else if (set_of (reg, insn) != NULL_RTX
15020 && !prologue_epilogue_contains (insn))
15021 return 1;
15024 return 0;
15027 /* Emit instructions needed to load the TOC register.
15028 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
15029 a constant pool; or for SVR4 -fpic. */
15031 void
15032 rs6000_emit_load_toc_table (int fromprolog)
15034 rtx dest;
15035 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
15037 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
15039 char buf[30];
15040 rtx lab, tmp1, tmp2, got;
15042 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
15043 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
15044 if (flag_pic == 2)
15045 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
15046 else
15047 got = rs6000_got_sym ();
15048 tmp1 = tmp2 = dest;
15049 if (!fromprolog)
15051 tmp1 = gen_reg_rtx (Pmode);
15052 tmp2 = gen_reg_rtx (Pmode);
15054 emit_insn (gen_load_toc_v4_PIC_1 (lab));
15055 emit_move_insn (tmp1,
15056 gen_rtx_REG (Pmode, LR_REGNO));
15057 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
15058 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
15060 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
15062 emit_insn (gen_load_toc_v4_pic_si ());
15063 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
15065 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
15067 char buf[30];
15068 rtx temp0 = (fromprolog
15069 ? gen_rtx_REG (Pmode, 0)
15070 : gen_reg_rtx (Pmode));
15072 if (fromprolog)
15074 rtx symF, symL;
15076 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
15077 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
15079 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
15080 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
15082 emit_insn (gen_load_toc_v4_PIC_1 (symF));
15083 emit_move_insn (dest,
15084 gen_rtx_REG (Pmode, LR_REGNO));
15085 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
15087 else
15089 rtx tocsym;
15091 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
15092 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
15093 emit_move_insn (dest,
15094 gen_rtx_REG (Pmode, LR_REGNO));
15095 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
15097 emit_insn (gen_addsi3 (dest, temp0, dest));
15099 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
15101 /* This is for AIX code running in non-PIC ELF32. */
15102 char buf[30];
15103 rtx realsym;
15104 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
15105 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
15107 emit_insn (gen_elf_high (dest, realsym));
15108 emit_insn (gen_elf_low (dest, dest, realsym));
15110 else
15112 gcc_assert (DEFAULT_ABI == ABI_AIX);
15114 if (TARGET_32BIT)
15115 emit_insn (gen_load_toc_aix_si (dest));
15116 else
15117 emit_insn (gen_load_toc_aix_di (dest));
15121 /* Emit instructions to restore the link register after determining where
15122 its value has been stored. */
15124 void
15125 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
15127 rs6000_stack_t *info = rs6000_stack_info ();
15128 rtx operands[2];
15130 operands[0] = source;
15131 operands[1] = scratch;
15133 if (info->lr_save_p)
15135 rtx frame_rtx = stack_pointer_rtx;
15136 HOST_WIDE_INT sp_offset = 0;
15137 rtx tmp;
15139 if (frame_pointer_needed
15140 || cfun->calls_alloca
15141 || info->total_size > 32767)
15143 tmp = gen_frame_mem (Pmode, frame_rtx);
15144 emit_move_insn (operands[1], tmp);
15145 frame_rtx = operands[1];
15147 else if (info->push_p)
15148 sp_offset = info->total_size;
15150 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
15151 tmp = gen_frame_mem (Pmode, tmp);
15152 emit_move_insn (tmp, operands[0]);
15154 else
15155 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
15158 static GTY(()) alias_set_type set = -1;
15160 alias_set_type
15161 get_TOC_alias_set (void)
15163 if (set == -1)
15164 set = new_alias_set ();
15165 return set;
15168 /* This returns nonzero if the current function uses the TOC. This is
15169 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
15170 is generated by the ABI_V4 load_toc_* patterns. */
15171 #if TARGET_ELF
15172 static int
15173 uses_TOC (void)
15175 rtx insn;
15177 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
15178 if (INSN_P (insn))
15180 rtx pat = PATTERN (insn);
15181 int i;
15183 if (GET_CODE (pat) == PARALLEL)
15184 for (i = 0; i < XVECLEN (pat, 0); i++)
15186 rtx sub = XVECEXP (pat, 0, i);
15187 if (GET_CODE (sub) == USE)
15189 sub = XEXP (sub, 0);
15190 if (GET_CODE (sub) == UNSPEC
15191 && XINT (sub, 1) == UNSPEC_TOC)
15192 return 1;
15196 return 0;
15198 #endif
15201 create_TOC_reference (rtx symbol)
15203 if (!can_create_pseudo_p ())
15204 df_set_regs_ever_live (TOC_REGISTER, true);
15205 return gen_rtx_PLUS (Pmode,
15206 gen_rtx_REG (Pmode, TOC_REGISTER),
15207 gen_rtx_CONST (Pmode,
15208 gen_rtx_MINUS (Pmode, symbol,
15209 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
15212 /* If _Unwind_* has been called from within the same module,
15213 toc register is not guaranteed to be saved to 40(1) on function
15214 entry. Save it there in that case. */
15216 void
15217 rs6000_aix_emit_builtin_unwind_init (void)
15219 rtx mem;
15220 rtx stack_top = gen_reg_rtx (Pmode);
15221 rtx opcode_addr = gen_reg_rtx (Pmode);
15222 rtx opcode = gen_reg_rtx (SImode);
15223 rtx tocompare = gen_reg_rtx (SImode);
15224 rtx no_toc_save_needed = gen_label_rtx ();
15226 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
15227 emit_move_insn (stack_top, mem);
15229 mem = gen_frame_mem (Pmode,
15230 gen_rtx_PLUS (Pmode, stack_top,
15231 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
15232 emit_move_insn (opcode_addr, mem);
15233 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
15234 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
15235 : 0xE8410028, SImode));
15237 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
15238 SImode, NULL_RTX, NULL_RTX,
15239 no_toc_save_needed);
15241 mem = gen_frame_mem (Pmode,
15242 gen_rtx_PLUS (Pmode, stack_top,
15243 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
15244 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
15245 emit_label (no_toc_save_needed);
15248 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
15249 and the change to the stack pointer. */
15251 static void
15252 rs6000_emit_stack_tie (void)
15254 rtx mem = gen_frame_mem (BLKmode,
15255 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
15257 emit_insn (gen_stack_tie (mem));
15260 /* Emit the correct code for allocating stack space, as insns.
15261 If COPY_R12, make sure a copy of the old frame is left in r12.
15262 The generated code may use hard register 0 as a temporary. */
15264 static void
15265 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
15267 rtx insn;
15268 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
15269 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
15270 rtx todec = gen_int_mode (-size, Pmode);
15272 if (INTVAL (todec) != -size)
15274 warning (0, "stack frame too large");
15275 emit_insn (gen_trap ());
15276 return;
15279 if (crtl->limit_stack)
15281 if (REG_P (stack_limit_rtx)
15282 && REGNO (stack_limit_rtx) > 1
15283 && REGNO (stack_limit_rtx) <= 31)
15285 emit_insn (TARGET_32BIT
15286 ? gen_addsi3 (tmp_reg,
15287 stack_limit_rtx,
15288 GEN_INT (size))
15289 : gen_adddi3 (tmp_reg,
15290 stack_limit_rtx,
15291 GEN_INT (size)));
15293 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
15294 const0_rtx));
15296 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
15297 && TARGET_32BIT
15298 && DEFAULT_ABI == ABI_V4)
15300 rtx toload = gen_rtx_CONST (VOIDmode,
15301 gen_rtx_PLUS (Pmode,
15302 stack_limit_rtx,
15303 GEN_INT (size)));
15305 emit_insn (gen_elf_high (tmp_reg, toload));
15306 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
15307 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
15308 const0_rtx));
15310 else
15311 warning (0, "stack limit expression is not supported");
15314 if (copy_r12 || ! TARGET_UPDATE)
15315 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
15317 if (TARGET_UPDATE)
15319 if (size > 32767)
15321 /* Need a note here so that try_split doesn't get confused. */
15322 if (get_last_insn () == NULL_RTX)
15323 emit_note (NOTE_INSN_DELETED);
15324 insn = emit_move_insn (tmp_reg, todec);
15325 try_split (PATTERN (insn), insn, 0);
15326 todec = tmp_reg;
15329 insn = emit_insn (TARGET_32BIT
15330 ? gen_movsi_update (stack_reg, stack_reg,
15331 todec, stack_reg)
15332 : gen_movdi_di_update (stack_reg, stack_reg,
15333 todec, stack_reg));
15335 else
15337 insn = emit_insn (TARGET_32BIT
15338 ? gen_addsi3 (stack_reg, stack_reg, todec)
15339 : gen_adddi3 (stack_reg, stack_reg, todec));
15340 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
15341 gen_rtx_REG (Pmode, 12));
15344 RTX_FRAME_RELATED_P (insn) = 1;
15345 REG_NOTES (insn) =
15346 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15347 gen_rtx_SET (VOIDmode, stack_reg,
15348 gen_rtx_PLUS (Pmode, stack_reg,
15349 GEN_INT (-size))),
15350 REG_NOTES (insn));
15353 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
15354 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
15355 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
15356 deduce these equivalences by itself so it wasn't necessary to hold
15357 its hand so much. */
15359 static void
15360 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
15361 rtx reg2, rtx rreg)
15363 rtx real, temp;
15365 /* copy_rtx will not make unique copies of registers, so we need to
15366 ensure we don't have unwanted sharing here. */
15367 if (reg == reg2)
15368 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
15370 if (reg == rreg)
15371 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
15373 real = copy_rtx (PATTERN (insn));
15375 if (reg2 != NULL_RTX)
15376 real = replace_rtx (real, reg2, rreg);
15378 real = replace_rtx (real, reg,
15379 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
15380 STACK_POINTER_REGNUM),
15381 GEN_INT (val)));
15383 /* We expect that 'real' is either a SET or a PARALLEL containing
15384 SETs (and possibly other stuff). In a PARALLEL, all the SETs
15385 are important so they all have to be marked RTX_FRAME_RELATED_P. */
15387 if (GET_CODE (real) == SET)
15389 rtx set = real;
15391 temp = simplify_rtx (SET_SRC (set));
15392 if (temp)
15393 SET_SRC (set) = temp;
15394 temp = simplify_rtx (SET_DEST (set));
15395 if (temp)
15396 SET_DEST (set) = temp;
15397 if (GET_CODE (SET_DEST (set)) == MEM)
15399 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
15400 if (temp)
15401 XEXP (SET_DEST (set), 0) = temp;
15404 else
15406 int i;
15408 gcc_assert (GET_CODE (real) == PARALLEL);
15409 for (i = 0; i < XVECLEN (real, 0); i++)
15410 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
15412 rtx set = XVECEXP (real, 0, i);
15414 temp = simplify_rtx (SET_SRC (set));
15415 if (temp)
15416 SET_SRC (set) = temp;
15417 temp = simplify_rtx (SET_DEST (set));
15418 if (temp)
15419 SET_DEST (set) = temp;
15420 if (GET_CODE (SET_DEST (set)) == MEM)
15422 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
15423 if (temp)
15424 XEXP (SET_DEST (set), 0) = temp;
15426 RTX_FRAME_RELATED_P (set) = 1;
15430 RTX_FRAME_RELATED_P (insn) = 1;
15431 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15432 real,
15433 REG_NOTES (insn));
15436 /* Returns an insn that has a vrsave set operation with the
15437 appropriate CLOBBERs. */
15439 static rtx
15440 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
15442 int nclobs, i;
15443 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
15444 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
15446 clobs[0]
15447 = gen_rtx_SET (VOIDmode,
15448 vrsave,
15449 gen_rtx_UNSPEC_VOLATILE (SImode,
15450 gen_rtvec (2, reg, vrsave),
15451 UNSPECV_SET_VRSAVE));
15453 nclobs = 1;
15455 /* We need to clobber the registers in the mask so the scheduler
15456 does not move sets to VRSAVE before sets of AltiVec registers.
15458 However, if the function receives nonlocal gotos, reload will set
15459 all call saved registers live. We will end up with:
15461 (set (reg 999) (mem))
15462 (parallel [ (set (reg vrsave) (unspec blah))
15463 (clobber (reg 999))])
15465 The clobber will cause the store into reg 999 to be dead, and
15466 flow will attempt to delete an epilogue insn. In this case, we
15467 need an unspec use/set of the register. */
15469 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
15470 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
15472 if (!epiloguep || call_used_regs [i])
15473 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
15474 gen_rtx_REG (V4SImode, i));
15475 else
15477 rtx reg = gen_rtx_REG (V4SImode, i);
15479 clobs[nclobs++]
15480 = gen_rtx_SET (VOIDmode,
15481 reg,
15482 gen_rtx_UNSPEC (V4SImode,
15483 gen_rtvec (1, reg), 27));
15487 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
15489 for (i = 0; i < nclobs; ++i)
15490 XVECEXP (insn, 0, i) = clobs[i];
15492 return insn;
15495 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
15496 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
15498 static void
15499 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
15500 unsigned int regno, int offset, HOST_WIDE_INT total_size)
15502 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
15503 rtx replacea, replaceb;
15505 int_rtx = GEN_INT (offset);
15507 /* Some cases that need register indexed addressing. */
15508 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
15509 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode))
15510 || (TARGET_SPE_ABI
15511 && SPE_VECTOR_MODE (mode)
15512 && !SPE_CONST_OFFSET_OK (offset)))
15514 /* Whomever calls us must make sure r11 is available in the
15515 flow path of instructions in the prologue. */
15516 offset_rtx = gen_rtx_REG (Pmode, 11);
15517 emit_move_insn (offset_rtx, int_rtx);
15519 replacea = offset_rtx;
15520 replaceb = int_rtx;
15522 else
15524 offset_rtx = int_rtx;
15525 replacea = NULL_RTX;
15526 replaceb = NULL_RTX;
15529 reg = gen_rtx_REG (mode, regno);
15530 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
15531 mem = gen_frame_mem (mode, addr);
15533 insn = emit_move_insn (mem, reg);
15535 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
15538 /* Emit an offset memory reference suitable for a frame store, while
15539 converting to a valid addressing mode. */
15541 static rtx
15542 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
15544 rtx int_rtx, offset_rtx;
15546 int_rtx = GEN_INT (offset);
15548 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
15549 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode)))
15551 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
15552 emit_move_insn (offset_rtx, int_rtx);
15554 else
15555 offset_rtx = int_rtx;
15557 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
15560 /* Look for user-defined global regs. We should not save and restore these,
15561 and cannot use stmw/lmw if there are any in its range. */
15563 static bool
15564 no_global_regs_above (int first_greg)
15566 int i;
15567 for (i = 0; i < 32 - first_greg; i++)
15568 if (global_regs[first_greg + i])
15569 return false;
15570 return true;
15573 #ifndef TARGET_FIX_AND_CONTINUE
15574 #define TARGET_FIX_AND_CONTINUE 0
15575 #endif
15577 /* Determine whether the gp REG is really used. */
15579 static bool
15580 rs6000_reg_live_or_pic_offset_p (int reg)
15582 return ((df_regs_ever_live_p (reg)
15583 && (!call_used_regs[reg]
15584 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
15585 && TARGET_TOC && TARGET_MINIMAL_TOC)))
15586 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
15587 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
15588 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
15591 /* Emit function prologue as insns. */
15593 void
15594 rs6000_emit_prologue (void)
15596 rs6000_stack_t *info = rs6000_stack_info ();
15597 enum machine_mode reg_mode = Pmode;
15598 int reg_size = TARGET_32BIT ? 4 : 8;
15599 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
15600 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
15601 rtx frame_reg_rtx = sp_reg_rtx;
15602 rtx cr_save_rtx = NULL_RTX;
15603 rtx insn;
15604 int saving_FPRs_inline;
15605 int using_store_multiple;
15606 HOST_WIDE_INT sp_offset = 0;
15608 if (TARGET_FIX_AND_CONTINUE)
15610 /* gdb on darwin arranges to forward a function from the old
15611 address by modifying the first 5 instructions of the function
15612 to branch to the overriding function. This is necessary to
15613 permit function pointers that point to the old function to
15614 actually forward to the new function. */
15615 emit_insn (gen_nop ());
15616 emit_insn (gen_nop ());
15617 emit_insn (gen_nop ());
15618 emit_insn (gen_nop ());
15619 emit_insn (gen_nop ());
15622 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15624 reg_mode = V2SImode;
15625 reg_size = 8;
15628 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
15629 && (!TARGET_SPE_ABI
15630 || info->spe_64bit_regs_used == 0)
15631 && info->first_gp_reg_save < 31
15632 && no_global_regs_above (info->first_gp_reg_save));
15633 saving_FPRs_inline = (info->first_fp_reg_save == 64
15634 || FP_SAVE_INLINE (info->first_fp_reg_save)
15635 || crtl->calls_eh_return
15636 || cfun->machine->ra_need_lr);
15638 /* For V.4, update stack before we do any saving and set back pointer. */
15639 if (! WORLD_SAVE_P (info)
15640 && info->push_p
15641 && (DEFAULT_ABI == ABI_V4
15642 || crtl->calls_eh_return))
15644 if (info->total_size < 32767)
15645 sp_offset = info->total_size;
15646 else
15647 frame_reg_rtx = frame_ptr_rtx;
15648 rs6000_emit_allocate_stack (info->total_size,
15649 (frame_reg_rtx != sp_reg_rtx
15650 && (info->cr_save_p
15651 || info->lr_save_p
15652 || info->first_fp_reg_save < 64
15653 || info->first_gp_reg_save < 32
15654 )));
15655 if (frame_reg_rtx != sp_reg_rtx)
15656 rs6000_emit_stack_tie ();
15659 /* Handle world saves specially here. */
15660 if (WORLD_SAVE_P (info))
15662 int i, j, sz;
15663 rtx treg;
15664 rtvec p;
15665 rtx reg0;
15667 /* save_world expects lr in r0. */
15668 reg0 = gen_rtx_REG (Pmode, 0);
15669 if (info->lr_save_p)
15671 insn = emit_move_insn (reg0,
15672 gen_rtx_REG (Pmode, LR_REGNO));
15673 RTX_FRAME_RELATED_P (insn) = 1;
15676 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
15677 assumptions about the offsets of various bits of the stack
15678 frame. */
15679 gcc_assert (info->gp_save_offset == -220
15680 && info->fp_save_offset == -144
15681 && info->lr_save_offset == 8
15682 && info->cr_save_offset == 4
15683 && info->push_p
15684 && info->lr_save_p
15685 && (!crtl->calls_eh_return
15686 || info->ehrd_offset == -432)
15687 && info->vrsave_save_offset == -224
15688 && info->altivec_save_offset == -416);
15690 treg = gen_rtx_REG (SImode, 11);
15691 emit_move_insn (treg, GEN_INT (-info->total_size));
15693 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
15694 in R11. It also clobbers R12, so beware! */
15696 /* Preserve CR2 for save_world prologues */
15697 sz = 5;
15698 sz += 32 - info->first_gp_reg_save;
15699 sz += 64 - info->first_fp_reg_save;
15700 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
15701 p = rtvec_alloc (sz);
15702 j = 0;
15703 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
15704 gen_rtx_REG (SImode,
15705 LR_REGNO));
15706 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
15707 gen_rtx_SYMBOL_REF (Pmode,
15708 "*save_world"));
15709 /* We do floats first so that the instruction pattern matches
15710 properly. */
15711 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15713 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15714 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15715 GEN_INT (info->fp_save_offset
15716 + sp_offset + 8 * i));
15717 rtx mem = gen_frame_mem (DFmode, addr);
15719 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15721 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
15723 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
15724 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15725 GEN_INT (info->altivec_save_offset
15726 + sp_offset + 16 * i));
15727 rtx mem = gen_frame_mem (V4SImode, addr);
15729 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15731 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15733 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15734 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15735 GEN_INT (info->gp_save_offset
15736 + sp_offset + reg_size * i));
15737 rtx mem = gen_frame_mem (reg_mode, addr);
15739 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15743 /* CR register traditionally saved as CR2. */
15744 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
15745 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15746 GEN_INT (info->cr_save_offset
15747 + sp_offset));
15748 rtx mem = gen_frame_mem (reg_mode, addr);
15750 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15752 /* Explain about use of R0. */
15753 if (info->lr_save_p)
15755 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15756 GEN_INT (info->lr_save_offset
15757 + sp_offset));
15758 rtx mem = gen_frame_mem (reg_mode, addr);
15760 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
15762 /* Explain what happens to the stack pointer. */
15764 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
15765 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
15768 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15769 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15770 treg, GEN_INT (-info->total_size));
15771 sp_offset = info->total_size;
15774 /* If we use the link register, get it into r0. */
15775 if (!WORLD_SAVE_P (info) && info->lr_save_p)
15777 rtx addr, reg, mem;
15779 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
15780 gen_rtx_REG (Pmode, LR_REGNO));
15781 RTX_FRAME_RELATED_P (insn) = 1;
15783 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15784 GEN_INT (info->lr_save_offset + sp_offset));
15785 reg = gen_rtx_REG (Pmode, 0);
15786 mem = gen_rtx_MEM (Pmode, addr);
15787 /* This should not be of rs6000_sr_alias_set, because of
15788 __builtin_return_address. */
15790 insn = emit_move_insn (mem, reg);
15791 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15792 NULL_RTX, NULL_RTX);
15795 /* If we need to save CR, put it into r12. */
15796 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
15798 rtx set;
15800 cr_save_rtx = gen_rtx_REG (SImode, 12);
15801 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
15802 RTX_FRAME_RELATED_P (insn) = 1;
15803 /* Now, there's no way that dwarf2out_frame_debug_expr is going
15804 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
15805 But that's OK. All we have to do is specify that _one_ condition
15806 code register is saved in this stack slot. The thrower's epilogue
15807 will then restore all the call-saved registers.
15808 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
15809 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
15810 gen_rtx_REG (SImode, CR2_REGNO));
15811 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15812 set,
15813 REG_NOTES (insn));
15816 /* Do any required saving of fpr's. If only one or two to save, do
15817 it ourselves. Otherwise, call function. */
15818 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
15820 int i;
15821 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15822 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
15823 && ! call_used_regs[info->first_fp_reg_save+i]))
15824 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
15825 info->first_fp_reg_save + i,
15826 info->fp_save_offset + sp_offset + 8 * i,
15827 info->total_size);
15829 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
15831 int i;
15832 char rname[30];
15833 const char *alloc_rname;
15834 rtvec p;
15835 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
15837 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
15838 gen_rtx_REG (Pmode,
15839 LR_REGNO));
15840 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
15841 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
15842 alloc_rname = ggc_strdup (rname);
15843 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
15844 gen_rtx_SYMBOL_REF (Pmode,
15845 alloc_rname));
15846 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15848 rtx addr, reg, mem;
15849 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15850 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15851 GEN_INT (info->fp_save_offset
15852 + sp_offset + 8*i));
15853 mem = gen_frame_mem (DFmode, addr);
15855 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
15857 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15858 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15859 NULL_RTX, NULL_RTX);
15862 /* Save GPRs. This is done as a PARALLEL if we are using
15863 the store-multiple instructions. */
15864 if (!WORLD_SAVE_P (info) && using_store_multiple)
15866 rtvec p;
15867 int i;
15868 p = rtvec_alloc (32 - info->first_gp_reg_save);
15869 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15871 rtx addr, reg, mem;
15872 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15873 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15874 GEN_INT (info->gp_save_offset
15875 + sp_offset
15876 + reg_size * i));
15877 mem = gen_frame_mem (reg_mode, addr);
15879 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
15881 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15882 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15883 NULL_RTX, NULL_RTX);
15885 else if (!WORLD_SAVE_P (info)
15886 && TARGET_SPE_ABI
15887 && info->spe_64bit_regs_used != 0
15888 && info->first_gp_reg_save != 32)
15890 int i;
15891 rtx spe_save_area_ptr;
15892 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
15893 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
15894 && !call_used_regs[STATIC_CHAIN_REGNUM]);
15896 /* Determine whether we can address all of the registers that need
15897 to be saved with an offset from the stack pointer that fits in
15898 the small const field for SPE memory instructions. */
15899 int spe_regs_addressable_via_sp
15900 = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
15901 + (32 - info->first_gp_reg_save - 1) * reg_size);
15902 int spe_offset;
15904 if (spe_regs_addressable_via_sp)
15906 spe_save_area_ptr = frame_reg_rtx;
15907 spe_offset = info->spe_gp_save_offset + sp_offset;
15909 else
15911 /* Make r11 point to the start of the SPE save area. We need
15912 to be careful here if r11 is holding the static chain. If
15913 it is, then temporarily save it in r0. We would use r0 as
15914 our base register here, but using r0 as a base register in
15915 loads and stores means something different from what we
15916 would like. */
15917 if (using_static_chain_p)
15919 rtx r0 = gen_rtx_REG (Pmode, 0);
15921 gcc_assert (info->first_gp_reg_save > 11);
15923 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
15926 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
15927 emit_insn (gen_addsi3 (spe_save_area_ptr, frame_reg_rtx,
15928 GEN_INT (info->spe_gp_save_offset + sp_offset)));
15930 spe_offset = 0;
15933 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15934 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
15936 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15937 rtx offset, addr, mem;
15939 /* We're doing all this to ensure that the offset fits into
15940 the immediate offset of 'evstdd'. */
15941 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
15943 offset = GEN_INT (reg_size * i + spe_offset);
15944 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
15945 mem = gen_rtx_MEM (V2SImode, addr);
15947 insn = emit_move_insn (mem, reg);
15949 rs6000_frame_related (insn, spe_save_area_ptr,
15950 info->spe_gp_save_offset
15951 + sp_offset + reg_size * i,
15952 offset, const0_rtx);
15955 /* Move the static chain pointer back. */
15956 if (using_static_chain_p && !spe_regs_addressable_via_sp)
15957 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
15959 else if (!WORLD_SAVE_P (info))
15961 int i;
15962 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15963 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
15965 rtx addr, reg, mem;
15966 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15968 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15969 GEN_INT (info->gp_save_offset
15970 + sp_offset
15971 + reg_size * i));
15972 mem = gen_frame_mem (reg_mode, addr);
15974 insn = emit_move_insn (mem, reg);
15975 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15976 NULL_RTX, NULL_RTX);
15980 /* ??? There's no need to emit actual instructions here, but it's the
15981 easiest way to get the frame unwind information emitted. */
15982 if (crtl->calls_eh_return)
15984 unsigned int i, regno;
15986 /* In AIX ABI we need to pretend we save r2 here. */
15987 if (TARGET_AIX)
15989 rtx addr, reg, mem;
15991 reg = gen_rtx_REG (reg_mode, 2);
15992 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15993 GEN_INT (sp_offset + 5 * reg_size));
15994 mem = gen_frame_mem (reg_mode, addr);
15996 insn = emit_move_insn (mem, reg);
15997 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15998 NULL_RTX, NULL_RTX);
15999 PATTERN (insn) = gen_blockage ();
16002 for (i = 0; ; ++i)
16004 regno = EH_RETURN_DATA_REGNO (i);
16005 if (regno == INVALID_REGNUM)
16006 break;
16008 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
16009 info->ehrd_offset + sp_offset
16010 + reg_size * (int) i,
16011 info->total_size);
16015 /* Save CR if we use any that must be preserved. */
16016 if (!WORLD_SAVE_P (info) && info->cr_save_p)
16018 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16019 GEN_INT (info->cr_save_offset + sp_offset));
16020 rtx mem = gen_frame_mem (SImode, addr);
16021 /* See the large comment above about why CR2_REGNO is used. */
16022 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
16024 /* If r12 was used to hold the original sp, copy cr into r0 now
16025 that it's free. */
16026 if (REGNO (frame_reg_rtx) == 12)
16028 rtx set;
16030 cr_save_rtx = gen_rtx_REG (SImode, 0);
16031 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
16032 RTX_FRAME_RELATED_P (insn) = 1;
16033 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
16034 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
16035 set,
16036 REG_NOTES (insn));
16039 insn = emit_move_insn (mem, cr_save_rtx);
16041 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
16042 NULL_RTX, NULL_RTX);
16045 /* Update stack and set back pointer unless this is V.4,
16046 for which it was done previously. */
16047 if (!WORLD_SAVE_P (info) && info->push_p
16048 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
16050 if (info->total_size < 32767)
16051 sp_offset = info->total_size;
16052 else
16053 frame_reg_rtx = frame_ptr_rtx;
16054 rs6000_emit_allocate_stack (info->total_size,
16055 (frame_reg_rtx != sp_reg_rtx
16056 && ((info->altivec_size != 0)
16057 || (info->vrsave_mask != 0)
16058 )));
16059 if (frame_reg_rtx != sp_reg_rtx)
16060 rs6000_emit_stack_tie ();
16063 /* Set frame pointer, if needed. */
16064 if (frame_pointer_needed)
16066 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
16067 sp_reg_rtx);
16068 RTX_FRAME_RELATED_P (insn) = 1;
16071 /* Save AltiVec registers if needed. Save here because the red zone does
16072 not include AltiVec registers. */
16073 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
16075 int i;
16077 /* There should be a non inline version of this, for when we
16078 are saving lots of vector registers. */
16079 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
16080 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
16082 rtx areg, savereg, mem;
16083 int offset;
16085 offset = info->altivec_save_offset + sp_offset
16086 + 16 * (i - info->first_altivec_reg_save);
16088 savereg = gen_rtx_REG (V4SImode, i);
16090 areg = gen_rtx_REG (Pmode, 0);
16091 emit_move_insn (areg, GEN_INT (offset));
16093 /* AltiVec addressing mode is [reg+reg]. */
16094 mem = gen_frame_mem (V4SImode,
16095 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
16097 insn = emit_move_insn (mem, savereg);
16099 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
16100 areg, GEN_INT (offset));
16104 /* VRSAVE is a bit vector representing which AltiVec registers
16105 are used. The OS uses this to determine which vector
16106 registers to save on a context switch. We need to save
16107 VRSAVE on the stack frame, add whatever AltiVec registers we
16108 used in this function, and do the corresponding magic in the
16109 epilogue. */
16111 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
16112 && info->vrsave_mask != 0)
16114 rtx reg, mem, vrsave;
16115 int offset;
16117 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
16118 as frame_reg_rtx and r11 as the static chain pointer for
16119 nested functions. */
16120 reg = gen_rtx_REG (SImode, 0);
16121 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
16122 if (TARGET_MACHO)
16123 emit_insn (gen_get_vrsave_internal (reg));
16124 else
16125 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
16127 if (!WORLD_SAVE_P (info))
16129 /* Save VRSAVE. */
16130 offset = info->vrsave_save_offset + sp_offset;
16131 mem = gen_frame_mem (SImode,
16132 gen_rtx_PLUS (Pmode, frame_reg_rtx,
16133 GEN_INT (offset)));
16134 insn = emit_move_insn (mem, reg);
16137 /* Include the registers in the mask. */
16138 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
16140 insn = emit_insn (generate_set_vrsave (reg, info, 0));
16143 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
16144 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
16145 || (DEFAULT_ABI == ABI_V4
16146 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
16147 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
16149 /* If emit_load_toc_table will use the link register, we need to save
16150 it. We use R12 for this purpose because emit_load_toc_table
16151 can use register 0. This allows us to use a plain 'blr' to return
16152 from the procedure more often. */
16153 int save_LR_around_toc_setup = (TARGET_ELF
16154 && DEFAULT_ABI != ABI_AIX
16155 && flag_pic
16156 && ! info->lr_save_p
16157 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
16158 if (save_LR_around_toc_setup)
16160 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
16162 insn = emit_move_insn (frame_ptr_rtx, lr);
16163 RTX_FRAME_RELATED_P (insn) = 1;
16165 rs6000_emit_load_toc_table (TRUE);
16167 insn = emit_move_insn (lr, frame_ptr_rtx);
16168 RTX_FRAME_RELATED_P (insn) = 1;
16170 else
16171 rs6000_emit_load_toc_table (TRUE);
16174 #if TARGET_MACHO
16175 if (DEFAULT_ABI == ABI_DARWIN
16176 && flag_pic && crtl->uses_pic_offset_table)
16178 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
16179 rtx src = machopic_function_base_sym ();
16181 /* Save and restore LR locally around this call (in R0). */
16182 if (!info->lr_save_p)
16183 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
16185 emit_insn (gen_load_macho_picbase (src));
16187 emit_move_insn (gen_rtx_REG (Pmode,
16188 RS6000_PIC_OFFSET_TABLE_REGNUM),
16189 lr);
16191 if (!info->lr_save_p)
16192 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
16194 #endif
16197 /* Write function prologue. */
16199 static void
16200 rs6000_output_function_prologue (FILE *file,
16201 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
16203 rs6000_stack_t *info = rs6000_stack_info ();
16205 if (TARGET_DEBUG_STACK)
16206 debug_stack_info (info);
16208 /* Write .extern for any function we will call to save and restore
16209 fp values. */
16210 if (info->first_fp_reg_save < 64
16211 && !FP_SAVE_INLINE (info->first_fp_reg_save))
16212 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
16213 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
16214 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
16215 RESTORE_FP_SUFFIX);
16217 /* Write .extern for AIX common mode routines, if needed. */
16218 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
16220 fputs ("\t.extern __mulh\n", file);
16221 fputs ("\t.extern __mull\n", file);
16222 fputs ("\t.extern __divss\n", file);
16223 fputs ("\t.extern __divus\n", file);
16224 fputs ("\t.extern __quoss\n", file);
16225 fputs ("\t.extern __quous\n", file);
16226 common_mode_defined = 1;
16229 if (! HAVE_prologue)
16231 start_sequence ();
16233 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
16234 the "toplevel" insn chain. */
16235 emit_note (NOTE_INSN_DELETED);
16236 rs6000_emit_prologue ();
16237 emit_note (NOTE_INSN_DELETED);
16239 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16241 rtx insn;
16242 unsigned addr = 0;
16243 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
16245 INSN_ADDRESSES_NEW (insn, addr);
16246 addr += 4;
16250 if (TARGET_DEBUG_STACK)
16251 debug_rtx_list (get_insns (), 100);
16252 final (get_insns (), file, FALSE);
16253 end_sequence ();
16256 rs6000_pic_labelno++;
16259 /* Non-zero if vmx regs are restored before the frame pop, zero if
16260 we restore after the pop when possible. */
16261 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
16263 /* Emit function epilogue as insns.
16265 At present, dwarf2out_frame_debug_expr doesn't understand
16266 register restores, so we don't bother setting RTX_FRAME_RELATED_P
16267 anywhere in the epilogue. Most of the insns below would in any case
16268 need special notes to explain where r11 is in relation to the stack. */
16270 void
16271 rs6000_emit_epilogue (int sibcall)
16273 rs6000_stack_t *info;
16274 int restoring_FPRs_inline;
16275 int using_load_multiple;
16276 int using_mtcr_multiple;
16277 int use_backchain_to_restore_sp;
16278 int sp_offset = 0;
16279 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
16280 rtx frame_reg_rtx = sp_reg_rtx;
16281 enum machine_mode reg_mode = Pmode;
16282 int reg_size = TARGET_32BIT ? 4 : 8;
16283 int i;
16285 info = rs6000_stack_info ();
16287 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
16289 reg_mode = V2SImode;
16290 reg_size = 8;
16293 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
16294 && (!TARGET_SPE_ABI
16295 || info->spe_64bit_regs_used == 0)
16296 && info->first_gp_reg_save < 31
16297 && no_global_regs_above (info->first_gp_reg_save));
16298 restoring_FPRs_inline = (sibcall
16299 || crtl->calls_eh_return
16300 || info->first_fp_reg_save == 64
16301 || FP_SAVE_INLINE (info->first_fp_reg_save));
16302 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
16303 || rs6000_cpu == PROCESSOR_PPC603
16304 || rs6000_cpu == PROCESSOR_PPC750
16305 || optimize_size);
16306 /* Restore via the backchain when we have a large frame, since this
16307 is more efficient than an addis, addi pair. The second condition
16308 here will not trigger at the moment; We don't actually need a
16309 frame pointer for alloca, but the generic parts of the compiler
16310 give us one anyway. */
16311 use_backchain_to_restore_sp = (info->total_size > 32767
16312 || (cfun->calls_alloca
16313 && !frame_pointer_needed));
16315 if (WORLD_SAVE_P (info))
16317 int i, j;
16318 char rname[30];
16319 const char *alloc_rname;
16320 rtvec p;
16322 /* eh_rest_world_r10 will return to the location saved in the LR
16323 stack slot (which is not likely to be our caller.)
16324 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
16325 rest_world is similar, except any R10 parameter is ignored.
16326 The exception-handling stuff that was here in 2.95 is no
16327 longer necessary. */
16329 p = rtvec_alloc (9
16331 + 32 - info->first_gp_reg_save
16332 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
16333 + 63 + 1 - info->first_fp_reg_save);
16335 strcpy (rname, ((crtl->calls_eh_return) ?
16336 "*eh_rest_world_r10" : "*rest_world"));
16337 alloc_rname = ggc_strdup (rname);
16339 j = 0;
16340 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
16341 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
16342 gen_rtx_REG (Pmode,
16343 LR_REGNO));
16344 RTVEC_ELT (p, j++)
16345 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
16346 /* The instruction pattern requires a clobber here;
16347 it is shared with the restVEC helper. */
16348 RTVEC_ELT (p, j++)
16349 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
16352 /* CR register traditionally saved as CR2. */
16353 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
16354 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16355 GEN_INT (info->cr_save_offset));
16356 rtx mem = gen_frame_mem (reg_mode, addr);
16358 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
16361 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16363 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
16364 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16365 GEN_INT (info->gp_save_offset
16366 + reg_size * i));
16367 rtx mem = gen_frame_mem (reg_mode, addr);
16369 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
16371 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
16373 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
16374 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16375 GEN_INT (info->altivec_save_offset
16376 + 16 * i));
16377 rtx mem = gen_frame_mem (V4SImode, addr);
16379 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
16381 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
16383 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
16384 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16385 GEN_INT (info->fp_save_offset
16386 + 8 * i));
16387 rtx mem = gen_frame_mem (DFmode, addr);
16389 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
16391 RTVEC_ELT (p, j++)
16392 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
16393 RTVEC_ELT (p, j++)
16394 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
16395 RTVEC_ELT (p, j++)
16396 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
16397 RTVEC_ELT (p, j++)
16398 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
16399 RTVEC_ELT (p, j++)
16400 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
16401 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
16403 return;
16406 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
16407 if (info->push_p)
16408 sp_offset = info->total_size;
16410 /* Restore AltiVec registers if we must do so before adjusting the
16411 stack. */
16412 if (TARGET_ALTIVEC_ABI
16413 && info->altivec_size != 0
16414 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16415 || (DEFAULT_ABI != ABI_V4
16416 && info->altivec_save_offset < (TARGET_32BIT ? -220 : -288))))
16418 int i;
16420 if (use_backchain_to_restore_sp)
16422 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16423 emit_move_insn (frame_reg_rtx,
16424 gen_rtx_MEM (Pmode, sp_reg_rtx));
16425 sp_offset = 0;
16427 else if (frame_pointer_needed)
16428 frame_reg_rtx = hard_frame_pointer_rtx;
16430 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
16431 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
16433 rtx addr, areg, mem;
16435 areg = gen_rtx_REG (Pmode, 0);
16436 emit_move_insn
16437 (areg, GEN_INT (info->altivec_save_offset
16438 + sp_offset
16439 + 16 * (i - info->first_altivec_reg_save)));
16441 /* AltiVec addressing mode is [reg+reg]. */
16442 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
16443 mem = gen_frame_mem (V4SImode, addr);
16445 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
16449 /* Restore VRSAVE if we must do so before adjusting the stack. */
16450 if (TARGET_ALTIVEC
16451 && TARGET_ALTIVEC_VRSAVE
16452 && info->vrsave_mask != 0
16453 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16454 || (DEFAULT_ABI != ABI_V4
16455 && info->vrsave_save_offset < (TARGET_32BIT ? -220 : -288))))
16457 rtx addr, mem, reg;
16459 if (frame_reg_rtx == sp_reg_rtx)
16461 if (use_backchain_to_restore_sp)
16463 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16464 emit_move_insn (frame_reg_rtx,
16465 gen_rtx_MEM (Pmode, sp_reg_rtx));
16466 sp_offset = 0;
16468 else if (frame_pointer_needed)
16469 frame_reg_rtx = hard_frame_pointer_rtx;
16472 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16473 GEN_INT (info->vrsave_save_offset + sp_offset));
16474 mem = gen_frame_mem (SImode, addr);
16475 reg = gen_rtx_REG (SImode, 12);
16476 emit_move_insn (reg, mem);
16478 emit_insn (generate_set_vrsave (reg, info, 1));
16481 /* If we have a large stack frame, restore the old stack pointer
16482 using the backchain. */
16483 if (use_backchain_to_restore_sp)
16485 if (frame_reg_rtx == sp_reg_rtx)
16487 /* Under V.4, don't reset the stack pointer until after we're done
16488 loading the saved registers. */
16489 if (DEFAULT_ABI == ABI_V4)
16490 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16492 emit_move_insn (frame_reg_rtx,
16493 gen_rtx_MEM (Pmode, sp_reg_rtx));
16494 sp_offset = 0;
16496 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16497 && DEFAULT_ABI == ABI_V4)
16498 /* frame_reg_rtx has been set up by the altivec restore. */
16500 else
16502 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
16503 frame_reg_rtx = sp_reg_rtx;
16506 /* If we have a frame pointer, we can restore the old stack pointer
16507 from it. */
16508 else if (frame_pointer_needed)
16510 frame_reg_rtx = sp_reg_rtx;
16511 if (DEFAULT_ABI == ABI_V4)
16512 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16514 emit_insn (TARGET_32BIT
16515 ? gen_addsi3 (frame_reg_rtx, hard_frame_pointer_rtx,
16516 GEN_INT (info->total_size))
16517 : gen_adddi3 (frame_reg_rtx, hard_frame_pointer_rtx,
16518 GEN_INT (info->total_size)));
16519 sp_offset = 0;
16521 else if (info->push_p
16522 && DEFAULT_ABI != ABI_V4
16523 && !crtl->calls_eh_return)
16525 emit_insn (TARGET_32BIT
16526 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
16527 GEN_INT (info->total_size))
16528 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
16529 GEN_INT (info->total_size)));
16530 sp_offset = 0;
16533 /* Restore AltiVec registers if we have not done so already. */
16534 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16535 && TARGET_ALTIVEC_ABI
16536 && info->altivec_size != 0
16537 && (DEFAULT_ABI == ABI_V4
16538 || info->altivec_save_offset >= (TARGET_32BIT ? -220 : -288)))
16540 int i;
16542 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
16543 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
16545 rtx addr, areg, mem;
16547 areg = gen_rtx_REG (Pmode, 0);
16548 emit_move_insn
16549 (areg, GEN_INT (info->altivec_save_offset
16550 + sp_offset
16551 + 16 * (i - info->first_altivec_reg_save)));
16553 /* AltiVec addressing mode is [reg+reg]. */
16554 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
16555 mem = gen_frame_mem (V4SImode, addr);
16557 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
16561 /* Restore VRSAVE if we have not done so already. */
16562 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
16563 && TARGET_ALTIVEC
16564 && TARGET_ALTIVEC_VRSAVE
16565 && info->vrsave_mask != 0
16566 && (DEFAULT_ABI == ABI_V4
16567 || info->vrsave_save_offset >= (TARGET_32BIT ? -220 : -288)))
16569 rtx addr, mem, reg;
16571 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16572 GEN_INT (info->vrsave_save_offset + sp_offset));
16573 mem = gen_frame_mem (SImode, addr);
16574 reg = gen_rtx_REG (SImode, 12);
16575 emit_move_insn (reg, mem);
16577 emit_insn (generate_set_vrsave (reg, info, 1));
16580 /* Get the old lr if we saved it. */
16581 if (info->lr_save_p)
16583 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
16584 info->lr_save_offset + sp_offset);
16586 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
16589 /* Get the old cr if we saved it. */
16590 if (info->cr_save_p)
16592 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16593 GEN_INT (info->cr_save_offset + sp_offset));
16594 rtx mem = gen_frame_mem (SImode, addr);
16596 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
16599 /* Set LR here to try to overlap restores below. */
16600 if (info->lr_save_p)
16601 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
16602 gen_rtx_REG (Pmode, 0));
16604 /* Load exception handler data registers, if needed. */
16605 if (crtl->calls_eh_return)
16607 unsigned int i, regno;
16609 if (TARGET_AIX)
16611 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16612 GEN_INT (sp_offset + 5 * reg_size));
16613 rtx mem = gen_frame_mem (reg_mode, addr);
16615 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
16618 for (i = 0; ; ++i)
16620 rtx mem;
16622 regno = EH_RETURN_DATA_REGNO (i);
16623 if (regno == INVALID_REGNUM)
16624 break;
16626 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
16627 info->ehrd_offset + sp_offset
16628 + reg_size * (int) i);
16630 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
16634 /* Restore GPRs. This is done as a PARALLEL if we are using
16635 the load-multiple instructions. */
16636 if (using_load_multiple)
16638 rtvec p;
16639 p = rtvec_alloc (32 - info->first_gp_reg_save);
16640 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16642 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16643 GEN_INT (info->gp_save_offset
16644 + sp_offset
16645 + reg_size * i));
16646 rtx mem = gen_frame_mem (reg_mode, addr);
16648 RTVEC_ELT (p, i) =
16649 gen_rtx_SET (VOIDmode,
16650 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
16651 mem);
16653 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
16655 else if (TARGET_SPE_ABI
16656 && info->spe_64bit_regs_used != 0
16657 && info->first_gp_reg_save != 32)
16659 /* Determine whether we can address all of the registers that need
16660 to be saved with an offset from the stack pointer that fits in
16661 the small const field for SPE memory instructions. */
16662 int spe_regs_addressable_via_sp
16663 = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
16664 + (32 - info->first_gp_reg_save - 1) * reg_size);
16665 int spe_offset;
16667 if (spe_regs_addressable_via_sp)
16668 spe_offset = info->spe_gp_save_offset + sp_offset;
16669 else
16671 rtx old_frame_reg_rtx = frame_reg_rtx;
16672 /* Make r11 point to the start of the SPE save area. We worried about
16673 not clobbering it when we were saving registers in the prologue.
16674 There's no need to worry here because the static chain is passed
16675 anew to every function. */
16676 if (frame_reg_rtx == sp_reg_rtx)
16677 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16678 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
16679 GEN_INT (info->spe_gp_save_offset + sp_offset)));
16680 /* Keep the invariant that frame_reg_rtx + sp_offset points
16681 at the top of the stack frame. */
16682 sp_offset = -info->spe_gp_save_offset;
16684 spe_offset = 0;
16687 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16688 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
16690 rtx offset, addr, mem;
16692 /* We're doing all this to ensure that the immediate offset
16693 fits into the immediate field of 'evldd'. */
16694 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
16696 offset = GEN_INT (spe_offset + reg_size * i);
16697 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
16698 mem = gen_rtx_MEM (V2SImode, addr);
16700 emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
16701 mem);
16704 else
16705 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16706 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
16708 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16709 GEN_INT (info->gp_save_offset
16710 + sp_offset
16711 + reg_size * i));
16712 rtx mem = gen_frame_mem (reg_mode, addr);
16714 emit_move_insn (gen_rtx_REG (reg_mode,
16715 info->first_gp_reg_save + i), mem);
16718 /* Restore fpr's if we need to do it without calling a function. */
16719 if (restoring_FPRs_inline)
16720 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
16721 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
16722 && ! call_used_regs[info->first_fp_reg_save+i]))
16724 rtx addr, mem;
16725 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16726 GEN_INT (info->fp_save_offset
16727 + sp_offset
16728 + 8 * i));
16729 mem = gen_frame_mem (DFmode, addr);
16731 emit_move_insn (gen_rtx_REG (DFmode,
16732 info->first_fp_reg_save + i),
16733 mem);
16736 /* If we saved cr, restore it here. Just those that were used. */
16737 if (info->cr_save_p)
16739 rtx r12_rtx = gen_rtx_REG (SImode, 12);
16740 int count = 0;
16742 if (using_mtcr_multiple)
16744 for (i = 0; i < 8; i++)
16745 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
16746 count++;
16747 gcc_assert (count);
16750 if (using_mtcr_multiple && count > 1)
16752 rtvec p;
16753 int ndx;
16755 p = rtvec_alloc (count);
16757 ndx = 0;
16758 for (i = 0; i < 8; i++)
16759 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
16761 rtvec r = rtvec_alloc (2);
16762 RTVEC_ELT (r, 0) = r12_rtx;
16763 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
16764 RTVEC_ELT (p, ndx) =
16765 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
16766 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
16767 ndx++;
16769 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
16770 gcc_assert (ndx == count);
16772 else
16773 for (i = 0; i < 8; i++)
16774 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
16776 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
16777 CR0_REGNO+i),
16778 r12_rtx));
16782 /* If this is V.4, unwind the stack pointer after all of the loads
16783 have been done. */
16784 if (frame_reg_rtx != sp_reg_rtx)
16786 /* This blockage is needed so that sched doesn't decide to move
16787 the sp change before the register restores. */
16788 rs6000_emit_stack_tie ();
16789 if (sp_offset != 0)
16790 emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
16791 GEN_INT (sp_offset)));
16792 else
16793 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
16795 else if (sp_offset != 0)
16796 emit_insn (TARGET_32BIT
16797 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
16798 GEN_INT (sp_offset))
16799 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
16800 GEN_INT (sp_offset)));
16802 if (crtl->calls_eh_return)
16804 rtx sa = EH_RETURN_STACKADJ_RTX;
16805 emit_insn (TARGET_32BIT
16806 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
16807 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
16810 if (!sibcall)
16812 rtvec p;
16813 if (! restoring_FPRs_inline)
16814 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
16815 else
16816 p = rtvec_alloc (2);
16818 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
16819 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
16820 gen_rtx_REG (Pmode,
16821 LR_REGNO));
16823 /* If we have to restore more than two FP registers, branch to the
16824 restore function. It will return to our caller. */
16825 if (! restoring_FPRs_inline)
16827 int i;
16828 char rname[30];
16829 const char *alloc_rname;
16831 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
16832 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
16833 alloc_rname = ggc_strdup (rname);
16834 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
16835 gen_rtx_SYMBOL_REF (Pmode,
16836 alloc_rname));
16838 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
16840 rtx addr, mem;
16841 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
16842 GEN_INT (info->fp_save_offset + 8*i));
16843 mem = gen_frame_mem (DFmode, addr);
16845 RTVEC_ELT (p, i+3) =
16846 gen_rtx_SET (VOIDmode,
16847 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
16848 mem);
16852 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
16856 /* Write function epilogue. */
16858 static void
16859 rs6000_output_function_epilogue (FILE *file,
16860 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
16862 if (! HAVE_epilogue)
16864 rtx insn = get_last_insn ();
16865 /* If the last insn was a BARRIER, we don't have to write anything except
16866 the trace table. */
16867 if (GET_CODE (insn) == NOTE)
16868 insn = prev_nonnote_insn (insn);
16869 if (insn == 0 || GET_CODE (insn) != BARRIER)
16871 /* This is slightly ugly, but at least we don't have two
16872 copies of the epilogue-emitting code. */
16873 start_sequence ();
16875 /* A NOTE_INSN_DELETED is supposed to be at the start
16876 and end of the "toplevel" insn chain. */
16877 emit_note (NOTE_INSN_DELETED);
16878 rs6000_emit_epilogue (FALSE);
16879 emit_note (NOTE_INSN_DELETED);
16881 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16883 rtx insn;
16884 unsigned addr = 0;
16885 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
16887 INSN_ADDRESSES_NEW (insn, addr);
16888 addr += 4;
16892 if (TARGET_DEBUG_STACK)
16893 debug_rtx_list (get_insns (), 100);
16894 final (get_insns (), file, FALSE);
16895 end_sequence ();
16899 #if TARGET_MACHO
16900 macho_branch_islands ();
16901 /* Mach-O doesn't support labels at the end of objects, so if
16902 it looks like we might want one, insert a NOP. */
16904 rtx insn = get_last_insn ();
16905 while (insn
16906 && NOTE_P (insn)
16907 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
16908 insn = PREV_INSN (insn);
16909 if (insn
16910 && (LABEL_P (insn)
16911 || (NOTE_P (insn)
16912 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
16913 fputs ("\tnop\n", file);
16915 #endif
16917 /* Output a traceback table here. See /usr/include/sys/debug.h for info
16918 on its format.
16920 We don't output a traceback table if -finhibit-size-directive was
16921 used. The documentation for -finhibit-size-directive reads
16922 ``don't output a @code{.size} assembler directive, or anything
16923 else that would cause trouble if the function is split in the
16924 middle, and the two halves are placed at locations far apart in
16925 memory.'' The traceback table has this property, since it
16926 includes the offset from the start of the function to the
16927 traceback table itself.
16929 System V.4 Powerpc's (and the embedded ABI derived from it) use a
16930 different traceback table. */
16931 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
16932 && rs6000_traceback != traceback_none && !crtl->is_thunk)
16934 const char *fname = NULL;
16935 const char *language_string = lang_hooks.name;
16936 int fixed_parms = 0, float_parms = 0, parm_info = 0;
16937 int i;
16938 int optional_tbtab;
16939 rs6000_stack_t *info = rs6000_stack_info ();
16941 if (rs6000_traceback == traceback_full)
16942 optional_tbtab = 1;
16943 else if (rs6000_traceback == traceback_part)
16944 optional_tbtab = 0;
16945 else
16946 optional_tbtab = !optimize_size && !TARGET_ELF;
16948 if (optional_tbtab)
16950 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
16951 while (*fname == '.') /* V.4 encodes . in the name */
16952 fname++;
16954 /* Need label immediately before tbtab, so we can compute
16955 its offset from the function start. */
16956 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
16957 ASM_OUTPUT_LABEL (file, fname);
16960 /* The .tbtab pseudo-op can only be used for the first eight
16961 expressions, since it can't handle the possibly variable
16962 length fields that follow. However, if you omit the optional
16963 fields, the assembler outputs zeros for all optional fields
16964 anyways, giving each variable length field is minimum length
16965 (as defined in sys/debug.h). Thus we can not use the .tbtab
16966 pseudo-op at all. */
16968 /* An all-zero word flags the start of the tbtab, for debuggers
16969 that have to find it by searching forward from the entry
16970 point or from the current pc. */
16971 fputs ("\t.long 0\n", file);
16973 /* Tbtab format type. Use format type 0. */
16974 fputs ("\t.byte 0,", file);
16976 /* Language type. Unfortunately, there does not seem to be any
16977 official way to discover the language being compiled, so we
16978 use language_string.
16979 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
16980 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
16981 a number, so for now use 9. */
16982 if (! strcmp (language_string, "GNU C"))
16983 i = 0;
16984 else if (! strcmp (language_string, "GNU F77")
16985 || ! strcmp (language_string, "GNU Fortran"))
16986 i = 1;
16987 else if (! strcmp (language_string, "GNU Pascal"))
16988 i = 2;
16989 else if (! strcmp (language_string, "GNU Ada"))
16990 i = 3;
16991 else if (! strcmp (language_string, "GNU C++")
16992 || ! strcmp (language_string, "GNU Objective-C++"))
16993 i = 9;
16994 else if (! strcmp (language_string, "GNU Java"))
16995 i = 13;
16996 else if (! strcmp (language_string, "GNU Objective-C"))
16997 i = 14;
16998 else
16999 gcc_unreachable ();
17000 fprintf (file, "%d,", i);
17002 /* 8 single bit fields: global linkage (not set for C extern linkage,
17003 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
17004 from start of procedure stored in tbtab, internal function, function
17005 has controlled storage, function has no toc, function uses fp,
17006 function logs/aborts fp operations. */
17007 /* Assume that fp operations are used if any fp reg must be saved. */
17008 fprintf (file, "%d,",
17009 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
17011 /* 6 bitfields: function is interrupt handler, name present in
17012 proc table, function calls alloca, on condition directives
17013 (controls stack walks, 3 bits), saves condition reg, saves
17014 link reg. */
17015 /* The `function calls alloca' bit seems to be set whenever reg 31 is
17016 set up as a frame pointer, even when there is no alloca call. */
17017 fprintf (file, "%d,",
17018 ((optional_tbtab << 6)
17019 | ((optional_tbtab & frame_pointer_needed) << 5)
17020 | (info->cr_save_p << 1)
17021 | (info->lr_save_p)));
17023 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
17024 (6 bits). */
17025 fprintf (file, "%d,",
17026 (info->push_p << 7) | (64 - info->first_fp_reg_save));
17028 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
17029 fprintf (file, "%d,", (32 - first_reg_to_save ()));
17031 if (optional_tbtab)
17033 /* Compute the parameter info from the function decl argument
17034 list. */
17035 tree decl;
17036 int next_parm_info_bit = 31;
17038 for (decl = DECL_ARGUMENTS (current_function_decl);
17039 decl; decl = TREE_CHAIN (decl))
17041 rtx parameter = DECL_INCOMING_RTL (decl);
17042 enum machine_mode mode = GET_MODE (parameter);
17044 if (GET_CODE (parameter) == REG)
17046 if (SCALAR_FLOAT_MODE_P (mode))
17048 int bits;
17050 float_parms++;
17052 switch (mode)
17054 case SFmode:
17055 case SDmode:
17056 bits = 0x2;
17057 break;
17059 case DFmode:
17060 case DDmode:
17061 case TFmode:
17062 case TDmode:
17063 bits = 0x3;
17064 break;
17066 default:
17067 gcc_unreachable ();
17070 /* If only one bit will fit, don't or in this entry. */
17071 if (next_parm_info_bit > 0)
17072 parm_info |= (bits << (next_parm_info_bit - 1));
17073 next_parm_info_bit -= 2;
17075 else
17077 fixed_parms += ((GET_MODE_SIZE (mode)
17078 + (UNITS_PER_WORD - 1))
17079 / UNITS_PER_WORD);
17080 next_parm_info_bit -= 1;
17086 /* Number of fixed point parameters. */
17087 /* This is actually the number of words of fixed point parameters; thus
17088 an 8 byte struct counts as 2; and thus the maximum value is 8. */
17089 fprintf (file, "%d,", fixed_parms);
17091 /* 2 bitfields: number of floating point parameters (7 bits), parameters
17092 all on stack. */
17093 /* This is actually the number of fp registers that hold parameters;
17094 and thus the maximum value is 13. */
17095 /* Set parameters on stack bit if parameters are not in their original
17096 registers, regardless of whether they are on the stack? Xlc
17097 seems to set the bit when not optimizing. */
17098 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
17100 if (! optional_tbtab)
17101 return;
17103 /* Optional fields follow. Some are variable length. */
17105 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
17106 11 double float. */
17107 /* There is an entry for each parameter in a register, in the order that
17108 they occur in the parameter list. Any intervening arguments on the
17109 stack are ignored. If the list overflows a long (max possible length
17110 34 bits) then completely leave off all elements that don't fit. */
17111 /* Only emit this long if there was at least one parameter. */
17112 if (fixed_parms || float_parms)
17113 fprintf (file, "\t.long %d\n", parm_info);
17115 /* Offset from start of code to tb table. */
17116 fputs ("\t.long ", file);
17117 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
17118 if (TARGET_AIX)
17119 RS6000_OUTPUT_BASENAME (file, fname);
17120 else
17121 assemble_name (file, fname);
17122 putc ('-', file);
17123 rs6000_output_function_entry (file, fname);
17124 putc ('\n', file);
17126 /* Interrupt handler mask. */
17127 /* Omit this long, since we never set the interrupt handler bit
17128 above. */
17130 /* Number of CTL (controlled storage) anchors. */
17131 /* Omit this long, since the has_ctl bit is never set above. */
17133 /* Displacement into stack of each CTL anchor. */
17134 /* Omit this list of longs, because there are no CTL anchors. */
17136 /* Length of function name. */
17137 if (*fname == '*')
17138 ++fname;
17139 fprintf (file, "\t.short %d\n", (int) strlen (fname));
17141 /* Function name. */
17142 assemble_string (fname, strlen (fname));
17144 /* Register for alloca automatic storage; this is always reg 31.
17145 Only emit this if the alloca bit was set above. */
17146 if (frame_pointer_needed)
17147 fputs ("\t.byte 31\n", file);
17149 fputs ("\t.align 2\n", file);
17153 /* A C compound statement that outputs the assembler code for a thunk
17154 function, used to implement C++ virtual function calls with
17155 multiple inheritance. The thunk acts as a wrapper around a virtual
17156 function, adjusting the implicit object parameter before handing
17157 control off to the real function.
17159 First, emit code to add the integer DELTA to the location that
17160 contains the incoming first argument. Assume that this argument
17161 contains a pointer, and is the one used to pass the `this' pointer
17162 in C++. This is the incoming argument *before* the function
17163 prologue, e.g. `%o0' on a sparc. The addition must preserve the
17164 values of all other incoming arguments.
17166 After the addition, emit code to jump to FUNCTION, which is a
17167 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
17168 not touch the return address. Hence returning from FUNCTION will
17169 return to whoever called the current `thunk'.
17171 The effect must be as if FUNCTION had been called directly with the
17172 adjusted first argument. This macro is responsible for emitting
17173 all of the code for a thunk function; output_function_prologue()
17174 and output_function_epilogue() are not invoked.
17176 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
17177 been extracted from it.) It might possibly be useful on some
17178 targets, but probably not.
17180 If you do not define this macro, the target-independent code in the
17181 C++ frontend will generate a less efficient heavyweight thunk that
17182 calls FUNCTION instead of jumping to it. The generic approach does
17183 not support varargs. */
17185 static void
17186 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
17187 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
17188 tree function)
17190 rtx this, insn, funexp;
17192 reload_completed = 1;
17193 epilogue_completed = 1;
17195 /* Mark the end of the (empty) prologue. */
17196 emit_note (NOTE_INSN_PROLOGUE_END);
17198 /* Find the "this" pointer. If the function returns a structure,
17199 the structure return pointer is in r3. */
17200 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
17201 this = gen_rtx_REG (Pmode, 4);
17202 else
17203 this = gen_rtx_REG (Pmode, 3);
17205 /* Apply the constant offset, if required. */
17206 if (delta)
17208 rtx delta_rtx = GEN_INT (delta);
17209 emit_insn (TARGET_32BIT
17210 ? gen_addsi3 (this, this, delta_rtx)
17211 : gen_adddi3 (this, this, delta_rtx));
17214 /* Apply the offset from the vtable, if required. */
17215 if (vcall_offset)
17217 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
17218 rtx tmp = gen_rtx_REG (Pmode, 12);
17220 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
17221 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
17223 emit_insn (TARGET_32BIT
17224 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
17225 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
17226 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
17228 else
17230 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
17232 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
17234 emit_insn (TARGET_32BIT
17235 ? gen_addsi3 (this, this, tmp)
17236 : gen_adddi3 (this, this, tmp));
17239 /* Generate a tail call to the target function. */
17240 if (!TREE_USED (function))
17242 assemble_external (function);
17243 TREE_USED (function) = 1;
17245 funexp = XEXP (DECL_RTL (function), 0);
17246 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
17248 #if TARGET_MACHO
17249 if (MACHOPIC_INDIRECT)
17250 funexp = machopic_indirect_call_target (funexp);
17251 #endif
17253 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
17254 generate sibcall RTL explicitly. */
17255 insn = emit_call_insn (
17256 gen_rtx_PARALLEL (VOIDmode,
17257 gen_rtvec (4,
17258 gen_rtx_CALL (VOIDmode,
17259 funexp, const0_rtx),
17260 gen_rtx_USE (VOIDmode, const0_rtx),
17261 gen_rtx_USE (VOIDmode,
17262 gen_rtx_REG (SImode,
17263 LR_REGNO)),
17264 gen_rtx_RETURN (VOIDmode))));
17265 SIBLING_CALL_P (insn) = 1;
17266 emit_barrier ();
17268 /* Run just enough of rest_of_compilation to get the insns emitted.
17269 There's not really enough bulk here to make other passes such as
17270 instruction scheduling worth while. Note that use_thunk calls
17271 assemble_start_function and assemble_end_function. */
17272 insn = get_insns ();
17273 insn_locators_alloc ();
17274 shorten_branches (insn);
17275 final_start_function (insn, file, 1);
17276 final (insn, file, 1);
17277 final_end_function ();
17278 free_after_compilation (cfun);
17280 reload_completed = 0;
17281 epilogue_completed = 0;
17284 /* A quick summary of the various types of 'constant-pool tables'
17285 under PowerPC:
17287 Target Flags Name One table per
17288 AIX (none) AIX TOC object file
17289 AIX -mfull-toc AIX TOC object file
17290 AIX -mminimal-toc AIX minimal TOC translation unit
17291 SVR4/EABI (none) SVR4 SDATA object file
17292 SVR4/EABI -fpic SVR4 pic object file
17293 SVR4/EABI -fPIC SVR4 PIC translation unit
17294 SVR4/EABI -mrelocatable EABI TOC function
17295 SVR4/EABI -maix AIX TOC object file
17296 SVR4/EABI -maix -mminimal-toc
17297 AIX minimal TOC translation unit
17299 Name Reg. Set by entries contains:
17300 made by addrs? fp? sum?
17302 AIX TOC 2 crt0 as Y option option
17303 AIX minimal TOC 30 prolog gcc Y Y option
17304 SVR4 SDATA 13 crt0 gcc N Y N
17305 SVR4 pic 30 prolog ld Y not yet N
17306 SVR4 PIC 30 prolog gcc Y option option
17307 EABI TOC 30 prolog gcc Y option option
17311 /* Hash functions for the hash table. */
17313 static unsigned
17314 rs6000_hash_constant (rtx k)
17316 enum rtx_code code = GET_CODE (k);
17317 enum machine_mode mode = GET_MODE (k);
17318 unsigned result = (code << 3) ^ mode;
17319 const char *format;
17320 int flen, fidx;
17322 format = GET_RTX_FORMAT (code);
17323 flen = strlen (format);
17324 fidx = 0;
17326 switch (code)
17328 case LABEL_REF:
17329 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
17331 case CONST_DOUBLE:
17332 if (mode != VOIDmode)
17333 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
17334 flen = 2;
17335 break;
17337 case CODE_LABEL:
17338 fidx = 3;
17339 break;
17341 default:
17342 break;
17345 for (; fidx < flen; fidx++)
17346 switch (format[fidx])
17348 case 's':
17350 unsigned i, len;
17351 const char *str = XSTR (k, fidx);
17352 len = strlen (str);
17353 result = result * 613 + len;
17354 for (i = 0; i < len; i++)
17355 result = result * 613 + (unsigned) str[i];
17356 break;
17358 case 'u':
17359 case 'e':
17360 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
17361 break;
17362 case 'i':
17363 case 'n':
17364 result = result * 613 + (unsigned) XINT (k, fidx);
17365 break;
17366 case 'w':
17367 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
17368 result = result * 613 + (unsigned) XWINT (k, fidx);
17369 else
17371 size_t i;
17372 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
17373 result = result * 613 + (unsigned) (XWINT (k, fidx)
17374 >> CHAR_BIT * i);
17376 break;
17377 case '0':
17378 break;
17379 default:
17380 gcc_unreachable ();
17383 return result;
17386 static unsigned
17387 toc_hash_function (const void *hash_entry)
17389 const struct toc_hash_struct *thc =
17390 (const struct toc_hash_struct *) hash_entry;
17391 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
17394 /* Compare H1 and H2 for equivalence. */
17396 static int
17397 toc_hash_eq (const void *h1, const void *h2)
17399 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
17400 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
17402 if (((const struct toc_hash_struct *) h1)->key_mode
17403 != ((const struct toc_hash_struct *) h2)->key_mode)
17404 return 0;
17406 return rtx_equal_p (r1, r2);
17409 /* These are the names given by the C++ front-end to vtables, and
17410 vtable-like objects. Ideally, this logic should not be here;
17411 instead, there should be some programmatic way of inquiring as
17412 to whether or not an object is a vtable. */
17414 #define VTABLE_NAME_P(NAME) \
17415 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
17416 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
17417 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
17418 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
17419 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
17421 void
17422 rs6000_output_symbol_ref (FILE *file, rtx x)
17424 /* Currently C++ toc references to vtables can be emitted before it
17425 is decided whether the vtable is public or private. If this is
17426 the case, then the linker will eventually complain that there is
17427 a reference to an unknown section. Thus, for vtables only,
17428 we emit the TOC reference to reference the symbol and not the
17429 section. */
17430 const char *name = XSTR (x, 0);
17432 if (VTABLE_NAME_P (name))
17434 RS6000_OUTPUT_BASENAME (file, name);
17436 else
17437 assemble_name (file, name);
17440 /* Output a TOC entry. We derive the entry name from what is being
17441 written. */
17443 void
17444 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
17446 char buf[256];
17447 const char *name = buf;
17448 const char *real_name;
17449 rtx base = x;
17450 HOST_WIDE_INT offset = 0;
17452 gcc_assert (!TARGET_NO_TOC);
17454 /* When the linker won't eliminate them, don't output duplicate
17455 TOC entries (this happens on AIX if there is any kind of TOC,
17456 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
17457 CODE_LABELs. */
17458 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
17460 struct toc_hash_struct *h;
17461 void * * found;
17463 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
17464 time because GGC is not initialized at that point. */
17465 if (toc_hash_table == NULL)
17466 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
17467 toc_hash_eq, NULL);
17469 h = ggc_alloc (sizeof (*h));
17470 h->key = x;
17471 h->key_mode = mode;
17472 h->labelno = labelno;
17474 found = htab_find_slot (toc_hash_table, h, 1);
17475 if (*found == NULL)
17476 *found = h;
17477 else /* This is indeed a duplicate.
17478 Set this label equal to that label. */
17480 fputs ("\t.set ", file);
17481 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
17482 fprintf (file, "%d,", labelno);
17483 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
17484 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
17485 found)->labelno));
17486 return;
17490 /* If we're going to put a double constant in the TOC, make sure it's
17491 aligned properly when strict alignment is on. */
17492 if (GET_CODE (x) == CONST_DOUBLE
17493 && STRICT_ALIGNMENT
17494 && GET_MODE_BITSIZE (mode) >= 64
17495 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
17496 ASM_OUTPUT_ALIGN (file, 3);
17499 (*targetm.asm_out.internal_label) (file, "LC", labelno);
17501 /* Handle FP constants specially. Note that if we have a minimal
17502 TOC, things we put here aren't actually in the TOC, so we can allow
17503 FP constants. */
17504 if (GET_CODE (x) == CONST_DOUBLE &&
17505 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
17507 REAL_VALUE_TYPE rv;
17508 long k[4];
17510 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
17511 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17512 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
17513 else
17514 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
17516 if (TARGET_64BIT)
17518 if (TARGET_MINIMAL_TOC)
17519 fputs (DOUBLE_INT_ASM_OP, file);
17520 else
17521 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17522 k[0] & 0xffffffff, k[1] & 0xffffffff,
17523 k[2] & 0xffffffff, k[3] & 0xffffffff);
17524 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
17525 k[0] & 0xffffffff, k[1] & 0xffffffff,
17526 k[2] & 0xffffffff, k[3] & 0xffffffff);
17527 return;
17529 else
17531 if (TARGET_MINIMAL_TOC)
17532 fputs ("\t.long ", file);
17533 else
17534 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17535 k[0] & 0xffffffff, k[1] & 0xffffffff,
17536 k[2] & 0xffffffff, k[3] & 0xffffffff);
17537 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
17538 k[0] & 0xffffffff, k[1] & 0xffffffff,
17539 k[2] & 0xffffffff, k[3] & 0xffffffff);
17540 return;
17543 else if (GET_CODE (x) == CONST_DOUBLE &&
17544 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
17546 REAL_VALUE_TYPE rv;
17547 long k[2];
17549 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
17551 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17552 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
17553 else
17554 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
17556 if (TARGET_64BIT)
17558 if (TARGET_MINIMAL_TOC)
17559 fputs (DOUBLE_INT_ASM_OP, file);
17560 else
17561 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
17562 k[0] & 0xffffffff, k[1] & 0xffffffff);
17563 fprintf (file, "0x%lx%08lx\n",
17564 k[0] & 0xffffffff, k[1] & 0xffffffff);
17565 return;
17567 else
17569 if (TARGET_MINIMAL_TOC)
17570 fputs ("\t.long ", file);
17571 else
17572 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
17573 k[0] & 0xffffffff, k[1] & 0xffffffff);
17574 fprintf (file, "0x%lx,0x%lx\n",
17575 k[0] & 0xffffffff, k[1] & 0xffffffff);
17576 return;
17579 else if (GET_CODE (x) == CONST_DOUBLE &&
17580 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
17582 REAL_VALUE_TYPE rv;
17583 long l;
17585 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
17586 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17587 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
17588 else
17589 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
17591 if (TARGET_64BIT)
17593 if (TARGET_MINIMAL_TOC)
17594 fputs (DOUBLE_INT_ASM_OP, file);
17595 else
17596 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
17597 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
17598 return;
17600 else
17602 if (TARGET_MINIMAL_TOC)
17603 fputs ("\t.long ", file);
17604 else
17605 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
17606 fprintf (file, "0x%lx\n", l & 0xffffffff);
17607 return;
17610 else if (GET_MODE (x) == VOIDmode
17611 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
17613 unsigned HOST_WIDE_INT low;
17614 HOST_WIDE_INT high;
17616 if (GET_CODE (x) == CONST_DOUBLE)
17618 low = CONST_DOUBLE_LOW (x);
17619 high = CONST_DOUBLE_HIGH (x);
17621 else
17622 #if HOST_BITS_PER_WIDE_INT == 32
17624 low = INTVAL (x);
17625 high = (low & 0x80000000) ? ~0 : 0;
17627 #else
17629 low = INTVAL (x) & 0xffffffff;
17630 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
17632 #endif
17634 /* TOC entries are always Pmode-sized, but since this
17635 is a bigendian machine then if we're putting smaller
17636 integer constants in the TOC we have to pad them.
17637 (This is still a win over putting the constants in
17638 a separate constant pool, because then we'd have
17639 to have both a TOC entry _and_ the actual constant.)
17641 For a 32-bit target, CONST_INT values are loaded and shifted
17642 entirely within `low' and can be stored in one TOC entry. */
17644 /* It would be easy to make this work, but it doesn't now. */
17645 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
17647 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
17649 #if HOST_BITS_PER_WIDE_INT == 32
17650 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
17651 POINTER_SIZE, &low, &high, 0);
17652 #else
17653 low |= high << 32;
17654 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
17655 high = (HOST_WIDE_INT) low >> 32;
17656 low &= 0xffffffff;
17657 #endif
17660 if (TARGET_64BIT)
17662 if (TARGET_MINIMAL_TOC)
17663 fputs (DOUBLE_INT_ASM_OP, file);
17664 else
17665 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
17666 (long) high & 0xffffffff, (long) low & 0xffffffff);
17667 fprintf (file, "0x%lx%08lx\n",
17668 (long) high & 0xffffffff, (long) low & 0xffffffff);
17669 return;
17671 else
17673 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
17675 if (TARGET_MINIMAL_TOC)
17676 fputs ("\t.long ", file);
17677 else
17678 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
17679 (long) high & 0xffffffff, (long) low & 0xffffffff);
17680 fprintf (file, "0x%lx,0x%lx\n",
17681 (long) high & 0xffffffff, (long) low & 0xffffffff);
17683 else
17685 if (TARGET_MINIMAL_TOC)
17686 fputs ("\t.long ", file);
17687 else
17688 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
17689 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
17691 return;
17695 if (GET_CODE (x) == CONST)
17697 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
17699 base = XEXP (XEXP (x, 0), 0);
17700 offset = INTVAL (XEXP (XEXP (x, 0), 1));
17703 switch (GET_CODE (base))
17705 case SYMBOL_REF:
17706 name = XSTR (base, 0);
17707 break;
17709 case LABEL_REF:
17710 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
17711 CODE_LABEL_NUMBER (XEXP (base, 0)));
17712 break;
17714 case CODE_LABEL:
17715 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
17716 break;
17718 default:
17719 gcc_unreachable ();
17722 real_name = (*targetm.strip_name_encoding) (name);
17723 if (TARGET_MINIMAL_TOC)
17724 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
17725 else
17727 fprintf (file, "\t.tc %s", real_name);
17729 if (offset < 0)
17730 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
17731 else if (offset)
17732 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
17734 fputs ("[TC],", file);
17737 /* Currently C++ toc references to vtables can be emitted before it
17738 is decided whether the vtable is public or private. If this is
17739 the case, then the linker will eventually complain that there is
17740 a TOC reference to an unknown section. Thus, for vtables only,
17741 we emit the TOC reference to reference the symbol and not the
17742 section. */
17743 if (VTABLE_NAME_P (name))
17745 RS6000_OUTPUT_BASENAME (file, name);
17746 if (offset < 0)
17747 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
17748 else if (offset > 0)
17749 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
17751 else
17752 output_addr_const (file, x);
17753 putc ('\n', file);
17756 /* Output an assembler pseudo-op to write an ASCII string of N characters
17757 starting at P to FILE.
17759 On the RS/6000, we have to do this using the .byte operation and
17760 write out special characters outside the quoted string.
17761 Also, the assembler is broken; very long strings are truncated,
17762 so we must artificially break them up early. */
17764 void
17765 output_ascii (FILE *file, const char *p, int n)
17767 char c;
17768 int i, count_string;
17769 const char *for_string = "\t.byte \"";
17770 const char *for_decimal = "\t.byte ";
17771 const char *to_close = NULL;
17773 count_string = 0;
17774 for (i = 0; i < n; i++)
17776 c = *p++;
17777 if (c >= ' ' && c < 0177)
17779 if (for_string)
17780 fputs (for_string, file);
17781 putc (c, file);
17783 /* Write two quotes to get one. */
17784 if (c == '"')
17786 putc (c, file);
17787 ++count_string;
17790 for_string = NULL;
17791 for_decimal = "\"\n\t.byte ";
17792 to_close = "\"\n";
17793 ++count_string;
17795 if (count_string >= 512)
17797 fputs (to_close, file);
17799 for_string = "\t.byte \"";
17800 for_decimal = "\t.byte ";
17801 to_close = NULL;
17802 count_string = 0;
17805 else
17807 if (for_decimal)
17808 fputs (for_decimal, file);
17809 fprintf (file, "%d", c);
17811 for_string = "\n\t.byte \"";
17812 for_decimal = ", ";
17813 to_close = "\n";
17814 count_string = 0;
17818 /* Now close the string if we have written one. Then end the line. */
17819 if (to_close)
17820 fputs (to_close, file);
17823 /* Generate a unique section name for FILENAME for a section type
17824 represented by SECTION_DESC. Output goes into BUF.
17826 SECTION_DESC can be any string, as long as it is different for each
17827 possible section type.
17829 We name the section in the same manner as xlc. The name begins with an
17830 underscore followed by the filename (after stripping any leading directory
17831 names) with the last period replaced by the string SECTION_DESC. If
17832 FILENAME does not contain a period, SECTION_DESC is appended to the end of
17833 the name. */
17835 void
17836 rs6000_gen_section_name (char **buf, const char *filename,
17837 const char *section_desc)
17839 const char *q, *after_last_slash, *last_period = 0;
17840 char *p;
17841 int len;
17843 after_last_slash = filename;
17844 for (q = filename; *q; q++)
17846 if (*q == '/')
17847 after_last_slash = q + 1;
17848 else if (*q == '.')
17849 last_period = q;
17852 len = strlen (after_last_slash) + strlen (section_desc) + 2;
17853 *buf = (char *) xmalloc (len);
17855 p = *buf;
17856 *p++ = '_';
17858 for (q = after_last_slash; *q; q++)
17860 if (q == last_period)
17862 strcpy (p, section_desc);
17863 p += strlen (section_desc);
17864 break;
17867 else if (ISALNUM (*q))
17868 *p++ = *q;
17871 if (last_period == 0)
17872 strcpy (p, section_desc);
17873 else
17874 *p = '\0';
17877 /* Emit profile function. */
17879 void
17880 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
17882 /* Non-standard profiling for kernels, which just saves LR then calls
17883 _mcount without worrying about arg saves. The idea is to change
17884 the function prologue as little as possible as it isn't easy to
17885 account for arg save/restore code added just for _mcount. */
17886 if (TARGET_PROFILE_KERNEL)
17887 return;
17889 if (DEFAULT_ABI == ABI_AIX)
17891 #ifndef NO_PROFILE_COUNTERS
17892 # define NO_PROFILE_COUNTERS 0
17893 #endif
17894 if (NO_PROFILE_COUNTERS)
17895 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
17896 else
17898 char buf[30];
17899 const char *label_name;
17900 rtx fun;
17902 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
17903 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
17904 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
17906 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
17907 fun, Pmode);
17910 else if (DEFAULT_ABI == ABI_DARWIN)
17912 const char *mcount_name = RS6000_MCOUNT;
17913 int caller_addr_regno = LR_REGNO;
17915 /* Be conservative and always set this, at least for now. */
17916 crtl->uses_pic_offset_table = 1;
17918 #if TARGET_MACHO
17919 /* For PIC code, set up a stub and collect the caller's address
17920 from r0, which is where the prologue puts it. */
17921 if (MACHOPIC_INDIRECT
17922 && crtl->uses_pic_offset_table)
17923 caller_addr_regno = 0;
17924 #endif
17925 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
17926 0, VOIDmode, 1,
17927 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
17931 /* Write function profiler code. */
17933 void
17934 output_function_profiler (FILE *file, int labelno)
17936 char buf[100];
17938 switch (DEFAULT_ABI)
17940 default:
17941 gcc_unreachable ();
17943 case ABI_V4:
17944 if (!TARGET_32BIT)
17946 warning (0, "no profiling of 64-bit code for this ABI");
17947 return;
17949 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
17950 fprintf (file, "\tmflr %s\n", reg_names[0]);
17951 if (NO_PROFILE_COUNTERS)
17953 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17954 reg_names[0], reg_names[1]);
17956 else if (TARGET_SECURE_PLT && flag_pic)
17958 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
17959 reg_names[0], reg_names[1]);
17960 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
17961 asm_fprintf (file, "\t{cau|addis} %s,%s,",
17962 reg_names[12], reg_names[12]);
17963 assemble_name (file, buf);
17964 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
17965 assemble_name (file, buf);
17966 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
17968 else if (flag_pic == 1)
17970 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
17971 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17972 reg_names[0], reg_names[1]);
17973 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
17974 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
17975 assemble_name (file, buf);
17976 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
17978 else if (flag_pic > 1)
17980 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17981 reg_names[0], reg_names[1]);
17982 /* Now, we need to get the address of the label. */
17983 fputs ("\tbcl 20,31,1f\n\t.long ", file);
17984 assemble_name (file, buf);
17985 fputs ("-.\n1:", file);
17986 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
17987 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
17988 reg_names[0], reg_names[11]);
17989 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
17990 reg_names[0], reg_names[0], reg_names[11]);
17992 else
17994 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
17995 assemble_name (file, buf);
17996 fputs ("@ha\n", file);
17997 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17998 reg_names[0], reg_names[1]);
17999 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
18000 assemble_name (file, buf);
18001 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
18004 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
18005 fprintf (file, "\tbl %s%s\n",
18006 RS6000_MCOUNT, flag_pic ? "@plt" : "");
18007 break;
18009 case ABI_AIX:
18010 case ABI_DARWIN:
18011 if (!TARGET_PROFILE_KERNEL)
18013 /* Don't do anything, done in output_profile_hook (). */
18015 else
18017 gcc_assert (!TARGET_32BIT);
18019 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
18020 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
18022 if (cfun->static_chain_decl != NULL)
18024 asm_fprintf (file, "\tstd %s,24(%s)\n",
18025 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
18026 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
18027 asm_fprintf (file, "\tld %s,24(%s)\n",
18028 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
18030 else
18031 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
18033 break;
18039 /* The following variable value is the last issued insn. */
18041 static rtx last_scheduled_insn;
18043 /* The following variable helps to balance issuing of load and
18044 store instructions */
18046 static int load_store_pendulum;
18048 /* Power4 load update and store update instructions are cracked into a
18049 load or store and an integer insn which are executed in the same cycle.
18050 Branches have their own dispatch slot which does not count against the
18051 GCC issue rate, but it changes the program flow so there are no other
18052 instructions to issue in this cycle. */
18054 static int
18055 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
18056 int verbose ATTRIBUTE_UNUSED,
18057 rtx insn, int more)
18059 last_scheduled_insn = insn;
18060 if (GET_CODE (PATTERN (insn)) == USE
18061 || GET_CODE (PATTERN (insn)) == CLOBBER)
18063 cached_can_issue_more = more;
18064 return cached_can_issue_more;
18067 if (insn_terminates_group_p (insn, current_group))
18069 cached_can_issue_more = 0;
18070 return cached_can_issue_more;
18073 /* If no reservation, but reach here */
18074 if (recog_memoized (insn) < 0)
18075 return more;
18077 if (rs6000_sched_groups)
18079 if (is_microcoded_insn (insn))
18080 cached_can_issue_more = 0;
18081 else if (is_cracked_insn (insn))
18082 cached_can_issue_more = more > 2 ? more - 2 : 0;
18083 else
18084 cached_can_issue_more = more - 1;
18086 return cached_can_issue_more;
18089 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
18090 return 0;
18092 cached_can_issue_more = more - 1;
18093 return cached_can_issue_more;
18096 /* Adjust the cost of a scheduling dependency. Return the new cost of
18097 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
18099 static int
18100 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
18102 enum attr_type attr_type;
18104 if (! recog_memoized (insn))
18105 return 0;
18107 switch (REG_NOTE_KIND (link))
18109 case REG_DEP_TRUE:
18111 /* Data dependency; DEP_INSN writes a register that INSN reads
18112 some cycles later. */
18114 /* Separate a load from a narrower, dependent store. */
18115 if (rs6000_sched_groups
18116 && GET_CODE (PATTERN (insn)) == SET
18117 && GET_CODE (PATTERN (dep_insn)) == SET
18118 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
18119 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
18120 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
18121 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
18122 return cost + 14;
18124 attr_type = get_attr_type (insn);
18126 switch (attr_type)
18128 case TYPE_JMPREG:
18129 /* Tell the first scheduling pass about the latency between
18130 a mtctr and bctr (and mtlr and br/blr). The first
18131 scheduling pass will not know about this latency since
18132 the mtctr instruction, which has the latency associated
18133 to it, will be generated by reload. */
18134 return TARGET_POWER ? 5 : 4;
18135 case TYPE_BRANCH:
18136 /* Leave some extra cycles between a compare and its
18137 dependent branch, to inhibit expensive mispredicts. */
18138 if ((rs6000_cpu_attr == CPU_PPC603
18139 || rs6000_cpu_attr == CPU_PPC604
18140 || rs6000_cpu_attr == CPU_PPC604E
18141 || rs6000_cpu_attr == CPU_PPC620
18142 || rs6000_cpu_attr == CPU_PPC630
18143 || rs6000_cpu_attr == CPU_PPC750
18144 || rs6000_cpu_attr == CPU_PPC7400
18145 || rs6000_cpu_attr == CPU_PPC7450
18146 || rs6000_cpu_attr == CPU_POWER4
18147 || rs6000_cpu_attr == CPU_POWER5
18148 || rs6000_cpu_attr == CPU_CELL)
18149 && recog_memoized (dep_insn)
18150 && (INSN_CODE (dep_insn) >= 0))
18152 switch (get_attr_type (dep_insn))
18154 case TYPE_CMP:
18155 case TYPE_COMPARE:
18156 case TYPE_DELAYED_COMPARE:
18157 case TYPE_IMUL_COMPARE:
18158 case TYPE_LMUL_COMPARE:
18159 case TYPE_FPCOMPARE:
18160 case TYPE_CR_LOGICAL:
18161 case TYPE_DELAYED_CR:
18162 return cost + 2;
18163 default:
18164 break;
18166 break;
18168 case TYPE_STORE:
18169 case TYPE_STORE_U:
18170 case TYPE_STORE_UX:
18171 case TYPE_FPSTORE:
18172 case TYPE_FPSTORE_U:
18173 case TYPE_FPSTORE_UX:
18174 if ((rs6000_cpu == PROCESSOR_POWER6)
18175 && recog_memoized (dep_insn)
18176 && (INSN_CODE (dep_insn) >= 0))
18179 if (GET_CODE (PATTERN (insn)) != SET)
18180 /* If this happens, we have to extend this to schedule
18181 optimally. Return default for now. */
18182 return cost;
18184 /* Adjust the cost for the case where the value written
18185 by a fixed point operation is used as the address
18186 gen value on a store. */
18187 switch (get_attr_type (dep_insn))
18189 case TYPE_LOAD:
18190 case TYPE_LOAD_U:
18191 case TYPE_LOAD_UX:
18192 case TYPE_CNTLZ:
18194 if (! store_data_bypass_p (dep_insn, insn))
18195 return 4;
18196 break;
18198 case TYPE_LOAD_EXT:
18199 case TYPE_LOAD_EXT_U:
18200 case TYPE_LOAD_EXT_UX:
18201 case TYPE_VAR_SHIFT_ROTATE:
18202 case TYPE_VAR_DELAYED_COMPARE:
18204 if (! store_data_bypass_p (dep_insn, insn))
18205 return 6;
18206 break;
18208 case TYPE_INTEGER:
18209 case TYPE_COMPARE:
18210 case TYPE_FAST_COMPARE:
18211 case TYPE_EXTS:
18212 case TYPE_SHIFT:
18213 case TYPE_INSERT_WORD:
18214 case TYPE_INSERT_DWORD:
18215 case TYPE_FPLOAD_U:
18216 case TYPE_FPLOAD_UX:
18217 case TYPE_STORE_U:
18218 case TYPE_STORE_UX:
18219 case TYPE_FPSTORE_U:
18220 case TYPE_FPSTORE_UX:
18222 if (! store_data_bypass_p (dep_insn, insn))
18223 return 3;
18224 break;
18226 case TYPE_IMUL:
18227 case TYPE_IMUL2:
18228 case TYPE_IMUL3:
18229 case TYPE_LMUL:
18230 case TYPE_IMUL_COMPARE:
18231 case TYPE_LMUL_COMPARE:
18233 if (! store_data_bypass_p (dep_insn, insn))
18234 return 17;
18235 break;
18237 case TYPE_IDIV:
18239 if (! store_data_bypass_p (dep_insn, insn))
18240 return 45;
18241 break;
18243 case TYPE_LDIV:
18245 if (! store_data_bypass_p (dep_insn, insn))
18246 return 57;
18247 break;
18249 default:
18250 break;
18253 break;
18255 case TYPE_LOAD:
18256 case TYPE_LOAD_U:
18257 case TYPE_LOAD_UX:
18258 case TYPE_LOAD_EXT:
18259 case TYPE_LOAD_EXT_U:
18260 case TYPE_LOAD_EXT_UX:
18261 if ((rs6000_cpu == PROCESSOR_POWER6)
18262 && recog_memoized (dep_insn)
18263 && (INSN_CODE (dep_insn) >= 0))
18266 /* Adjust the cost for the case where the value written
18267 by a fixed point instruction is used within the address
18268 gen portion of a subsequent load(u)(x) */
18269 switch (get_attr_type (dep_insn))
18271 case TYPE_LOAD:
18272 case TYPE_LOAD_U:
18273 case TYPE_LOAD_UX:
18274 case TYPE_CNTLZ:
18276 if (set_to_load_agen (dep_insn, insn))
18277 return 4;
18278 break;
18280 case TYPE_LOAD_EXT:
18281 case TYPE_LOAD_EXT_U:
18282 case TYPE_LOAD_EXT_UX:
18283 case TYPE_VAR_SHIFT_ROTATE:
18284 case TYPE_VAR_DELAYED_COMPARE:
18286 if (set_to_load_agen (dep_insn, insn))
18287 return 6;
18288 break;
18290 case TYPE_INTEGER:
18291 case TYPE_COMPARE:
18292 case TYPE_FAST_COMPARE:
18293 case TYPE_EXTS:
18294 case TYPE_SHIFT:
18295 case TYPE_INSERT_WORD:
18296 case TYPE_INSERT_DWORD:
18297 case TYPE_FPLOAD_U:
18298 case TYPE_FPLOAD_UX:
18299 case TYPE_STORE_U:
18300 case TYPE_STORE_UX:
18301 case TYPE_FPSTORE_U:
18302 case TYPE_FPSTORE_UX:
18304 if (set_to_load_agen (dep_insn, insn))
18305 return 3;
18306 break;
18308 case TYPE_IMUL:
18309 case TYPE_IMUL2:
18310 case TYPE_IMUL3:
18311 case TYPE_LMUL:
18312 case TYPE_IMUL_COMPARE:
18313 case TYPE_LMUL_COMPARE:
18315 if (set_to_load_agen (dep_insn, insn))
18316 return 17;
18317 break;
18319 case TYPE_IDIV:
18321 if (set_to_load_agen (dep_insn, insn))
18322 return 45;
18323 break;
18325 case TYPE_LDIV:
18327 if (set_to_load_agen (dep_insn, insn))
18328 return 57;
18329 break;
18331 default:
18332 break;
18335 break;
18337 case TYPE_FPLOAD:
18338 if ((rs6000_cpu == PROCESSOR_POWER6)
18339 && recog_memoized (dep_insn)
18340 && (INSN_CODE (dep_insn) >= 0)
18341 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
18342 return 2;
18344 default:
18345 break;
18348 /* Fall out to return default cost. */
18350 break;
18352 case REG_DEP_OUTPUT:
18353 /* Output dependency; DEP_INSN writes a register that INSN writes some
18354 cycles later. */
18355 if ((rs6000_cpu == PROCESSOR_POWER6)
18356 && recog_memoized (dep_insn)
18357 && (INSN_CODE (dep_insn) >= 0))
18359 attr_type = get_attr_type (insn);
18361 switch (attr_type)
18363 case TYPE_FP:
18364 if (get_attr_type (dep_insn) == TYPE_FP)
18365 return 1;
18366 break;
18367 case TYPE_FPLOAD:
18368 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
18369 return 2;
18370 break;
18371 default:
18372 break;
18375 case REG_DEP_ANTI:
18376 /* Anti dependency; DEP_INSN reads a register that INSN writes some
18377 cycles later. */
18378 return 0;
18380 default:
18381 gcc_unreachable ();
18384 return cost;
18387 /* The function returns a true if INSN is microcoded.
18388 Return false otherwise. */
18390 static bool
18391 is_microcoded_insn (rtx insn)
18393 if (!insn || !INSN_P (insn)
18394 || GET_CODE (PATTERN (insn)) == USE
18395 || GET_CODE (PATTERN (insn)) == CLOBBER)
18396 return false;
18398 if (rs6000_cpu_attr == CPU_CELL)
18399 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
18401 if (rs6000_sched_groups)
18403 enum attr_type type = get_attr_type (insn);
18404 if (type == TYPE_LOAD_EXT_U
18405 || type == TYPE_LOAD_EXT_UX
18406 || type == TYPE_LOAD_UX
18407 || type == TYPE_STORE_UX
18408 || type == TYPE_MFCR)
18409 return true;
18412 return false;
18415 /* The function returns true if INSN is cracked into 2 instructions
18416 by the processor (and therefore occupies 2 issue slots). */
18418 static bool
18419 is_cracked_insn (rtx insn)
18421 if (!insn || !INSN_P (insn)
18422 || GET_CODE (PATTERN (insn)) == USE
18423 || GET_CODE (PATTERN (insn)) == CLOBBER)
18424 return false;
18426 if (rs6000_sched_groups)
18428 enum attr_type type = get_attr_type (insn);
18429 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
18430 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
18431 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
18432 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
18433 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
18434 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
18435 || type == TYPE_IDIV || type == TYPE_LDIV
18436 || type == TYPE_INSERT_WORD)
18437 return true;
18440 return false;
18443 /* The function returns true if INSN can be issued only from
18444 the branch slot. */
18446 static bool
18447 is_branch_slot_insn (rtx insn)
18449 if (!insn || !INSN_P (insn)
18450 || GET_CODE (PATTERN (insn)) == USE
18451 || GET_CODE (PATTERN (insn)) == CLOBBER)
18452 return false;
18454 if (rs6000_sched_groups)
18456 enum attr_type type = get_attr_type (insn);
18457 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
18458 return true;
18459 return false;
18462 return false;
18465 /* The function returns true if out_inst sets a value that is
18466 used in the address generation computation of in_insn */
18467 static bool
18468 set_to_load_agen (rtx out_insn, rtx in_insn)
18470 rtx out_set, in_set;
18472 /* For performance reasons, only handle the simple case where
18473 both loads are a single_set. */
18474 out_set = single_set (out_insn);
18475 if (out_set)
18477 in_set = single_set (in_insn);
18478 if (in_set)
18479 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
18482 return false;
18485 /* The function returns true if the target storage location of
18486 out_insn is adjacent to the target storage location of in_insn */
18487 /* Return 1 if memory locations are adjacent. */
18489 static bool
18490 adjacent_mem_locations (rtx insn1, rtx insn2)
18493 rtx a = get_store_dest (PATTERN (insn1));
18494 rtx b = get_store_dest (PATTERN (insn2));
18496 if ((GET_CODE (XEXP (a, 0)) == REG
18497 || (GET_CODE (XEXP (a, 0)) == PLUS
18498 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
18499 && (GET_CODE (XEXP (b, 0)) == REG
18500 || (GET_CODE (XEXP (b, 0)) == PLUS
18501 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
18503 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
18504 rtx reg0, reg1;
18506 if (GET_CODE (XEXP (a, 0)) == PLUS)
18508 reg0 = XEXP (XEXP (a, 0), 0);
18509 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
18511 else
18512 reg0 = XEXP (a, 0);
18514 if (GET_CODE (XEXP (b, 0)) == PLUS)
18516 reg1 = XEXP (XEXP (b, 0), 0);
18517 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
18519 else
18520 reg1 = XEXP (b, 0);
18522 val_diff = val1 - val0;
18524 return ((REGNO (reg0) == REGNO (reg1))
18525 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
18526 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
18529 return false;
18532 /* A C statement (sans semicolon) to update the integer scheduling
18533 priority INSN_PRIORITY (INSN). Increase the priority to execute the
18534 INSN earlier, reduce the priority to execute INSN later. Do not
18535 define this macro if you do not need to adjust the scheduling
18536 priorities of insns. */
18538 static int
18539 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
18541 /* On machines (like the 750) which have asymmetric integer units,
18542 where one integer unit can do multiply and divides and the other
18543 can't, reduce the priority of multiply/divide so it is scheduled
18544 before other integer operations. */
18546 #if 0
18547 if (! INSN_P (insn))
18548 return priority;
18550 if (GET_CODE (PATTERN (insn)) == USE)
18551 return priority;
18553 switch (rs6000_cpu_attr) {
18554 case CPU_PPC750:
18555 switch (get_attr_type (insn))
18557 default:
18558 break;
18560 case TYPE_IMUL:
18561 case TYPE_IDIV:
18562 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
18563 priority, priority);
18564 if (priority >= 0 && priority < 0x01000000)
18565 priority >>= 3;
18566 break;
18569 #endif
18571 if (insn_must_be_first_in_group (insn)
18572 && reload_completed
18573 && current_sched_info->sched_max_insns_priority
18574 && rs6000_sched_restricted_insns_priority)
18577 /* Prioritize insns that can be dispatched only in the first
18578 dispatch slot. */
18579 if (rs6000_sched_restricted_insns_priority == 1)
18580 /* Attach highest priority to insn. This means that in
18581 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
18582 precede 'priority' (critical path) considerations. */
18583 return current_sched_info->sched_max_insns_priority;
18584 else if (rs6000_sched_restricted_insns_priority == 2)
18585 /* Increase priority of insn by a minimal amount. This means that in
18586 haifa-sched.c:ready_sort(), only 'priority' (critical path)
18587 considerations precede dispatch-slot restriction considerations. */
18588 return (priority + 1);
18591 if (rs6000_cpu == PROCESSOR_POWER6
18592 && ((load_store_pendulum == -2 && is_load_insn (insn))
18593 || (load_store_pendulum == 2 && is_store_insn (insn))))
18594 /* Attach highest priority to insn if the scheduler has just issued two
18595 stores and this instruction is a load, or two loads and this instruction
18596 is a store. Power6 wants loads and stores scheduled alternately
18597 when possible */
18598 return current_sched_info->sched_max_insns_priority;
18600 return priority;
18603 /* Return true if the instruction is nonpipelined on the Cell. */
18604 static bool
18605 is_nonpipeline_insn (rtx insn)
18607 enum attr_type type;
18608 if (!insn || !INSN_P (insn)
18609 || GET_CODE (PATTERN (insn)) == USE
18610 || GET_CODE (PATTERN (insn)) == CLOBBER)
18611 return false;
18613 type = get_attr_type (insn);
18614 if (type == TYPE_IMUL
18615 || type == TYPE_IMUL2
18616 || type == TYPE_IMUL3
18617 || type == TYPE_LMUL
18618 || type == TYPE_IDIV
18619 || type == TYPE_LDIV
18620 || type == TYPE_SDIV
18621 || type == TYPE_DDIV
18622 || type == TYPE_SSQRT
18623 || type == TYPE_DSQRT
18624 || type == TYPE_MFCR
18625 || type == TYPE_MFCRF
18626 || type == TYPE_MFJMPR)
18628 return true;
18630 return false;
18634 /* Return how many instructions the machine can issue per cycle. */
18636 static int
18637 rs6000_issue_rate (void)
18639 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
18640 if (!reload_completed)
18641 return 1;
18643 switch (rs6000_cpu_attr) {
18644 case CPU_RIOS1: /* ? */
18645 case CPU_RS64A:
18646 case CPU_PPC601: /* ? */
18647 case CPU_PPC7450:
18648 return 3;
18649 case CPU_PPC440:
18650 case CPU_PPC603:
18651 case CPU_PPC750:
18652 case CPU_PPC7400:
18653 case CPU_PPC8540:
18654 case CPU_CELL:
18655 case CPU_PPCE300C2:
18656 case CPU_PPCE300C3:
18657 return 2;
18658 case CPU_RIOS2:
18659 case CPU_PPC604:
18660 case CPU_PPC604E:
18661 case CPU_PPC620:
18662 case CPU_PPC630:
18663 return 4;
18664 case CPU_POWER4:
18665 case CPU_POWER5:
18666 case CPU_POWER6:
18667 return 5;
18668 default:
18669 return 1;
18673 /* Return how many instructions to look ahead for better insn
18674 scheduling. */
18676 static int
18677 rs6000_use_sched_lookahead (void)
18679 if (rs6000_cpu_attr == CPU_PPC8540)
18680 return 4;
18681 if (rs6000_cpu_attr == CPU_CELL)
18682 return (reload_completed ? 8 : 0);
18683 return 0;
18686 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
18687 static int
18688 rs6000_use_sched_lookahead_guard (rtx insn)
18690 if (rs6000_cpu_attr != CPU_CELL)
18691 return 1;
18693 if (insn == NULL_RTX || !INSN_P (insn))
18694 abort ();
18696 if (!reload_completed
18697 || is_nonpipeline_insn (insn)
18698 || is_microcoded_insn (insn))
18699 return 0;
18701 return 1;
18704 /* Determine is PAT refers to memory. */
18706 static bool
18707 is_mem_ref (rtx pat)
18709 const char * fmt;
18710 int i, j;
18711 bool ret = false;
18713 /* stack_tie does not produce any real memory traffic. */
18714 if (GET_CODE (pat) == UNSPEC
18715 && XINT (pat, 1) == UNSPEC_TIE)
18716 return false;
18718 if (GET_CODE (pat) == MEM)
18719 return true;
18721 /* Recursively process the pattern. */
18722 fmt = GET_RTX_FORMAT (GET_CODE (pat));
18724 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
18726 if (fmt[i] == 'e')
18727 ret |= is_mem_ref (XEXP (pat, i));
18728 else if (fmt[i] == 'E')
18729 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
18730 ret |= is_mem_ref (XVECEXP (pat, i, j));
18733 return ret;
18736 /* Determine if PAT is a PATTERN of a load insn. */
18738 static bool
18739 is_load_insn1 (rtx pat)
18741 if (!pat || pat == NULL_RTX)
18742 return false;
18744 if (GET_CODE (pat) == SET)
18745 return is_mem_ref (SET_SRC (pat));
18747 if (GET_CODE (pat) == PARALLEL)
18749 int i;
18751 for (i = 0; i < XVECLEN (pat, 0); i++)
18752 if (is_load_insn1 (XVECEXP (pat, 0, i)))
18753 return true;
18756 return false;
18759 /* Determine if INSN loads from memory. */
18761 static bool
18762 is_load_insn (rtx insn)
18764 if (!insn || !INSN_P (insn))
18765 return false;
18767 if (GET_CODE (insn) == CALL_INSN)
18768 return false;
18770 return is_load_insn1 (PATTERN (insn));
18773 /* Determine if PAT is a PATTERN of a store insn. */
18775 static bool
18776 is_store_insn1 (rtx pat)
18778 if (!pat || pat == NULL_RTX)
18779 return false;
18781 if (GET_CODE (pat) == SET)
18782 return is_mem_ref (SET_DEST (pat));
18784 if (GET_CODE (pat) == PARALLEL)
18786 int i;
18788 for (i = 0; i < XVECLEN (pat, 0); i++)
18789 if (is_store_insn1 (XVECEXP (pat, 0, i)))
18790 return true;
18793 return false;
18796 /* Determine if INSN stores to memory. */
18798 static bool
18799 is_store_insn (rtx insn)
18801 if (!insn || !INSN_P (insn))
18802 return false;
18804 return is_store_insn1 (PATTERN (insn));
18807 /* Return the dest of a store insn. */
18809 static rtx
18810 get_store_dest (rtx pat)
18812 gcc_assert (is_store_insn1 (pat));
18814 if (GET_CODE (pat) == SET)
18815 return SET_DEST (pat);
18816 else if (GET_CODE (pat) == PARALLEL)
18818 int i;
18820 for (i = 0; i < XVECLEN (pat, 0); i++)
18822 rtx inner_pat = XVECEXP (pat, 0, i);
18823 if (GET_CODE (inner_pat) == SET
18824 && is_mem_ref (SET_DEST (inner_pat)))
18825 return inner_pat;
18828 /* We shouldn't get here, because we should have either a simple
18829 store insn or a store with update which are covered above. */
18830 gcc_unreachable();
18833 /* Returns whether the dependence between INSN and NEXT is considered
18834 costly by the given target. */
18836 static bool
18837 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
18839 rtx insn;
18840 rtx next;
18842 /* If the flag is not enabled - no dependence is considered costly;
18843 allow all dependent insns in the same group.
18844 This is the most aggressive option. */
18845 if (rs6000_sched_costly_dep == no_dep_costly)
18846 return false;
18848 /* If the flag is set to 1 - a dependence is always considered costly;
18849 do not allow dependent instructions in the same group.
18850 This is the most conservative option. */
18851 if (rs6000_sched_costly_dep == all_deps_costly)
18852 return true;
18854 insn = DEP_PRO (dep);
18855 next = DEP_CON (dep);
18857 if (rs6000_sched_costly_dep == store_to_load_dep_costly
18858 && is_load_insn (next)
18859 && is_store_insn (insn))
18860 /* Prevent load after store in the same group. */
18861 return true;
18863 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
18864 && is_load_insn (next)
18865 && is_store_insn (insn)
18866 && DEP_TYPE (dep) == REG_DEP_TRUE)
18867 /* Prevent load after store in the same group if it is a true
18868 dependence. */
18869 return true;
18871 /* The flag is set to X; dependences with latency >= X are considered costly,
18872 and will not be scheduled in the same group. */
18873 if (rs6000_sched_costly_dep <= max_dep_latency
18874 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
18875 return true;
18877 return false;
18880 /* Return the next insn after INSN that is found before TAIL is reached,
18881 skipping any "non-active" insns - insns that will not actually occupy
18882 an issue slot. Return NULL_RTX if such an insn is not found. */
18884 static rtx
18885 get_next_active_insn (rtx insn, rtx tail)
18887 if (insn == NULL_RTX || insn == tail)
18888 return NULL_RTX;
18890 while (1)
18892 insn = NEXT_INSN (insn);
18893 if (insn == NULL_RTX || insn == tail)
18894 return NULL_RTX;
18896 if (CALL_P (insn)
18897 || JUMP_P (insn)
18898 || (NONJUMP_INSN_P (insn)
18899 && GET_CODE (PATTERN (insn)) != USE
18900 && GET_CODE (PATTERN (insn)) != CLOBBER
18901 && INSN_CODE (insn) != CODE_FOR_stack_tie))
18902 break;
18904 return insn;
18907 /* We are about to begin issuing insns for this clock cycle. */
18909 static int
18910 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
18911 rtx *ready ATTRIBUTE_UNUSED,
18912 int *pn_ready ATTRIBUTE_UNUSED,
18913 int clock_var ATTRIBUTE_UNUSED)
18915 int n_ready = *pn_ready;
18917 if (sched_verbose)
18918 fprintf (dump, "// rs6000_sched_reorder :\n");
18920 /* Reorder the ready list, if the second to last ready insn
18921 is a nonepipeline insn. */
18922 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
18924 if (is_nonpipeline_insn (ready[n_ready - 1])
18925 && (recog_memoized (ready[n_ready - 2]) > 0))
18926 /* Simply swap first two insns. */
18928 rtx tmp = ready[n_ready - 1];
18929 ready[n_ready - 1] = ready[n_ready - 2];
18930 ready[n_ready - 2] = tmp;
18934 if (rs6000_cpu == PROCESSOR_POWER6)
18935 load_store_pendulum = 0;
18937 return rs6000_issue_rate ();
18940 /* Like rs6000_sched_reorder, but called after issuing each insn. */
18942 static int
18943 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
18944 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
18946 if (sched_verbose)
18947 fprintf (dump, "// rs6000_sched_reorder2 :\n");
18949 /* For Power6, we need to handle some special cases to try and keep the
18950 store queue from overflowing and triggering expensive flushes.
18952 This code monitors how load and store instructions are being issued
18953 and skews the ready list one way or the other to increase the likelihood
18954 that a desired instruction is issued at the proper time.
18956 A couple of things are done. First, we maintain a "load_store_pendulum"
18957 to track the current state of load/store issue.
18959 - If the pendulum is at zero, then no loads or stores have been
18960 issued in the current cycle so we do nothing.
18962 - If the pendulum is 1, then a single load has been issued in this
18963 cycle and we attempt to locate another load in the ready list to
18964 issue with it.
18966 - If the pendulum is -2, then two stores have already been
18967 issued in this cycle, so we increase the priority of the first load
18968 in the ready list to increase it's likelihood of being chosen first
18969 in the next cycle.
18971 - If the pendulum is -1, then a single store has been issued in this
18972 cycle and we attempt to locate another store in the ready list to
18973 issue with it, preferring a store to an adjacent memory location to
18974 facilitate store pairing in the store queue.
18976 - If the pendulum is 2, then two loads have already been
18977 issued in this cycle, so we increase the priority of the first store
18978 in the ready list to increase it's likelihood of being chosen first
18979 in the next cycle.
18981 - If the pendulum < -2 or > 2, then do nothing.
18983 Note: This code covers the most common scenarios. There exist non
18984 load/store instructions which make use of the LSU and which
18985 would need to be accounted for to strictly model the behavior
18986 of the machine. Those instructions are currently unaccounted
18987 for to help minimize compile time overhead of this code.
18989 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
18991 int pos;
18992 int i;
18993 rtx tmp;
18995 if (is_store_insn (last_scheduled_insn))
18996 /* Issuing a store, swing the load_store_pendulum to the left */
18997 load_store_pendulum--;
18998 else if (is_load_insn (last_scheduled_insn))
18999 /* Issuing a load, swing the load_store_pendulum to the right */
19000 load_store_pendulum++;
19001 else
19002 return cached_can_issue_more;
19004 /* If the pendulum is balanced, or there is only one instruction on
19005 the ready list, then all is well, so return. */
19006 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
19007 return cached_can_issue_more;
19009 if (load_store_pendulum == 1)
19011 /* A load has been issued in this cycle. Scan the ready list
19012 for another load to issue with it */
19013 pos = *pn_ready-1;
19015 while (pos >= 0)
19017 if (is_load_insn (ready[pos]))
19019 /* Found a load. Move it to the head of the ready list,
19020 and adjust it's priority so that it is more likely to
19021 stay there */
19022 tmp = ready[pos];
19023 for (i=pos; i<*pn_ready-1; i++)
19024 ready[i] = ready[i + 1];
19025 ready[*pn_ready-1] = tmp;
19026 if INSN_PRIORITY_KNOWN (tmp)
19027 INSN_PRIORITY (tmp)++;
19028 break;
19030 pos--;
19033 else if (load_store_pendulum == -2)
19035 /* Two stores have been issued in this cycle. Increase the
19036 priority of the first load in the ready list to favor it for
19037 issuing in the next cycle. */
19038 pos = *pn_ready-1;
19040 while (pos >= 0)
19042 if (is_load_insn (ready[pos])
19043 && INSN_PRIORITY_KNOWN (ready[pos]))
19045 INSN_PRIORITY (ready[pos])++;
19047 /* Adjust the pendulum to account for the fact that a load
19048 was found and increased in priority. This is to prevent
19049 increasing the priority of multiple loads */
19050 load_store_pendulum--;
19052 break;
19054 pos--;
19057 else if (load_store_pendulum == -1)
19059 /* A store has been issued in this cycle. Scan the ready list for
19060 another store to issue with it, preferring a store to an adjacent
19061 memory location */
19062 int first_store_pos = -1;
19064 pos = *pn_ready-1;
19066 while (pos >= 0)
19068 if (is_store_insn (ready[pos]))
19070 /* Maintain the index of the first store found on the
19071 list */
19072 if (first_store_pos == -1)
19073 first_store_pos = pos;
19075 if (is_store_insn (last_scheduled_insn)
19076 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
19078 /* Found an adjacent store. Move it to the head of the
19079 ready list, and adjust it's priority so that it is
19080 more likely to stay there */
19081 tmp = ready[pos];
19082 for (i=pos; i<*pn_ready-1; i++)
19083 ready[i] = ready[i + 1];
19084 ready[*pn_ready-1] = tmp;
19085 if INSN_PRIORITY_KNOWN (tmp)
19086 INSN_PRIORITY (tmp)++;
19087 first_store_pos = -1;
19089 break;
19092 pos--;
19095 if (first_store_pos >= 0)
19097 /* An adjacent store wasn't found, but a non-adjacent store was,
19098 so move the non-adjacent store to the front of the ready
19099 list, and adjust its priority so that it is more likely to
19100 stay there. */
19101 tmp = ready[first_store_pos];
19102 for (i=first_store_pos; i<*pn_ready-1; i++)
19103 ready[i] = ready[i + 1];
19104 ready[*pn_ready-1] = tmp;
19105 if INSN_PRIORITY_KNOWN (tmp)
19106 INSN_PRIORITY (tmp)++;
19109 else if (load_store_pendulum == 2)
19111 /* Two loads have been issued in this cycle. Increase the priority
19112 of the first store in the ready list to favor it for issuing in
19113 the next cycle. */
19114 pos = *pn_ready-1;
19116 while (pos >= 0)
19118 if (is_store_insn (ready[pos])
19119 && INSN_PRIORITY_KNOWN (ready[pos]))
19121 INSN_PRIORITY (ready[pos])++;
19123 /* Adjust the pendulum to account for the fact that a store
19124 was found and increased in priority. This is to prevent
19125 increasing the priority of multiple stores */
19126 load_store_pendulum++;
19128 break;
19130 pos--;
19135 return cached_can_issue_more;
19138 /* Return whether the presence of INSN causes a dispatch group termination
19139 of group WHICH_GROUP.
19141 If WHICH_GROUP == current_group, this function will return true if INSN
19142 causes the termination of the current group (i.e, the dispatch group to
19143 which INSN belongs). This means that INSN will be the last insn in the
19144 group it belongs to.
19146 If WHICH_GROUP == previous_group, this function will return true if INSN
19147 causes the termination of the previous group (i.e, the dispatch group that
19148 precedes the group to which INSN belongs). This means that INSN will be
19149 the first insn in the group it belongs to). */
19151 static bool
19152 insn_terminates_group_p (rtx insn, enum group_termination which_group)
19154 bool first, last;
19156 if (! insn)
19157 return false;
19159 first = insn_must_be_first_in_group (insn);
19160 last = insn_must_be_last_in_group (insn);
19162 if (first && last)
19163 return true;
19165 if (which_group == current_group)
19166 return last;
19167 else if (which_group == previous_group)
19168 return first;
19170 return false;
19174 static bool
19175 insn_must_be_first_in_group (rtx insn)
19177 enum attr_type type;
19179 if (!insn
19180 || insn == NULL_RTX
19181 || GET_CODE (insn) == NOTE
19182 || GET_CODE (PATTERN (insn)) == USE
19183 || GET_CODE (PATTERN (insn)) == CLOBBER)
19184 return false;
19186 switch (rs6000_cpu)
19188 case PROCESSOR_POWER5:
19189 if (is_cracked_insn (insn))
19190 return true;
19191 case PROCESSOR_POWER4:
19192 if (is_microcoded_insn (insn))
19193 return true;
19195 if (!rs6000_sched_groups)
19196 return false;
19198 type = get_attr_type (insn);
19200 switch (type)
19202 case TYPE_MFCR:
19203 case TYPE_MFCRF:
19204 case TYPE_MTCR:
19205 case TYPE_DELAYED_CR:
19206 case TYPE_CR_LOGICAL:
19207 case TYPE_MTJMPR:
19208 case TYPE_MFJMPR:
19209 case TYPE_IDIV:
19210 case TYPE_LDIV:
19211 case TYPE_LOAD_L:
19212 case TYPE_STORE_C:
19213 case TYPE_ISYNC:
19214 case TYPE_SYNC:
19215 return true;
19216 default:
19217 break;
19219 break;
19220 case PROCESSOR_POWER6:
19221 type = get_attr_type (insn);
19223 switch (type)
19225 case TYPE_INSERT_DWORD:
19226 case TYPE_EXTS:
19227 case TYPE_CNTLZ:
19228 case TYPE_SHIFT:
19229 case TYPE_VAR_SHIFT_ROTATE:
19230 case TYPE_TRAP:
19231 case TYPE_IMUL:
19232 case TYPE_IMUL2:
19233 case TYPE_IMUL3:
19234 case TYPE_LMUL:
19235 case TYPE_IDIV:
19236 case TYPE_INSERT_WORD:
19237 case TYPE_DELAYED_COMPARE:
19238 case TYPE_IMUL_COMPARE:
19239 case TYPE_LMUL_COMPARE:
19240 case TYPE_FPCOMPARE:
19241 case TYPE_MFCR:
19242 case TYPE_MTCR:
19243 case TYPE_MFJMPR:
19244 case TYPE_MTJMPR:
19245 case TYPE_ISYNC:
19246 case TYPE_SYNC:
19247 case TYPE_LOAD_L:
19248 case TYPE_STORE_C:
19249 case TYPE_LOAD_U:
19250 case TYPE_LOAD_UX:
19251 case TYPE_LOAD_EXT_UX:
19252 case TYPE_STORE_U:
19253 case TYPE_STORE_UX:
19254 case TYPE_FPLOAD_U:
19255 case TYPE_FPLOAD_UX:
19256 case TYPE_FPSTORE_U:
19257 case TYPE_FPSTORE_UX:
19258 return true;
19259 default:
19260 break;
19262 break;
19263 default:
19264 break;
19267 return false;
19270 static bool
19271 insn_must_be_last_in_group (rtx insn)
19273 enum attr_type type;
19275 if (!insn
19276 || insn == NULL_RTX
19277 || GET_CODE (insn) == NOTE
19278 || GET_CODE (PATTERN (insn)) == USE
19279 || GET_CODE (PATTERN (insn)) == CLOBBER)
19280 return false;
19282 switch (rs6000_cpu) {
19283 case PROCESSOR_POWER4:
19284 case PROCESSOR_POWER5:
19285 if (is_microcoded_insn (insn))
19286 return true;
19288 if (is_branch_slot_insn (insn))
19289 return true;
19291 break;
19292 case PROCESSOR_POWER6:
19293 type = get_attr_type (insn);
19295 switch (type)
19297 case TYPE_EXTS:
19298 case TYPE_CNTLZ:
19299 case TYPE_SHIFT:
19300 case TYPE_VAR_SHIFT_ROTATE:
19301 case TYPE_TRAP:
19302 case TYPE_IMUL:
19303 case TYPE_IMUL2:
19304 case TYPE_IMUL3:
19305 case TYPE_LMUL:
19306 case TYPE_IDIV:
19307 case TYPE_DELAYED_COMPARE:
19308 case TYPE_IMUL_COMPARE:
19309 case TYPE_LMUL_COMPARE:
19310 case TYPE_FPCOMPARE:
19311 case TYPE_MFCR:
19312 case TYPE_MTCR:
19313 case TYPE_MFJMPR:
19314 case TYPE_MTJMPR:
19315 case TYPE_ISYNC:
19316 case TYPE_SYNC:
19317 case TYPE_LOAD_L:
19318 case TYPE_STORE_C:
19319 return true;
19320 default:
19321 break;
19323 break;
19324 default:
19325 break;
19328 return false;
19331 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
19332 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
19334 static bool
19335 is_costly_group (rtx *group_insns, rtx next_insn)
19337 int i;
19338 int issue_rate = rs6000_issue_rate ();
19340 for (i = 0; i < issue_rate; i++)
19342 sd_iterator_def sd_it;
19343 dep_t dep;
19344 rtx insn = group_insns[i];
19346 if (!insn)
19347 continue;
19349 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
19351 rtx next = DEP_CON (dep);
19353 if (next == next_insn
19354 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
19355 return true;
19359 return false;
19362 /* Utility of the function redefine_groups.
19363 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
19364 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
19365 to keep it "far" (in a separate group) from GROUP_INSNS, following
19366 one of the following schemes, depending on the value of the flag
19367 -minsert_sched_nops = X:
19368 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
19369 in order to force NEXT_INSN into a separate group.
19370 (2) X < sched_finish_regroup_exact: insert exactly X nops.
19371 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
19372 insertion (has a group just ended, how many vacant issue slots remain in the
19373 last group, and how many dispatch groups were encountered so far). */
19375 static int
19376 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
19377 rtx next_insn, bool *group_end, int can_issue_more,
19378 int *group_count)
19380 rtx nop;
19381 bool force;
19382 int issue_rate = rs6000_issue_rate ();
19383 bool end = *group_end;
19384 int i;
19386 if (next_insn == NULL_RTX)
19387 return can_issue_more;
19389 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
19390 return can_issue_more;
19392 force = is_costly_group (group_insns, next_insn);
19393 if (!force)
19394 return can_issue_more;
19396 if (sched_verbose > 6)
19397 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
19398 *group_count ,can_issue_more);
19400 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
19402 if (*group_end)
19403 can_issue_more = 0;
19405 /* Since only a branch can be issued in the last issue_slot, it is
19406 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
19407 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
19408 in this case the last nop will start a new group and the branch
19409 will be forced to the new group. */
19410 if (can_issue_more && !is_branch_slot_insn (next_insn))
19411 can_issue_more--;
19413 while (can_issue_more > 0)
19415 nop = gen_nop ();
19416 emit_insn_before (nop, next_insn);
19417 can_issue_more--;
19420 *group_end = true;
19421 return 0;
19424 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
19426 int n_nops = rs6000_sched_insert_nops;
19428 /* Nops can't be issued from the branch slot, so the effective
19429 issue_rate for nops is 'issue_rate - 1'. */
19430 if (can_issue_more == 0)
19431 can_issue_more = issue_rate;
19432 can_issue_more--;
19433 if (can_issue_more == 0)
19435 can_issue_more = issue_rate - 1;
19436 (*group_count)++;
19437 end = true;
19438 for (i = 0; i < issue_rate; i++)
19440 group_insns[i] = 0;
19444 while (n_nops > 0)
19446 nop = gen_nop ();
19447 emit_insn_before (nop, next_insn);
19448 if (can_issue_more == issue_rate - 1) /* new group begins */
19449 end = false;
19450 can_issue_more--;
19451 if (can_issue_more == 0)
19453 can_issue_more = issue_rate - 1;
19454 (*group_count)++;
19455 end = true;
19456 for (i = 0; i < issue_rate; i++)
19458 group_insns[i] = 0;
19461 n_nops--;
19464 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
19465 can_issue_more++;
19467 /* Is next_insn going to start a new group? */
19468 *group_end
19469 = (end
19470 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
19471 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
19472 || (can_issue_more < issue_rate &&
19473 insn_terminates_group_p (next_insn, previous_group)));
19474 if (*group_end && end)
19475 (*group_count)--;
19477 if (sched_verbose > 6)
19478 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
19479 *group_count, can_issue_more);
19480 return can_issue_more;
19483 return can_issue_more;
19486 /* This function tries to synch the dispatch groups that the compiler "sees"
19487 with the dispatch groups that the processor dispatcher is expected to
19488 form in practice. It tries to achieve this synchronization by forcing the
19489 estimated processor grouping on the compiler (as opposed to the function
19490 'pad_goups' which tries to force the scheduler's grouping on the processor).
19492 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
19493 examines the (estimated) dispatch groups that will be formed by the processor
19494 dispatcher. It marks these group boundaries to reflect the estimated
19495 processor grouping, overriding the grouping that the scheduler had marked.
19496 Depending on the value of the flag '-minsert-sched-nops' this function can
19497 force certain insns into separate groups or force a certain distance between
19498 them by inserting nops, for example, if there exists a "costly dependence"
19499 between the insns.
19501 The function estimates the group boundaries that the processor will form as
19502 follows: It keeps track of how many vacant issue slots are available after
19503 each insn. A subsequent insn will start a new group if one of the following
19504 4 cases applies:
19505 - no more vacant issue slots remain in the current dispatch group.
19506 - only the last issue slot, which is the branch slot, is vacant, but the next
19507 insn is not a branch.
19508 - only the last 2 or less issue slots, including the branch slot, are vacant,
19509 which means that a cracked insn (which occupies two issue slots) can't be
19510 issued in this group.
19511 - less than 'issue_rate' slots are vacant, and the next insn always needs to
19512 start a new group. */
19514 static int
19515 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
19517 rtx insn, next_insn;
19518 int issue_rate;
19519 int can_issue_more;
19520 int slot, i;
19521 bool group_end;
19522 int group_count = 0;
19523 rtx *group_insns;
19525 /* Initialize. */
19526 issue_rate = rs6000_issue_rate ();
19527 group_insns = alloca (issue_rate * sizeof (rtx));
19528 for (i = 0; i < issue_rate; i++)
19530 group_insns[i] = 0;
19532 can_issue_more = issue_rate;
19533 slot = 0;
19534 insn = get_next_active_insn (prev_head_insn, tail);
19535 group_end = false;
19537 while (insn != NULL_RTX)
19539 slot = (issue_rate - can_issue_more);
19540 group_insns[slot] = insn;
19541 can_issue_more =
19542 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
19543 if (insn_terminates_group_p (insn, current_group))
19544 can_issue_more = 0;
19546 next_insn = get_next_active_insn (insn, tail);
19547 if (next_insn == NULL_RTX)
19548 return group_count + 1;
19550 /* Is next_insn going to start a new group? */
19551 group_end
19552 = (can_issue_more == 0
19553 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
19554 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
19555 || (can_issue_more < issue_rate &&
19556 insn_terminates_group_p (next_insn, previous_group)));
19558 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
19559 next_insn, &group_end, can_issue_more,
19560 &group_count);
19562 if (group_end)
19564 group_count++;
19565 can_issue_more = 0;
19566 for (i = 0; i < issue_rate; i++)
19568 group_insns[i] = 0;
19572 if (GET_MODE (next_insn) == TImode && can_issue_more)
19573 PUT_MODE (next_insn, VOIDmode);
19574 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
19575 PUT_MODE (next_insn, TImode);
19577 insn = next_insn;
19578 if (can_issue_more == 0)
19579 can_issue_more = issue_rate;
19580 } /* while */
19582 return group_count;
19585 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
19586 dispatch group boundaries that the scheduler had marked. Pad with nops
19587 any dispatch groups which have vacant issue slots, in order to force the
19588 scheduler's grouping on the processor dispatcher. The function
19589 returns the number of dispatch groups found. */
19591 static int
19592 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
19594 rtx insn, next_insn;
19595 rtx nop;
19596 int issue_rate;
19597 int can_issue_more;
19598 int group_end;
19599 int group_count = 0;
19601 /* Initialize issue_rate. */
19602 issue_rate = rs6000_issue_rate ();
19603 can_issue_more = issue_rate;
19605 insn = get_next_active_insn (prev_head_insn, tail);
19606 next_insn = get_next_active_insn (insn, tail);
19608 while (insn != NULL_RTX)
19610 can_issue_more =
19611 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
19613 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
19615 if (next_insn == NULL_RTX)
19616 break;
19618 if (group_end)
19620 /* If the scheduler had marked group termination at this location
19621 (between insn and next_indn), and neither insn nor next_insn will
19622 force group termination, pad the group with nops to force group
19623 termination. */
19624 if (can_issue_more
19625 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
19626 && !insn_terminates_group_p (insn, current_group)
19627 && !insn_terminates_group_p (next_insn, previous_group))
19629 if (!is_branch_slot_insn (next_insn))
19630 can_issue_more--;
19632 while (can_issue_more)
19634 nop = gen_nop ();
19635 emit_insn_before (nop, next_insn);
19636 can_issue_more--;
19640 can_issue_more = issue_rate;
19641 group_count++;
19644 insn = next_insn;
19645 next_insn = get_next_active_insn (insn, tail);
19648 return group_count;
19651 /* We're beginning a new block. Initialize data structures as necessary. */
19653 static void
19654 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
19655 int sched_verbose ATTRIBUTE_UNUSED,
19656 int max_ready ATTRIBUTE_UNUSED)
19658 last_scheduled_insn = NULL_RTX;
19659 load_store_pendulum = 0;
19662 /* The following function is called at the end of scheduling BB.
19663 After reload, it inserts nops at insn group bundling. */
19665 static void
19666 rs6000_sched_finish (FILE *dump, int sched_verbose)
19668 int n_groups;
19670 if (sched_verbose)
19671 fprintf (dump, "=== Finishing schedule.\n");
19673 if (reload_completed && rs6000_sched_groups)
19675 if (rs6000_sched_insert_nops == sched_finish_none)
19676 return;
19678 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
19679 n_groups = pad_groups (dump, sched_verbose,
19680 current_sched_info->prev_head,
19681 current_sched_info->next_tail);
19682 else
19683 n_groups = redefine_groups (dump, sched_verbose,
19684 current_sched_info->prev_head,
19685 current_sched_info->next_tail);
19687 if (sched_verbose >= 6)
19689 fprintf (dump, "ngroups = %d\n", n_groups);
19690 print_rtl (dump, current_sched_info->prev_head);
19691 fprintf (dump, "Done finish_sched\n");
19696 /* Length in units of the trampoline for entering a nested function. */
19699 rs6000_trampoline_size (void)
19701 int ret = 0;
19703 switch (DEFAULT_ABI)
19705 default:
19706 gcc_unreachable ();
19708 case ABI_AIX:
19709 ret = (TARGET_32BIT) ? 12 : 24;
19710 break;
19712 case ABI_DARWIN:
19713 case ABI_V4:
19714 ret = (TARGET_32BIT) ? 40 : 48;
19715 break;
19718 return ret;
19721 /* Emit RTL insns to initialize the variable parts of a trampoline.
19722 FNADDR is an RTX for the address of the function's pure code.
19723 CXT is an RTX for the static chain value for the function. */
19725 void
19726 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
19728 int regsize = (TARGET_32BIT) ? 4 : 8;
19729 rtx ctx_reg = force_reg (Pmode, cxt);
19731 switch (DEFAULT_ABI)
19733 default:
19734 gcc_unreachable ();
19736 /* Macros to shorten the code expansions below. */
19737 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
19738 #define MEM_PLUS(addr,offset) \
19739 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
19741 /* Under AIX, just build the 3 word function descriptor */
19742 case ABI_AIX:
19744 rtx fn_reg = gen_reg_rtx (Pmode);
19745 rtx toc_reg = gen_reg_rtx (Pmode);
19746 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
19747 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
19748 emit_move_insn (MEM_DEREF (addr), fn_reg);
19749 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
19750 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
19752 break;
19754 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
19755 case ABI_DARWIN:
19756 case ABI_V4:
19757 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
19758 FALSE, VOIDmode, 4,
19759 addr, Pmode,
19760 GEN_INT (rs6000_trampoline_size ()), SImode,
19761 fnaddr, Pmode,
19762 ctx_reg, Pmode);
19763 break;
19766 return;
19770 /* Table of valid machine attributes. */
19772 const struct attribute_spec rs6000_attribute_table[] =
19774 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
19775 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
19776 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
19777 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
19778 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
19779 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
19780 #ifdef SUBTARGET_ATTRIBUTE_TABLE
19781 SUBTARGET_ATTRIBUTE_TABLE,
19782 #endif
19783 { NULL, 0, 0, false, false, false, NULL }
19786 /* Handle the "altivec" attribute. The attribute may have
19787 arguments as follows:
19789 __attribute__((altivec(vector__)))
19790 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
19791 __attribute__((altivec(bool__))) (always followed by 'unsigned')
19793 and may appear more than once (e.g., 'vector bool char') in a
19794 given declaration. */
19796 static tree
19797 rs6000_handle_altivec_attribute (tree *node,
19798 tree name ATTRIBUTE_UNUSED,
19799 tree args,
19800 int flags ATTRIBUTE_UNUSED,
19801 bool *no_add_attrs)
19803 tree type = *node, result = NULL_TREE;
19804 enum machine_mode mode;
19805 int unsigned_p;
19806 char altivec_type
19807 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
19808 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
19809 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
19810 : '?');
19812 while (POINTER_TYPE_P (type)
19813 || TREE_CODE (type) == FUNCTION_TYPE
19814 || TREE_CODE (type) == METHOD_TYPE
19815 || TREE_CODE (type) == ARRAY_TYPE)
19816 type = TREE_TYPE (type);
19818 mode = TYPE_MODE (type);
19820 /* Check for invalid AltiVec type qualifiers. */
19821 if (type == long_unsigned_type_node || type == long_integer_type_node)
19823 if (TARGET_64BIT)
19824 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
19825 else if (rs6000_warn_altivec_long)
19826 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
19828 else if (type == long_long_unsigned_type_node
19829 || type == long_long_integer_type_node)
19830 error ("use of %<long long%> in AltiVec types is invalid");
19831 else if (type == double_type_node)
19832 error ("use of %<double%> in AltiVec types is invalid");
19833 else if (type == long_double_type_node)
19834 error ("use of %<long double%> in AltiVec types is invalid");
19835 else if (type == boolean_type_node)
19836 error ("use of boolean types in AltiVec types is invalid");
19837 else if (TREE_CODE (type) == COMPLEX_TYPE)
19838 error ("use of %<complex%> in AltiVec types is invalid");
19839 else if (DECIMAL_FLOAT_MODE_P (mode))
19840 error ("use of decimal floating point types in AltiVec types is invalid");
19842 switch (altivec_type)
19844 case 'v':
19845 unsigned_p = TYPE_UNSIGNED (type);
19846 switch (mode)
19848 case SImode:
19849 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
19850 break;
19851 case HImode:
19852 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
19853 break;
19854 case QImode:
19855 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
19856 break;
19857 case SFmode: result = V4SF_type_node; break;
19858 /* If the user says 'vector int bool', we may be handed the 'bool'
19859 attribute _before_ the 'vector' attribute, and so select the
19860 proper type in the 'b' case below. */
19861 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
19862 result = type;
19863 default: break;
19865 break;
19866 case 'b':
19867 switch (mode)
19869 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
19870 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
19871 case QImode: case V16QImode: result = bool_V16QI_type_node;
19872 default: break;
19874 break;
19875 case 'p':
19876 switch (mode)
19878 case V8HImode: result = pixel_V8HI_type_node;
19879 default: break;
19881 default: break;
19884 if (result && result != type && TYPE_READONLY (type))
19885 result = build_qualified_type (result, TYPE_QUAL_CONST);
19887 *no_add_attrs = true; /* No need to hang on to the attribute. */
19889 if (result)
19890 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
19892 return NULL_TREE;
19895 /* AltiVec defines four built-in scalar types that serve as vector
19896 elements; we must teach the compiler how to mangle them. */
19898 static const char *
19899 rs6000_mangle_type (const_tree type)
19901 type = TYPE_MAIN_VARIANT (type);
19903 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
19904 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
19905 return NULL;
19907 if (type == bool_char_type_node) return "U6__boolc";
19908 if (type == bool_short_type_node) return "U6__bools";
19909 if (type == pixel_type_node) return "u7__pixel";
19910 if (type == bool_int_type_node) return "U6__booli";
19912 /* Mangle IBM extended float long double as `g' (__float128) on
19913 powerpc*-linux where long-double-64 previously was the default. */
19914 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
19915 && TARGET_ELF
19916 && TARGET_LONG_DOUBLE_128
19917 && !TARGET_IEEEQUAD)
19918 return "g";
19920 /* For all other types, use normal C++ mangling. */
19921 return NULL;
19924 /* Handle a "longcall" or "shortcall" attribute; arguments as in
19925 struct attribute_spec.handler. */
19927 static tree
19928 rs6000_handle_longcall_attribute (tree *node, tree name,
19929 tree args ATTRIBUTE_UNUSED,
19930 int flags ATTRIBUTE_UNUSED,
19931 bool *no_add_attrs)
19933 if (TREE_CODE (*node) != FUNCTION_TYPE
19934 && TREE_CODE (*node) != FIELD_DECL
19935 && TREE_CODE (*node) != TYPE_DECL)
19937 warning (OPT_Wattributes, "%qs attribute only applies to functions",
19938 IDENTIFIER_POINTER (name));
19939 *no_add_attrs = true;
19942 return NULL_TREE;
19945 /* Set longcall attributes on all functions declared when
19946 rs6000_default_long_calls is true. */
19947 static void
19948 rs6000_set_default_type_attributes (tree type)
19950 if (rs6000_default_long_calls
19951 && (TREE_CODE (type) == FUNCTION_TYPE
19952 || TREE_CODE (type) == METHOD_TYPE))
19953 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
19954 NULL_TREE,
19955 TYPE_ATTRIBUTES (type));
19957 #if TARGET_MACHO
19958 darwin_set_default_type_attributes (type);
19959 #endif
19962 /* Return a reference suitable for calling a function with the
19963 longcall attribute. */
19966 rs6000_longcall_ref (rtx call_ref)
19968 const char *call_name;
19969 tree node;
19971 if (GET_CODE (call_ref) != SYMBOL_REF)
19972 return call_ref;
19974 /* System V adds '.' to the internal name, so skip them. */
19975 call_name = XSTR (call_ref, 0);
19976 if (*call_name == '.')
19978 while (*call_name == '.')
19979 call_name++;
19981 node = get_identifier (call_name);
19982 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
19985 return force_reg (Pmode, call_ref);
19988 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
19989 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
19990 #endif
19992 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
19993 struct attribute_spec.handler. */
19994 static tree
19995 rs6000_handle_struct_attribute (tree *node, tree name,
19996 tree args ATTRIBUTE_UNUSED,
19997 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
19999 tree *type = NULL;
20000 if (DECL_P (*node))
20002 if (TREE_CODE (*node) == TYPE_DECL)
20003 type = &TREE_TYPE (*node);
20005 else
20006 type = node;
20008 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
20009 || TREE_CODE (*type) == UNION_TYPE)))
20011 warning (OPT_Wattributes, "%qs attribute ignored", IDENTIFIER_POINTER (name));
20012 *no_add_attrs = true;
20015 else if ((is_attribute_p ("ms_struct", name)
20016 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
20017 || ((is_attribute_p ("gcc_struct", name)
20018 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
20020 warning (OPT_Wattributes, "%qs incompatible attribute ignored",
20021 IDENTIFIER_POINTER (name));
20022 *no_add_attrs = true;
20025 return NULL_TREE;
20028 static bool
20029 rs6000_ms_bitfield_layout_p (const_tree record_type)
20031 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
20032 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
20033 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
20036 #ifdef USING_ELFOS_H
20038 /* A get_unnamed_section callback, used for switching to toc_section. */
20040 static void
20041 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
20043 if (DEFAULT_ABI == ABI_AIX
20044 && TARGET_MINIMAL_TOC
20045 && !TARGET_RELOCATABLE)
20047 if (!toc_initialized)
20049 toc_initialized = 1;
20050 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
20051 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
20052 fprintf (asm_out_file, "\t.tc ");
20053 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
20054 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
20055 fprintf (asm_out_file, "\n");
20057 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20058 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
20059 fprintf (asm_out_file, " = .+32768\n");
20061 else
20062 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20064 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
20065 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
20066 else
20068 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20069 if (!toc_initialized)
20071 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
20072 fprintf (asm_out_file, " = .+32768\n");
20073 toc_initialized = 1;
20078 /* Implement TARGET_ASM_INIT_SECTIONS. */
20080 static void
20081 rs6000_elf_asm_init_sections (void)
20083 toc_section
20084 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
20086 sdata2_section
20087 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
20088 SDATA2_SECTION_ASM_OP);
20091 /* Implement TARGET_SELECT_RTX_SECTION. */
20093 static section *
20094 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
20095 unsigned HOST_WIDE_INT align)
20097 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
20098 return toc_section;
20099 else
20100 return default_elf_select_rtx_section (mode, x, align);
20103 /* For a SYMBOL_REF, set generic flags and then perform some
20104 target-specific processing.
20106 When the AIX ABI is requested on a non-AIX system, replace the
20107 function name with the real name (with a leading .) rather than the
20108 function descriptor name. This saves a lot of overriding code to
20109 read the prefixes. */
20111 static void
20112 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
20114 default_encode_section_info (decl, rtl, first);
20116 if (first
20117 && TREE_CODE (decl) == FUNCTION_DECL
20118 && !TARGET_AIX
20119 && DEFAULT_ABI == ABI_AIX)
20121 rtx sym_ref = XEXP (rtl, 0);
20122 size_t len = strlen (XSTR (sym_ref, 0));
20123 char *str = alloca (len + 2);
20124 str[0] = '.';
20125 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
20126 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
20130 static inline bool
20131 compare_section_name (const char *section, const char *template)
20133 int len;
20135 len = strlen (template);
20136 return (strncmp (section, template, len) == 0
20137 && (section[len] == 0 || section[len] == '.'));
20140 bool
20141 rs6000_elf_in_small_data_p (const_tree decl)
20143 if (rs6000_sdata == SDATA_NONE)
20144 return false;
20146 /* We want to merge strings, so we never consider them small data. */
20147 if (TREE_CODE (decl) == STRING_CST)
20148 return false;
20150 /* Functions are never in the small data area. */
20151 if (TREE_CODE (decl) == FUNCTION_DECL)
20152 return false;
20154 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
20156 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
20157 if (compare_section_name (section, ".sdata")
20158 || compare_section_name (section, ".sdata2")
20159 || compare_section_name (section, ".gnu.linkonce.s")
20160 || compare_section_name (section, ".sbss")
20161 || compare_section_name (section, ".sbss2")
20162 || compare_section_name (section, ".gnu.linkonce.sb")
20163 || strcmp (section, ".PPC.EMB.sdata0") == 0
20164 || strcmp (section, ".PPC.EMB.sbss0") == 0)
20165 return true;
20167 else
20169 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
20171 if (size > 0
20172 && (unsigned HOST_WIDE_INT) size <= g_switch_value
20173 /* If it's not public, and we're not going to reference it there,
20174 there's no need to put it in the small data section. */
20175 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
20176 return true;
20179 return false;
20182 #endif /* USING_ELFOS_H */
20184 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
20186 static bool
20187 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
20189 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
20192 /* Return a REG that occurs in ADDR with coefficient 1.
20193 ADDR can be effectively incremented by incrementing REG.
20195 r0 is special and we must not select it as an address
20196 register by this routine since our caller will try to
20197 increment the returned register via an "la" instruction. */
20200 find_addr_reg (rtx addr)
20202 while (GET_CODE (addr) == PLUS)
20204 if (GET_CODE (XEXP (addr, 0)) == REG
20205 && REGNO (XEXP (addr, 0)) != 0)
20206 addr = XEXP (addr, 0);
20207 else if (GET_CODE (XEXP (addr, 1)) == REG
20208 && REGNO (XEXP (addr, 1)) != 0)
20209 addr = XEXP (addr, 1);
20210 else if (CONSTANT_P (XEXP (addr, 0)))
20211 addr = XEXP (addr, 1);
20212 else if (CONSTANT_P (XEXP (addr, 1)))
20213 addr = XEXP (addr, 0);
20214 else
20215 gcc_unreachable ();
20217 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
20218 return addr;
20221 void
20222 rs6000_fatal_bad_address (rtx op)
20224 fatal_insn ("bad address", op);
20227 #if TARGET_MACHO
20229 static tree branch_island_list = 0;
20231 /* Remember to generate a branch island for far calls to the given
20232 function. */
20234 static void
20235 add_compiler_branch_island (tree label_name, tree function_name,
20236 int line_number)
20238 tree branch_island = build_tree_list (function_name, label_name);
20239 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
20240 TREE_CHAIN (branch_island) = branch_island_list;
20241 branch_island_list = branch_island;
20244 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
20245 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
20246 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
20247 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
20249 /* Generate far-jump branch islands for everything on the
20250 branch_island_list. Invoked immediately after the last instruction
20251 of the epilogue has been emitted; the branch-islands must be
20252 appended to, and contiguous with, the function body. Mach-O stubs
20253 are generated in machopic_output_stub(). */
20255 static void
20256 macho_branch_islands (void)
20258 char tmp_buf[512];
20259 tree branch_island;
20261 for (branch_island = branch_island_list;
20262 branch_island;
20263 branch_island = TREE_CHAIN (branch_island))
20265 const char *label =
20266 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
20267 const char *name =
20268 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
20269 char name_buf[512];
20270 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
20271 if (name[0] == '*' || name[0] == '&')
20272 strcpy (name_buf, name+1);
20273 else
20275 name_buf[0] = '_';
20276 strcpy (name_buf+1, name);
20278 strcpy (tmp_buf, "\n");
20279 strcat (tmp_buf, label);
20280 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20281 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
20282 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
20283 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20284 if (flag_pic)
20286 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
20287 strcat (tmp_buf, label);
20288 strcat (tmp_buf, "_pic\n");
20289 strcat (tmp_buf, label);
20290 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
20292 strcat (tmp_buf, "\taddis r11,r11,ha16(");
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, "\tmtlr r0\n");
20300 strcat (tmp_buf, "\taddi r12,r11,lo16(");
20301 strcat (tmp_buf, name_buf);
20302 strcat (tmp_buf, " - ");
20303 strcat (tmp_buf, label);
20304 strcat (tmp_buf, "_pic)\n");
20306 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
20308 else
20310 strcat (tmp_buf, ":\nlis r12,hi16(");
20311 strcat (tmp_buf, name_buf);
20312 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
20313 strcat (tmp_buf, name_buf);
20314 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
20316 output_asm_insn (tmp_buf, 0);
20317 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20318 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
20319 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
20320 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20323 branch_island_list = 0;
20326 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
20327 already there or not. */
20329 static int
20330 no_previous_def (tree function_name)
20332 tree branch_island;
20333 for (branch_island = branch_island_list;
20334 branch_island;
20335 branch_island = TREE_CHAIN (branch_island))
20336 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
20337 return 0;
20338 return 1;
20341 /* GET_PREV_LABEL gets the label name from the previous definition of
20342 the function. */
20344 static tree
20345 get_prev_label (tree function_name)
20347 tree branch_island;
20348 for (branch_island = branch_island_list;
20349 branch_island;
20350 branch_island = TREE_CHAIN (branch_island))
20351 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
20352 return BRANCH_ISLAND_LABEL_NAME (branch_island);
20353 return 0;
20356 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
20357 #define DARWIN_LINKER_GENERATES_ISLANDS 0
20358 #endif
20360 /* KEXTs still need branch islands. */
20361 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
20362 || flag_mkernel || flag_apple_kext)
20364 /* INSN is either a function call or a millicode call. It may have an
20365 unconditional jump in its delay slot.
20367 CALL_DEST is the routine we are calling. */
20369 char *
20370 output_call (rtx insn, rtx *operands, int dest_operand_number,
20371 int cookie_operand_number)
20373 static char buf[256];
20374 if (DARWIN_GENERATE_ISLANDS
20375 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
20376 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
20378 tree labelname;
20379 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
20381 if (no_previous_def (funname))
20383 rtx label_rtx = gen_label_rtx ();
20384 char *label_buf, temp_buf[256];
20385 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
20386 CODE_LABEL_NUMBER (label_rtx));
20387 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
20388 labelname = get_identifier (label_buf);
20389 add_compiler_branch_island (labelname, funname, insn_line (insn));
20391 else
20392 labelname = get_prev_label (funname);
20394 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
20395 instruction will reach 'foo', otherwise link as 'bl L42'".
20396 "L42" should be a 'branch island', that will do a far jump to
20397 'foo'. Branch islands are generated in
20398 macho_branch_islands(). */
20399 sprintf (buf, "jbsr %%z%d,%.246s",
20400 dest_operand_number, IDENTIFIER_POINTER (labelname));
20402 else
20403 sprintf (buf, "bl %%z%d", dest_operand_number);
20404 return buf;
20407 /* Generate PIC and indirect symbol stubs. */
20409 void
20410 machopic_output_stub (FILE *file, const char *symb, const char *stub)
20412 unsigned int length;
20413 char *symbol_name, *lazy_ptr_name;
20414 char *local_label_0;
20415 static int label = 0;
20417 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
20418 symb = (*targetm.strip_name_encoding) (symb);
20421 length = strlen (symb);
20422 symbol_name = alloca (length + 32);
20423 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
20425 lazy_ptr_name = alloca (length + 32);
20426 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
20428 if (flag_pic == 2)
20429 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
20430 else
20431 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
20433 if (flag_pic == 2)
20435 fprintf (file, "\t.align 5\n");
20437 fprintf (file, "%s:\n", stub);
20438 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
20440 label++;
20441 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
20442 sprintf (local_label_0, "\"L%011d$spb\"", label);
20444 fprintf (file, "\tmflr r0\n");
20445 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
20446 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
20447 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
20448 lazy_ptr_name, local_label_0);
20449 fprintf (file, "\tmtlr r0\n");
20450 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
20451 (TARGET_64BIT ? "ldu" : "lwzu"),
20452 lazy_ptr_name, local_label_0);
20453 fprintf (file, "\tmtctr r12\n");
20454 fprintf (file, "\tbctr\n");
20456 else
20458 fprintf (file, "\t.align 4\n");
20460 fprintf (file, "%s:\n", stub);
20461 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
20463 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
20464 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
20465 (TARGET_64BIT ? "ldu" : "lwzu"),
20466 lazy_ptr_name);
20467 fprintf (file, "\tmtctr r12\n");
20468 fprintf (file, "\tbctr\n");
20471 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
20472 fprintf (file, "%s:\n", lazy_ptr_name);
20473 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
20474 fprintf (file, "%sdyld_stub_binding_helper\n",
20475 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
20478 /* Legitimize PIC addresses. If the address is already
20479 position-independent, we return ORIG. Newly generated
20480 position-independent addresses go into a reg. This is REG if non
20481 zero, otherwise we allocate register(s) as necessary. */
20483 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
20486 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
20487 rtx reg)
20489 rtx base, offset;
20491 if (reg == NULL && ! reload_in_progress && ! reload_completed)
20492 reg = gen_reg_rtx (Pmode);
20494 if (GET_CODE (orig) == CONST)
20496 rtx reg_temp;
20498 if (GET_CODE (XEXP (orig, 0)) == PLUS
20499 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
20500 return orig;
20502 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
20504 /* Use a different reg for the intermediate value, as
20505 it will be marked UNCHANGING. */
20506 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
20507 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
20508 Pmode, reg_temp);
20509 offset =
20510 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
20511 Pmode, reg);
20513 if (GET_CODE (offset) == CONST_INT)
20515 if (SMALL_INT (offset))
20516 return plus_constant (base, INTVAL (offset));
20517 else if (! reload_in_progress && ! reload_completed)
20518 offset = force_reg (Pmode, offset);
20519 else
20521 rtx mem = force_const_mem (Pmode, orig);
20522 return machopic_legitimize_pic_address (mem, Pmode, reg);
20525 return gen_rtx_PLUS (Pmode, base, offset);
20528 /* Fall back on generic machopic code. */
20529 return machopic_legitimize_pic_address (orig, mode, reg);
20532 /* Output a .machine directive for the Darwin assembler, and call
20533 the generic start_file routine. */
20535 static void
20536 rs6000_darwin_file_start (void)
20538 static const struct
20540 const char *arg;
20541 const char *name;
20542 int if_set;
20543 } mapping[] = {
20544 { "ppc64", "ppc64", MASK_64BIT },
20545 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
20546 { "power4", "ppc970", 0 },
20547 { "G5", "ppc970", 0 },
20548 { "7450", "ppc7450", 0 },
20549 { "7400", "ppc7400", MASK_ALTIVEC },
20550 { "G4", "ppc7400", 0 },
20551 { "750", "ppc750", 0 },
20552 { "740", "ppc750", 0 },
20553 { "G3", "ppc750", 0 },
20554 { "604e", "ppc604e", 0 },
20555 { "604", "ppc604", 0 },
20556 { "603e", "ppc603", 0 },
20557 { "603", "ppc603", 0 },
20558 { "601", "ppc601", 0 },
20559 { NULL, "ppc", 0 } };
20560 const char *cpu_id = "";
20561 size_t i;
20563 rs6000_file_start ();
20564 darwin_file_start ();
20566 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
20567 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
20568 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
20569 && rs6000_select[i].string[0] != '\0')
20570 cpu_id = rs6000_select[i].string;
20572 /* Look through the mapping array. Pick the first name that either
20573 matches the argument, has a bit set in IF_SET that is also set
20574 in the target flags, or has a NULL name. */
20576 i = 0;
20577 while (mapping[i].arg != NULL
20578 && strcmp (mapping[i].arg, cpu_id) != 0
20579 && (mapping[i].if_set & target_flags) == 0)
20580 i++;
20582 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
20585 #endif /* TARGET_MACHO */
20587 #if TARGET_ELF
20588 static int
20589 rs6000_elf_reloc_rw_mask (void)
20591 if (flag_pic)
20592 return 3;
20593 else if (DEFAULT_ABI == ABI_AIX)
20594 return 2;
20595 else
20596 return 0;
20599 /* Record an element in the table of global constructors. SYMBOL is
20600 a SYMBOL_REF of the function to be called; PRIORITY is a number
20601 between 0 and MAX_INIT_PRIORITY.
20603 This differs from default_named_section_asm_out_constructor in
20604 that we have special handling for -mrelocatable. */
20606 static void
20607 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
20609 const char *section = ".ctors";
20610 char buf[16];
20612 if (priority != DEFAULT_INIT_PRIORITY)
20614 sprintf (buf, ".ctors.%.5u",
20615 /* Invert the numbering so the linker puts us in the proper
20616 order; constructors are run from right to left, and the
20617 linker sorts in increasing order. */
20618 MAX_INIT_PRIORITY - priority);
20619 section = buf;
20622 switch_to_section (get_section (section, SECTION_WRITE, NULL));
20623 assemble_align (POINTER_SIZE);
20625 if (TARGET_RELOCATABLE)
20627 fputs ("\t.long (", asm_out_file);
20628 output_addr_const (asm_out_file, symbol);
20629 fputs (")@fixup\n", asm_out_file);
20631 else
20632 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
20635 static void
20636 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
20638 const char *section = ".dtors";
20639 char buf[16];
20641 if (priority != DEFAULT_INIT_PRIORITY)
20643 sprintf (buf, ".dtors.%.5u",
20644 /* Invert the numbering so the linker puts us in the proper
20645 order; constructors are run from right to left, and the
20646 linker sorts in increasing order. */
20647 MAX_INIT_PRIORITY - priority);
20648 section = buf;
20651 switch_to_section (get_section (section, SECTION_WRITE, NULL));
20652 assemble_align (POINTER_SIZE);
20654 if (TARGET_RELOCATABLE)
20656 fputs ("\t.long (", asm_out_file);
20657 output_addr_const (asm_out_file, symbol);
20658 fputs (")@fixup\n", asm_out_file);
20660 else
20661 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
20664 void
20665 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
20667 if (TARGET_64BIT)
20669 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
20670 ASM_OUTPUT_LABEL (file, name);
20671 fputs (DOUBLE_INT_ASM_OP, file);
20672 rs6000_output_function_entry (file, name);
20673 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
20674 if (DOT_SYMBOLS)
20676 fputs ("\t.size\t", file);
20677 assemble_name (file, name);
20678 fputs (",24\n\t.type\t.", file);
20679 assemble_name (file, name);
20680 fputs (",@function\n", file);
20681 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
20683 fputs ("\t.globl\t.", file);
20684 assemble_name (file, name);
20685 putc ('\n', file);
20688 else
20689 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
20690 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
20691 rs6000_output_function_entry (file, name);
20692 fputs (":\n", file);
20693 return;
20696 if (TARGET_RELOCATABLE
20697 && !TARGET_SECURE_PLT
20698 && (get_pool_size () != 0 || crtl->profile)
20699 && uses_TOC ())
20701 char buf[256];
20703 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
20705 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
20706 fprintf (file, "\t.long ");
20707 assemble_name (file, buf);
20708 putc ('-', file);
20709 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
20710 assemble_name (file, buf);
20711 putc ('\n', file);
20714 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
20715 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
20717 if (DEFAULT_ABI == ABI_AIX)
20719 const char *desc_name, *orig_name;
20721 orig_name = (*targetm.strip_name_encoding) (name);
20722 desc_name = orig_name;
20723 while (*desc_name == '.')
20724 desc_name++;
20726 if (TREE_PUBLIC (decl))
20727 fprintf (file, "\t.globl %s\n", desc_name);
20729 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20730 fprintf (file, "%s:\n", desc_name);
20731 fprintf (file, "\t.long %s\n", orig_name);
20732 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
20733 if (DEFAULT_ABI == ABI_AIX)
20734 fputs ("\t.long 0\n", file);
20735 fprintf (file, "\t.previous\n");
20737 ASM_OUTPUT_LABEL (file, name);
20740 static void
20741 rs6000_elf_end_indicate_exec_stack (void)
20743 if (TARGET_32BIT)
20744 file_end_indicate_exec_stack ();
20746 #endif
20748 #if TARGET_XCOFF
20749 static void
20750 rs6000_xcoff_asm_output_anchor (rtx symbol)
20752 char buffer[100];
20754 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
20755 SYMBOL_REF_BLOCK_OFFSET (symbol));
20756 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
20759 static void
20760 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
20762 fputs (GLOBAL_ASM_OP, stream);
20763 RS6000_OUTPUT_BASENAME (stream, name);
20764 putc ('\n', stream);
20767 /* A get_unnamed_decl callback, used for read-only sections. PTR
20768 points to the section string variable. */
20770 static void
20771 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
20773 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
20774 *(const char *const *) directive,
20775 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
20778 /* Likewise for read-write sections. */
20780 static void
20781 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
20783 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
20784 *(const char *const *) directive,
20785 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
20788 /* A get_unnamed_section callback, used for switching to toc_section. */
20790 static void
20791 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
20793 if (TARGET_MINIMAL_TOC)
20795 /* toc_section is always selected at least once from
20796 rs6000_xcoff_file_start, so this is guaranteed to
20797 always be defined once and only once in each file. */
20798 if (!toc_initialized)
20800 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
20801 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
20802 toc_initialized = 1;
20804 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
20805 (TARGET_32BIT ? "" : ",3"));
20807 else
20808 fputs ("\t.toc\n", asm_out_file);
20811 /* Implement TARGET_ASM_INIT_SECTIONS. */
20813 static void
20814 rs6000_xcoff_asm_init_sections (void)
20816 read_only_data_section
20817 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
20818 &xcoff_read_only_section_name);
20820 private_data_section
20821 = get_unnamed_section (SECTION_WRITE,
20822 rs6000_xcoff_output_readwrite_section_asm_op,
20823 &xcoff_private_data_section_name);
20825 read_only_private_data_section
20826 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
20827 &xcoff_private_data_section_name);
20829 toc_section
20830 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
20832 readonly_data_section = read_only_data_section;
20833 exception_section = data_section;
20836 static int
20837 rs6000_xcoff_reloc_rw_mask (void)
20839 return 3;
20842 static void
20843 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
20844 tree decl ATTRIBUTE_UNUSED)
20846 int smclass;
20847 static const char * const suffix[3] = { "PR", "RO", "RW" };
20849 if (flags & SECTION_CODE)
20850 smclass = 0;
20851 else if (flags & SECTION_WRITE)
20852 smclass = 2;
20853 else
20854 smclass = 1;
20856 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
20857 (flags & SECTION_CODE) ? "." : "",
20858 name, suffix[smclass], flags & SECTION_ENTSIZE);
20861 static section *
20862 rs6000_xcoff_select_section (tree decl, int reloc,
20863 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
20865 if (decl_readonly_section (decl, reloc))
20867 if (TREE_PUBLIC (decl))
20868 return read_only_data_section;
20869 else
20870 return read_only_private_data_section;
20872 else
20874 if (TREE_PUBLIC (decl))
20875 return data_section;
20876 else
20877 return private_data_section;
20881 static void
20882 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
20884 const char *name;
20886 /* Use select_section for private and uninitialized data. */
20887 if (!TREE_PUBLIC (decl)
20888 || DECL_COMMON (decl)
20889 || DECL_INITIAL (decl) == NULL_TREE
20890 || DECL_INITIAL (decl) == error_mark_node
20891 || (flag_zero_initialized_in_bss
20892 && initializer_zerop (DECL_INITIAL (decl))))
20893 return;
20895 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
20896 name = (*targetm.strip_name_encoding) (name);
20897 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
20900 /* Select section for constant in constant pool.
20902 On RS/6000, all constants are in the private read-only data area.
20903 However, if this is being placed in the TOC it must be output as a
20904 toc entry. */
20906 static section *
20907 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
20908 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
20910 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
20911 return toc_section;
20912 else
20913 return read_only_private_data_section;
20916 /* Remove any trailing [DS] or the like from the symbol name. */
20918 static const char *
20919 rs6000_xcoff_strip_name_encoding (const char *name)
20921 size_t len;
20922 if (*name == '*')
20923 name++;
20924 len = strlen (name);
20925 if (name[len - 1] == ']')
20926 return ggc_alloc_string (name, len - 4);
20927 else
20928 return name;
20931 /* Section attributes. AIX is always PIC. */
20933 static unsigned int
20934 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
20936 unsigned int align;
20937 unsigned int flags = default_section_type_flags (decl, name, reloc);
20939 /* Align to at least UNIT size. */
20940 if (flags & SECTION_CODE)
20941 align = MIN_UNITS_PER_WORD;
20942 else
20943 /* Increase alignment of large objects if not already stricter. */
20944 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
20945 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
20946 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
20948 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
20951 /* Output at beginning of assembler file.
20953 Initialize the section names for the RS/6000 at this point.
20955 Specify filename, including full path, to assembler.
20957 We want to go into the TOC section so at least one .toc will be emitted.
20958 Also, in order to output proper .bs/.es pairs, we need at least one static
20959 [RW] section emitted.
20961 Finally, declare mcount when profiling to make the assembler happy. */
20963 static void
20964 rs6000_xcoff_file_start (void)
20966 rs6000_gen_section_name (&xcoff_bss_section_name,
20967 main_input_filename, ".bss_");
20968 rs6000_gen_section_name (&xcoff_private_data_section_name,
20969 main_input_filename, ".rw_");
20970 rs6000_gen_section_name (&xcoff_read_only_section_name,
20971 main_input_filename, ".ro_");
20973 fputs ("\t.file\t", asm_out_file);
20974 output_quoted_string (asm_out_file, main_input_filename);
20975 fputc ('\n', asm_out_file);
20976 if (write_symbols != NO_DEBUG)
20977 switch_to_section (private_data_section);
20978 switch_to_section (text_section);
20979 if (profile_flag)
20980 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
20981 rs6000_file_start ();
20984 /* Output at end of assembler file.
20985 On the RS/6000, referencing data should automatically pull in text. */
20987 static void
20988 rs6000_xcoff_file_end (void)
20990 switch_to_section (text_section);
20991 fputs ("_section_.text:\n", asm_out_file);
20992 switch_to_section (data_section);
20993 fputs (TARGET_32BIT
20994 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
20995 asm_out_file);
20997 #endif /* TARGET_XCOFF */
20999 /* Compute a (partial) cost for rtx X. Return true if the complete
21000 cost has been computed, and false if subexpressions should be
21001 scanned. In either case, *TOTAL contains the cost result. */
21003 static bool
21004 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
21006 enum machine_mode mode = GET_MODE (x);
21008 switch (code)
21010 /* On the RS/6000, if it is valid in the insn, it is free. */
21011 case CONST_INT:
21012 if (((outer_code == SET
21013 || outer_code == PLUS
21014 || outer_code == MINUS)
21015 && (satisfies_constraint_I (x)
21016 || satisfies_constraint_L (x)))
21017 || (outer_code == AND
21018 && (satisfies_constraint_K (x)
21019 || (mode == SImode
21020 ? satisfies_constraint_L (x)
21021 : satisfies_constraint_J (x))
21022 || mask_operand (x, mode)
21023 || (mode == DImode
21024 && mask64_operand (x, DImode))))
21025 || ((outer_code == IOR || outer_code == XOR)
21026 && (satisfies_constraint_K (x)
21027 || (mode == SImode
21028 ? satisfies_constraint_L (x)
21029 : satisfies_constraint_J (x))))
21030 || outer_code == ASHIFT
21031 || outer_code == ASHIFTRT
21032 || outer_code == LSHIFTRT
21033 || outer_code == ROTATE
21034 || outer_code == ROTATERT
21035 || outer_code == ZERO_EXTRACT
21036 || (outer_code == MULT
21037 && satisfies_constraint_I (x))
21038 || ((outer_code == DIV || outer_code == UDIV
21039 || outer_code == MOD || outer_code == UMOD)
21040 && exact_log2 (INTVAL (x)) >= 0)
21041 || (outer_code == COMPARE
21042 && (satisfies_constraint_I (x)
21043 || satisfies_constraint_K (x)))
21044 || (outer_code == EQ
21045 && (satisfies_constraint_I (x)
21046 || satisfies_constraint_K (x)
21047 || (mode == SImode
21048 ? satisfies_constraint_L (x)
21049 : satisfies_constraint_J (x))))
21050 || (outer_code == GTU
21051 && satisfies_constraint_I (x))
21052 || (outer_code == LTU
21053 && satisfies_constraint_P (x)))
21055 *total = 0;
21056 return true;
21058 else if ((outer_code == PLUS
21059 && reg_or_add_cint_operand (x, VOIDmode))
21060 || (outer_code == MINUS
21061 && reg_or_sub_cint_operand (x, VOIDmode))
21062 || ((outer_code == SET
21063 || outer_code == IOR
21064 || outer_code == XOR)
21065 && (INTVAL (x)
21066 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
21068 *total = COSTS_N_INSNS (1);
21069 return true;
21071 /* FALLTHRU */
21073 case CONST_DOUBLE:
21074 if (mode == DImode && code == CONST_DOUBLE)
21076 if ((outer_code == IOR || outer_code == XOR)
21077 && CONST_DOUBLE_HIGH (x) == 0
21078 && (CONST_DOUBLE_LOW (x)
21079 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
21081 *total = 0;
21082 return true;
21084 else if ((outer_code == AND && and64_2_operand (x, DImode))
21085 || ((outer_code == SET
21086 || outer_code == IOR
21087 || outer_code == XOR)
21088 && CONST_DOUBLE_HIGH (x) == 0))
21090 *total = COSTS_N_INSNS (1);
21091 return true;
21094 /* FALLTHRU */
21096 case CONST:
21097 case HIGH:
21098 case SYMBOL_REF:
21099 case MEM:
21100 /* When optimizing for size, MEM should be slightly more expensive
21101 than generating address, e.g., (plus (reg) (const)).
21102 L1 cache latency is about two instructions. */
21103 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
21104 return true;
21106 case LABEL_REF:
21107 *total = 0;
21108 return true;
21110 case PLUS:
21111 if (mode == DFmode)
21113 if (GET_CODE (XEXP (x, 0)) == MULT)
21115 /* FNMA accounted in outer NEG. */
21116 if (outer_code == NEG)
21117 *total = rs6000_cost->dmul - rs6000_cost->fp;
21118 else
21119 *total = rs6000_cost->dmul;
21121 else
21122 *total = rs6000_cost->fp;
21124 else if (mode == SFmode)
21126 /* FNMA accounted in outer NEG. */
21127 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
21128 *total = 0;
21129 else
21130 *total = rs6000_cost->fp;
21132 else
21133 *total = COSTS_N_INSNS (1);
21134 return false;
21136 case MINUS:
21137 if (mode == DFmode)
21139 if (GET_CODE (XEXP (x, 0)) == MULT
21140 || GET_CODE (XEXP (x, 1)) == MULT)
21142 /* FNMA accounted in outer NEG. */
21143 if (outer_code == NEG)
21144 *total = rs6000_cost->dmul - rs6000_cost->fp;
21145 else
21146 *total = rs6000_cost->dmul;
21148 else
21149 *total = rs6000_cost->fp;
21151 else if (mode == SFmode)
21153 /* FNMA accounted in outer NEG. */
21154 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
21155 *total = 0;
21156 else
21157 *total = rs6000_cost->fp;
21159 else
21160 *total = COSTS_N_INSNS (1);
21161 return false;
21163 case MULT:
21164 if (GET_CODE (XEXP (x, 1)) == CONST_INT
21165 && satisfies_constraint_I (XEXP (x, 1)))
21167 if (INTVAL (XEXP (x, 1)) >= -256
21168 && INTVAL (XEXP (x, 1)) <= 255)
21169 *total = rs6000_cost->mulsi_const9;
21170 else
21171 *total = rs6000_cost->mulsi_const;
21173 /* FMA accounted in outer PLUS/MINUS. */
21174 else if ((mode == DFmode || mode == SFmode)
21175 && (outer_code == PLUS || outer_code == MINUS))
21176 *total = 0;
21177 else if (mode == DFmode)
21178 *total = rs6000_cost->dmul;
21179 else if (mode == SFmode)
21180 *total = rs6000_cost->fp;
21181 else if (mode == DImode)
21182 *total = rs6000_cost->muldi;
21183 else
21184 *total = rs6000_cost->mulsi;
21185 return false;
21187 case DIV:
21188 case MOD:
21189 if (FLOAT_MODE_P (mode))
21191 *total = mode == DFmode ? rs6000_cost->ddiv
21192 : rs6000_cost->sdiv;
21193 return false;
21195 /* FALLTHRU */
21197 case UDIV:
21198 case UMOD:
21199 if (GET_CODE (XEXP (x, 1)) == CONST_INT
21200 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
21202 if (code == DIV || code == MOD)
21203 /* Shift, addze */
21204 *total = COSTS_N_INSNS (2);
21205 else
21206 /* Shift */
21207 *total = COSTS_N_INSNS (1);
21209 else
21211 if (GET_MODE (XEXP (x, 1)) == DImode)
21212 *total = rs6000_cost->divdi;
21213 else
21214 *total = rs6000_cost->divsi;
21216 /* Add in shift and subtract for MOD. */
21217 if (code == MOD || code == UMOD)
21218 *total += COSTS_N_INSNS (2);
21219 return false;
21221 case CTZ:
21222 case FFS:
21223 *total = COSTS_N_INSNS (4);
21224 return false;
21226 case POPCOUNT:
21227 *total = COSTS_N_INSNS (6);
21228 return false;
21230 case NOT:
21231 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
21233 *total = 0;
21234 return false;
21236 /* FALLTHRU */
21238 case AND:
21239 case CLZ:
21240 case IOR:
21241 case XOR:
21242 case ZERO_EXTRACT:
21243 *total = COSTS_N_INSNS (1);
21244 return false;
21246 case ASHIFT:
21247 case ASHIFTRT:
21248 case LSHIFTRT:
21249 case ROTATE:
21250 case ROTATERT:
21251 /* Handle mul_highpart. */
21252 if (outer_code == TRUNCATE
21253 && GET_CODE (XEXP (x, 0)) == MULT)
21255 if (mode == DImode)
21256 *total = rs6000_cost->muldi;
21257 else
21258 *total = rs6000_cost->mulsi;
21259 return true;
21261 else if (outer_code == AND)
21262 *total = 0;
21263 else
21264 *total = COSTS_N_INSNS (1);
21265 return false;
21267 case SIGN_EXTEND:
21268 case ZERO_EXTEND:
21269 if (GET_CODE (XEXP (x, 0)) == MEM)
21270 *total = 0;
21271 else
21272 *total = COSTS_N_INSNS (1);
21273 return false;
21275 case COMPARE:
21276 case NEG:
21277 case ABS:
21278 if (!FLOAT_MODE_P (mode))
21280 *total = COSTS_N_INSNS (1);
21281 return false;
21283 /* FALLTHRU */
21285 case FLOAT:
21286 case UNSIGNED_FLOAT:
21287 case FIX:
21288 case UNSIGNED_FIX:
21289 case FLOAT_TRUNCATE:
21290 *total = rs6000_cost->fp;
21291 return false;
21293 case FLOAT_EXTEND:
21294 if (mode == DFmode)
21295 *total = 0;
21296 else
21297 *total = rs6000_cost->fp;
21298 return false;
21300 case UNSPEC:
21301 switch (XINT (x, 1))
21303 case UNSPEC_FRSP:
21304 *total = rs6000_cost->fp;
21305 return true;
21307 default:
21308 break;
21310 break;
21312 case CALL:
21313 case IF_THEN_ELSE:
21314 if (optimize_size)
21316 *total = COSTS_N_INSNS (1);
21317 return true;
21319 else if (FLOAT_MODE_P (mode)
21320 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
21322 *total = rs6000_cost->fp;
21323 return false;
21325 break;
21327 case EQ:
21328 case GTU:
21329 case LTU:
21330 /* Carry bit requires mode == Pmode.
21331 NEG or PLUS already counted so only add one. */
21332 if (mode == Pmode
21333 && (outer_code == NEG || outer_code == PLUS))
21335 *total = COSTS_N_INSNS (1);
21336 return true;
21338 if (outer_code == SET)
21340 if (XEXP (x, 1) == const0_rtx)
21342 *total = COSTS_N_INSNS (2);
21343 return true;
21345 else if (mode == Pmode)
21347 *total = COSTS_N_INSNS (3);
21348 return false;
21351 /* FALLTHRU */
21353 case GT:
21354 case LT:
21355 case UNORDERED:
21356 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
21358 *total = COSTS_N_INSNS (2);
21359 return true;
21361 /* CC COMPARE. */
21362 if (outer_code == COMPARE)
21364 *total = 0;
21365 return true;
21367 break;
21369 default:
21370 break;
21373 return false;
21376 /* A C expression returning the cost of moving data from a register of class
21377 CLASS1 to one of CLASS2. */
21380 rs6000_register_move_cost (enum machine_mode mode,
21381 enum reg_class from, enum reg_class to)
21383 /* Moves from/to GENERAL_REGS. */
21384 if (reg_classes_intersect_p (to, GENERAL_REGS)
21385 || reg_classes_intersect_p (from, GENERAL_REGS))
21387 if (! reg_classes_intersect_p (to, GENERAL_REGS))
21388 from = to;
21390 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
21391 return (rs6000_memory_move_cost (mode, from, 0)
21392 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
21394 /* It's more expensive to move CR_REGS than CR0_REGS because of the
21395 shift. */
21396 else if (from == CR_REGS)
21397 return 4;
21399 /* Power6 has slower LR/CTR moves so make them more expensive than
21400 memory in order to bias spills to memory .*/
21401 else if (rs6000_cpu == PROCESSOR_POWER6
21402 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
21403 return 6 * hard_regno_nregs[0][mode];
21405 else
21406 /* A move will cost one instruction per GPR moved. */
21407 return 2 * hard_regno_nregs[0][mode];
21410 /* Moving between two similar registers is just one instruction. */
21411 else if (reg_classes_intersect_p (to, from))
21412 return (mode == TFmode || mode == TDmode) ? 4 : 2;
21414 /* Everything else has to go through GENERAL_REGS. */
21415 else
21416 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
21417 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
21420 /* A C expressions returning the cost of moving data of MODE from a register to
21421 or from memory. */
21424 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
21425 int in ATTRIBUTE_UNUSED)
21427 if (reg_classes_intersect_p (class, GENERAL_REGS))
21428 return 4 * hard_regno_nregs[0][mode];
21429 else if (reg_classes_intersect_p (class, FLOAT_REGS))
21430 return 4 * hard_regno_nregs[32][mode];
21431 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
21432 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
21433 else
21434 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
21437 /* Returns a code for a target-specific builtin that implements
21438 reciprocal of the function, or NULL_TREE if not available. */
21440 static tree
21441 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
21442 bool sqrt ATTRIBUTE_UNUSED)
21444 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
21445 && flag_finite_math_only && !flag_trapping_math
21446 && flag_unsafe_math_optimizations))
21447 return NULL_TREE;
21449 if (md_fn)
21450 return NULL_TREE;
21451 else
21452 switch (fn)
21454 case BUILT_IN_SQRTF:
21455 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
21457 default:
21458 return NULL_TREE;
21462 /* Newton-Raphson approximation of single-precision floating point divide n/d.
21463 Assumes no trapping math and finite arguments. */
21465 void
21466 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
21468 rtx x0, e0, e1, y1, u0, v0, one;
21470 x0 = gen_reg_rtx (SFmode);
21471 e0 = gen_reg_rtx (SFmode);
21472 e1 = gen_reg_rtx (SFmode);
21473 y1 = gen_reg_rtx (SFmode);
21474 u0 = gen_reg_rtx (SFmode);
21475 v0 = gen_reg_rtx (SFmode);
21476 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
21478 /* x0 = 1./d estimate */
21479 emit_insn (gen_rtx_SET (VOIDmode, x0,
21480 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
21481 UNSPEC_FRES)));
21482 /* e0 = 1. - d * x0 */
21483 emit_insn (gen_rtx_SET (VOIDmode, e0,
21484 gen_rtx_MINUS (SFmode, one,
21485 gen_rtx_MULT (SFmode, d, x0))));
21486 /* e1 = e0 + e0 * e0 */
21487 emit_insn (gen_rtx_SET (VOIDmode, e1,
21488 gen_rtx_PLUS (SFmode,
21489 gen_rtx_MULT (SFmode, e0, e0), e0)));
21490 /* y1 = x0 + e1 * x0 */
21491 emit_insn (gen_rtx_SET (VOIDmode, y1,
21492 gen_rtx_PLUS (SFmode,
21493 gen_rtx_MULT (SFmode, e1, x0), x0)));
21494 /* u0 = n * y1 */
21495 emit_insn (gen_rtx_SET (VOIDmode, u0,
21496 gen_rtx_MULT (SFmode, n, y1)));
21497 /* v0 = n - d * u0 */
21498 emit_insn (gen_rtx_SET (VOIDmode, v0,
21499 gen_rtx_MINUS (SFmode, n,
21500 gen_rtx_MULT (SFmode, d, u0))));
21501 /* dst = u0 + v0 * y1 */
21502 emit_insn (gen_rtx_SET (VOIDmode, dst,
21503 gen_rtx_PLUS (SFmode,
21504 gen_rtx_MULT (SFmode, v0, y1), u0)));
21507 /* Newton-Raphson approximation of double-precision floating point divide n/d.
21508 Assumes no trapping math and finite arguments. */
21510 void
21511 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
21513 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
21515 x0 = gen_reg_rtx (DFmode);
21516 e0 = gen_reg_rtx (DFmode);
21517 e1 = gen_reg_rtx (DFmode);
21518 e2 = gen_reg_rtx (DFmode);
21519 y1 = gen_reg_rtx (DFmode);
21520 y2 = gen_reg_rtx (DFmode);
21521 y3 = gen_reg_rtx (DFmode);
21522 u0 = gen_reg_rtx (DFmode);
21523 v0 = gen_reg_rtx (DFmode);
21524 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
21526 /* x0 = 1./d estimate */
21527 emit_insn (gen_rtx_SET (VOIDmode, x0,
21528 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
21529 UNSPEC_FRES)));
21530 /* e0 = 1. - d * x0 */
21531 emit_insn (gen_rtx_SET (VOIDmode, e0,
21532 gen_rtx_MINUS (DFmode, one,
21533 gen_rtx_MULT (SFmode, d, x0))));
21534 /* y1 = x0 + e0 * x0 */
21535 emit_insn (gen_rtx_SET (VOIDmode, y1,
21536 gen_rtx_PLUS (DFmode,
21537 gen_rtx_MULT (DFmode, e0, x0), x0)));
21538 /* e1 = e0 * e0 */
21539 emit_insn (gen_rtx_SET (VOIDmode, e1,
21540 gen_rtx_MULT (DFmode, e0, e0)));
21541 /* y2 = y1 + e1 * y1 */
21542 emit_insn (gen_rtx_SET (VOIDmode, y2,
21543 gen_rtx_PLUS (DFmode,
21544 gen_rtx_MULT (DFmode, e1, y1), y1)));
21545 /* e2 = e1 * e1 */
21546 emit_insn (gen_rtx_SET (VOIDmode, e2,
21547 gen_rtx_MULT (DFmode, e1, e1)));
21548 /* y3 = y2 + e2 * y2 */
21549 emit_insn (gen_rtx_SET (VOIDmode, y3,
21550 gen_rtx_PLUS (DFmode,
21551 gen_rtx_MULT (DFmode, e2, y2), y2)));
21552 /* u0 = n * y3 */
21553 emit_insn (gen_rtx_SET (VOIDmode, u0,
21554 gen_rtx_MULT (DFmode, n, y3)));
21555 /* v0 = n - d * u0 */
21556 emit_insn (gen_rtx_SET (VOIDmode, v0,
21557 gen_rtx_MINUS (DFmode, n,
21558 gen_rtx_MULT (DFmode, d, u0))));
21559 /* dst = u0 + v0 * y3 */
21560 emit_insn (gen_rtx_SET (VOIDmode, dst,
21561 gen_rtx_PLUS (DFmode,
21562 gen_rtx_MULT (DFmode, v0, y3), u0)));
21566 /* Newton-Raphson approximation of single-precision floating point rsqrt.
21567 Assumes no trapping math and finite arguments. */
21569 void
21570 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
21572 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
21573 half, one, halfthree, c1, cond, label;
21575 x0 = gen_reg_rtx (SFmode);
21576 x1 = gen_reg_rtx (SFmode);
21577 x2 = gen_reg_rtx (SFmode);
21578 y1 = gen_reg_rtx (SFmode);
21579 u0 = gen_reg_rtx (SFmode);
21580 u1 = gen_reg_rtx (SFmode);
21581 u2 = gen_reg_rtx (SFmode);
21582 v0 = gen_reg_rtx (SFmode);
21583 v1 = gen_reg_rtx (SFmode);
21584 v2 = gen_reg_rtx (SFmode);
21585 t0 = gen_reg_rtx (SFmode);
21586 halfthree = gen_reg_rtx (SFmode);
21587 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
21588 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
21590 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
21591 emit_insn (gen_rtx_SET (VOIDmode, t0,
21592 gen_rtx_MULT (SFmode, src, src)));
21594 emit_insn (gen_rtx_SET (VOIDmode, cond,
21595 gen_rtx_COMPARE (CCFPmode, t0, src)));
21596 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
21597 emit_unlikely_jump (c1, label);
21599 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
21600 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
21602 /* halfthree = 1.5 = 1.0 + 0.5 */
21603 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
21604 gen_rtx_PLUS (SFmode, one, half)));
21606 /* x0 = rsqrt estimate */
21607 emit_insn (gen_rtx_SET (VOIDmode, x0,
21608 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
21609 UNSPEC_RSQRT)));
21611 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
21612 emit_insn (gen_rtx_SET (VOIDmode, y1,
21613 gen_rtx_MINUS (SFmode,
21614 gen_rtx_MULT (SFmode, src, halfthree),
21615 src)));
21617 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
21618 emit_insn (gen_rtx_SET (VOIDmode, u0,
21619 gen_rtx_MULT (SFmode, x0, x0)));
21620 emit_insn (gen_rtx_SET (VOIDmode, v0,
21621 gen_rtx_MINUS (SFmode,
21622 halfthree,
21623 gen_rtx_MULT (SFmode, y1, u0))));
21624 emit_insn (gen_rtx_SET (VOIDmode, x1,
21625 gen_rtx_MULT (SFmode, x0, v0)));
21627 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
21628 emit_insn (gen_rtx_SET (VOIDmode, u1,
21629 gen_rtx_MULT (SFmode, x1, x1)));
21630 emit_insn (gen_rtx_SET (VOIDmode, v1,
21631 gen_rtx_MINUS (SFmode,
21632 halfthree,
21633 gen_rtx_MULT (SFmode, y1, u1))));
21634 emit_insn (gen_rtx_SET (VOIDmode, x2,
21635 gen_rtx_MULT (SFmode, x1, v1)));
21637 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
21638 emit_insn (gen_rtx_SET (VOIDmode, u2,
21639 gen_rtx_MULT (SFmode, x2, x2)));
21640 emit_insn (gen_rtx_SET (VOIDmode, v2,
21641 gen_rtx_MINUS (SFmode,
21642 halfthree,
21643 gen_rtx_MULT (SFmode, y1, u2))));
21644 emit_insn (gen_rtx_SET (VOIDmode, dst,
21645 gen_rtx_MULT (SFmode, x2, v2)));
21647 emit_label (XEXP (label, 0));
21650 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
21651 target, and SRC is the argument operand. */
21653 void
21654 rs6000_emit_popcount (rtx dst, rtx src)
21656 enum machine_mode mode = GET_MODE (dst);
21657 rtx tmp1, tmp2;
21659 tmp1 = gen_reg_rtx (mode);
21661 if (mode == SImode)
21663 emit_insn (gen_popcntbsi2 (tmp1, src));
21664 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
21665 NULL_RTX, 0);
21666 tmp2 = force_reg (SImode, tmp2);
21667 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
21669 else
21671 emit_insn (gen_popcntbdi2 (tmp1, src));
21672 tmp2 = expand_mult (DImode, tmp1,
21673 GEN_INT ((HOST_WIDE_INT)
21674 0x01010101 << 32 | 0x01010101),
21675 NULL_RTX, 0);
21676 tmp2 = force_reg (DImode, tmp2);
21677 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
21682 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
21683 target, and SRC is the argument operand. */
21685 void
21686 rs6000_emit_parity (rtx dst, rtx src)
21688 enum machine_mode mode = GET_MODE (dst);
21689 rtx tmp;
21691 tmp = gen_reg_rtx (mode);
21692 if (mode == SImode)
21694 /* Is mult+shift >= shift+xor+shift+xor? */
21695 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
21697 rtx tmp1, tmp2, tmp3, tmp4;
21699 tmp1 = gen_reg_rtx (SImode);
21700 emit_insn (gen_popcntbsi2 (tmp1, src));
21702 tmp2 = gen_reg_rtx (SImode);
21703 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
21704 tmp3 = gen_reg_rtx (SImode);
21705 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
21707 tmp4 = gen_reg_rtx (SImode);
21708 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
21709 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
21711 else
21712 rs6000_emit_popcount (tmp, src);
21713 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
21715 else
21717 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
21718 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
21720 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
21722 tmp1 = gen_reg_rtx (DImode);
21723 emit_insn (gen_popcntbdi2 (tmp1, src));
21725 tmp2 = gen_reg_rtx (DImode);
21726 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
21727 tmp3 = gen_reg_rtx (DImode);
21728 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
21730 tmp4 = gen_reg_rtx (DImode);
21731 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
21732 tmp5 = gen_reg_rtx (DImode);
21733 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
21735 tmp6 = gen_reg_rtx (DImode);
21736 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
21737 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
21739 else
21740 rs6000_emit_popcount (tmp, src);
21741 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
21745 /* Return an RTX representing where to find the function value of a
21746 function returning MODE. */
21747 static rtx
21748 rs6000_complex_function_value (enum machine_mode mode)
21750 unsigned int regno;
21751 rtx r1, r2;
21752 enum machine_mode inner = GET_MODE_INNER (mode);
21753 unsigned int inner_bytes = GET_MODE_SIZE (inner);
21755 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
21756 regno = FP_ARG_RETURN;
21757 else
21759 regno = GP_ARG_RETURN;
21761 /* 32-bit is OK since it'll go in r3/r4. */
21762 if (TARGET_32BIT && inner_bytes >= 4)
21763 return gen_rtx_REG (mode, regno);
21766 if (inner_bytes >= 8)
21767 return gen_rtx_REG (mode, regno);
21769 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
21770 const0_rtx);
21771 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
21772 GEN_INT (inner_bytes));
21773 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
21776 /* Define how to find the value returned by a function.
21777 VALTYPE is the data type of the value (as a tree).
21778 If the precise function being called is known, FUNC is its FUNCTION_DECL;
21779 otherwise, FUNC is 0.
21781 On the SPE, both FPs and vectors are returned in r3.
21783 On RS/6000 an integer value is in r3 and a floating-point value is in
21784 fp1, unless -msoft-float. */
21787 rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
21789 enum machine_mode mode;
21790 unsigned int regno;
21792 /* Special handling for structs in darwin64. */
21793 if (rs6000_darwin64_abi
21794 && TYPE_MODE (valtype) == BLKmode
21795 && TREE_CODE (valtype) == RECORD_TYPE
21796 && int_size_in_bytes (valtype) > 0)
21798 CUMULATIVE_ARGS valcum;
21799 rtx valret;
21801 valcum.words = 0;
21802 valcum.fregno = FP_ARG_MIN_REG;
21803 valcum.vregno = ALTIVEC_ARG_MIN_REG;
21804 /* Do a trial code generation as if this were going to be passed as
21805 an argument; if any part goes in memory, we return NULL. */
21806 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
21807 if (valret)
21808 return valret;
21809 /* Otherwise fall through to standard ABI rules. */
21812 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
21814 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21815 return gen_rtx_PARALLEL (DImode,
21816 gen_rtvec (2,
21817 gen_rtx_EXPR_LIST (VOIDmode,
21818 gen_rtx_REG (SImode, GP_ARG_RETURN),
21819 const0_rtx),
21820 gen_rtx_EXPR_LIST (VOIDmode,
21821 gen_rtx_REG (SImode,
21822 GP_ARG_RETURN + 1),
21823 GEN_INT (4))));
21825 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
21827 return gen_rtx_PARALLEL (DCmode,
21828 gen_rtvec (4,
21829 gen_rtx_EXPR_LIST (VOIDmode,
21830 gen_rtx_REG (SImode, GP_ARG_RETURN),
21831 const0_rtx),
21832 gen_rtx_EXPR_LIST (VOIDmode,
21833 gen_rtx_REG (SImode,
21834 GP_ARG_RETURN + 1),
21835 GEN_INT (4)),
21836 gen_rtx_EXPR_LIST (VOIDmode,
21837 gen_rtx_REG (SImode,
21838 GP_ARG_RETURN + 2),
21839 GEN_INT (8)),
21840 gen_rtx_EXPR_LIST (VOIDmode,
21841 gen_rtx_REG (SImode,
21842 GP_ARG_RETURN + 3),
21843 GEN_INT (12))));
21846 mode = TYPE_MODE (valtype);
21847 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
21848 || POINTER_TYPE_P (valtype))
21849 mode = TARGET_32BIT ? SImode : DImode;
21851 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
21852 /* _Decimal128 must use an even/odd register pair. */
21853 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
21854 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
21855 regno = FP_ARG_RETURN;
21856 else if (TREE_CODE (valtype) == COMPLEX_TYPE
21857 && targetm.calls.split_complex_arg)
21858 return rs6000_complex_function_value (mode);
21859 else if (TREE_CODE (valtype) == VECTOR_TYPE
21860 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
21861 && ALTIVEC_VECTOR_MODE (mode))
21862 regno = ALTIVEC_ARG_RETURN;
21863 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
21864 && (mode == DFmode || mode == DDmode || mode == DCmode
21865 || mode == TFmode || mode == TDmode || mode == TCmode))
21866 return spe_build_register_parallel (mode, GP_ARG_RETURN);
21867 else
21868 regno = GP_ARG_RETURN;
21870 return gen_rtx_REG (mode, regno);
21873 /* Define how to find the value returned by a library function
21874 assuming the value has mode MODE. */
21876 rs6000_libcall_value (enum machine_mode mode)
21878 unsigned int regno;
21880 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
21882 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21883 return gen_rtx_PARALLEL (DImode,
21884 gen_rtvec (2,
21885 gen_rtx_EXPR_LIST (VOIDmode,
21886 gen_rtx_REG (SImode, GP_ARG_RETURN),
21887 const0_rtx),
21888 gen_rtx_EXPR_LIST (VOIDmode,
21889 gen_rtx_REG (SImode,
21890 GP_ARG_RETURN + 1),
21891 GEN_INT (4))));
21894 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
21895 /* _Decimal128 must use an even/odd register pair. */
21896 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
21897 else if (SCALAR_FLOAT_MODE_P (mode)
21898 && TARGET_HARD_FLOAT && TARGET_FPRS)
21899 regno = FP_ARG_RETURN;
21900 else if (ALTIVEC_VECTOR_MODE (mode)
21901 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
21902 regno = ALTIVEC_ARG_RETURN;
21903 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
21904 return rs6000_complex_function_value (mode);
21905 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
21906 && (mode == DFmode || mode == DDmode || mode == DCmode
21907 || mode == TFmode || mode == TDmode || mode == TCmode))
21908 return spe_build_register_parallel (mode, GP_ARG_RETURN);
21909 else
21910 regno = GP_ARG_RETURN;
21912 return gen_rtx_REG (mode, regno);
21915 /* Define the offset between two registers, FROM to be eliminated and its
21916 replacement TO, at the start of a routine. */
21917 HOST_WIDE_INT
21918 rs6000_initial_elimination_offset (int from, int to)
21920 rs6000_stack_t *info = rs6000_stack_info ();
21921 HOST_WIDE_INT offset;
21923 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
21924 offset = info->push_p ? 0 : -info->total_size;
21925 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
21927 offset = info->push_p ? 0 : -info->total_size;
21928 if (FRAME_GROWS_DOWNWARD)
21929 offset += info->fixed_size + info->vars_size + info->parm_size;
21931 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
21932 offset = FRAME_GROWS_DOWNWARD
21933 ? info->fixed_size + info->vars_size + info->parm_size
21934 : 0;
21935 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
21936 offset = info->total_size;
21937 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
21938 offset = info->push_p ? info->total_size : 0;
21939 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
21940 offset = 0;
21941 else
21942 gcc_unreachable ();
21944 return offset;
21947 /* Return true if TYPE is a SPE or AltiVec opaque type. */
21949 static bool
21950 rs6000_is_opaque_type (const_tree type)
21952 return (type == opaque_V2SI_type_node
21953 || type == opaque_V2SF_type_node
21954 || type == opaque_p_V2SI_type_node
21955 || type == opaque_V4SI_type_node);
21958 static rtx
21959 rs6000_dwarf_register_span (rtx reg)
21961 unsigned regno;
21963 if (TARGET_SPE
21964 && (SPE_VECTOR_MODE (GET_MODE (reg))
21965 || (TARGET_E500_DOUBLE
21966 && (GET_MODE (reg) == DFmode || GET_MODE (reg) == DDmode))))
21968 else
21969 return NULL_RTX;
21971 regno = REGNO (reg);
21973 /* The duality of the SPE register size wreaks all kinds of havoc.
21974 This is a way of distinguishing r0 in 32-bits from r0 in
21975 64-bits. */
21976 return
21977 gen_rtx_PARALLEL (VOIDmode,
21978 BYTES_BIG_ENDIAN
21979 ? gen_rtvec (2,
21980 gen_rtx_REG (SImode, regno + 1200),
21981 gen_rtx_REG (SImode, regno))
21982 : gen_rtvec (2,
21983 gen_rtx_REG (SImode, regno),
21984 gen_rtx_REG (SImode, regno + 1200)));
21987 /* Fill in sizes for SPE register high parts in table used by unwinder. */
21989 static void
21990 rs6000_init_dwarf_reg_sizes_extra (tree address)
21992 if (TARGET_SPE)
21994 int i;
21995 enum machine_mode mode = TYPE_MODE (char_type_node);
21996 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
21997 rtx mem = gen_rtx_MEM (BLKmode, addr);
21998 rtx value = gen_int_mode (4, mode);
22000 for (i = 1201; i < 1232; i++)
22002 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
22003 HOST_WIDE_INT offset
22004 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
22006 emit_move_insn (adjust_address (mem, mode, offset), value);
22011 /* Map internal gcc register numbers to DWARF2 register numbers. */
22013 unsigned int
22014 rs6000_dbx_register_number (unsigned int regno)
22016 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
22017 return regno;
22018 if (regno == MQ_REGNO)
22019 return 100;
22020 if (regno == LR_REGNO)
22021 return 108;
22022 if (regno == CTR_REGNO)
22023 return 109;
22024 if (CR_REGNO_P (regno))
22025 return regno - CR0_REGNO + 86;
22026 if (regno == XER_REGNO)
22027 return 101;
22028 if (ALTIVEC_REGNO_P (regno))
22029 return regno - FIRST_ALTIVEC_REGNO + 1124;
22030 if (regno == VRSAVE_REGNO)
22031 return 356;
22032 if (regno == VSCR_REGNO)
22033 return 67;
22034 if (regno == SPE_ACC_REGNO)
22035 return 99;
22036 if (regno == SPEFSCR_REGNO)
22037 return 612;
22038 /* SPE high reg number. We get these values of regno from
22039 rs6000_dwarf_register_span. */
22040 gcc_assert (regno >= 1200 && regno < 1232);
22041 return regno;
22044 /* target hook eh_return_filter_mode */
22045 static enum machine_mode
22046 rs6000_eh_return_filter_mode (void)
22048 return TARGET_32BIT ? SImode : word_mode;
22051 /* Target hook for scalar_mode_supported_p. */
22052 static bool
22053 rs6000_scalar_mode_supported_p (enum machine_mode mode)
22055 if (DECIMAL_FLOAT_MODE_P (mode))
22056 return true;
22057 else
22058 return default_scalar_mode_supported_p (mode);
22061 /* Target hook for vector_mode_supported_p. */
22062 static bool
22063 rs6000_vector_mode_supported_p (enum machine_mode mode)
22066 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
22067 return true;
22069 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
22070 return true;
22072 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
22073 return true;
22075 else
22076 return false;
22079 /* Target hook for invalid_arg_for_unprototyped_fn. */
22080 static const char *
22081 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
22083 return (!rs6000_darwin64_abi
22084 && typelist == 0
22085 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
22086 && (funcdecl == NULL_TREE
22087 || (TREE_CODE (funcdecl) == FUNCTION_DECL
22088 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
22089 ? N_("AltiVec argument passed to unprototyped function")
22090 : NULL;
22093 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
22094 setup by using __stack_chk_fail_local hidden function instead of
22095 calling __stack_chk_fail directly. Otherwise it is better to call
22096 __stack_chk_fail directly. */
22098 static tree
22099 rs6000_stack_protect_fail (void)
22101 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
22102 ? default_hidden_stack_protect_fail ()
22103 : default_external_stack_protect_fail ();
22106 #include "gt-rs6000.h"