* config/alpha/alpha.md, arm/arm.c, darwin.c, frv/frv.md,
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob15f263ab01660303c722bacc56193b1e922832ff
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
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 2, 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 COPYING. If not, write to the
21 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "real.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "recog.h"
37 #include "obstack.h"
38 #include "tree.h"
39 #include "expr.h"
40 #include "optabs.h"
41 #include "except.h"
42 #include "function.h"
43 #include "output.h"
44 #include "basic-block.h"
45 #include "integrate.h"
46 #include "toplev.h"
47 #include "ggc.h"
48 #include "hashtab.h"
49 #include "tm_p.h"
50 #include "target.h"
51 #include "target-def.h"
52 #include "langhooks.h"
53 #include "reload.h"
54 #include "cfglayout.h"
55 #include "sched-int.h"
56 #include "tree-gimple.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 } machine_function;
131 /* Target cpu type */
133 enum processor_type rs6000_cpu;
134 struct rs6000_cpu_select rs6000_select[3] =
136 /* switch name, tune arch */
137 { (const char *)0, "--with-cpu=", 1, 1 },
138 { (const char *)0, "-mcpu=", 1, 1 },
139 { (const char *)0, "-mtune=", 1, 0 },
142 static GTY(()) bool rs6000_cell_dont_microcode;
144 /* Always emit branch hint bits. */
145 static GTY(()) bool rs6000_always_hint;
147 /* Schedule instructions for group formation. */
148 static GTY(()) bool rs6000_sched_groups;
150 /* Align branch targets. */
151 static GTY(()) bool rs6000_align_branch_targets;
153 /* Support for -msched-costly-dep option. */
154 const char *rs6000_sched_costly_dep_str;
155 enum rs6000_dependence_cost rs6000_sched_costly_dep;
157 /* Support for -minsert-sched-nops option. */
158 const char *rs6000_sched_insert_nops_str;
159 enum rs6000_nop_insertion rs6000_sched_insert_nops;
161 /* Support targetm.vectorize.builtin_mask_for_load. */
162 static GTY(()) tree altivec_builtin_mask_for_load;
164 /* Size of long double. */
165 int rs6000_long_double_type_size;
167 /* IEEE quad extended precision long double. */
168 int rs6000_ieeequad;
170 /* Whether -mabi=altivec has appeared. */
171 int rs6000_altivec_abi;
173 /* Nonzero if we want SPE ABI extensions. */
174 int rs6000_spe_abi;
176 /* Nonzero if floating point operations are done in the GPRs. */
177 int rs6000_float_gprs = 0;
179 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
180 int rs6000_darwin64_abi;
182 /* Set to nonzero once AIX common-mode calls have been defined. */
183 static GTY(()) int common_mode_defined;
185 /* Save information from a "cmpxx" operation until the branch or scc is
186 emitted. */
187 rtx rs6000_compare_op0, rs6000_compare_op1;
188 int rs6000_compare_fp_p;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno;
194 #ifdef USING_ELFOS_H
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name = (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno = 0;
206 #endif
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size = 32;
210 const char *rs6000_tls_size_string;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
216 int dot_symbols;
218 /* Debug flags */
219 const char *rs6000_debug_name;
220 int rs6000_debug_stack; /* debug stack applications */
221 int rs6000_debug_arg; /* debug argument handling */
223 /* Value is TRUE if register/mode pair is acceptable. */
224 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
226 /* Built in types. */
228 tree rs6000_builtin_types[RS6000_BTI_MAX];
229 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
231 const char *rs6000_traceback_name;
232 static enum {
233 traceback_default = 0,
234 traceback_none,
235 traceback_part,
236 traceback_full
237 } rs6000_traceback;
239 /* Flag to say the TOC is initialized */
240 int toc_initialized;
241 char toc_label_name[10];
243 /* Cached value of rs6000_variable_issue. This is cached in
244 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
245 static short cached_can_issue_more;
247 static GTY(()) section *read_only_data_section;
248 static GTY(()) section *private_data_section;
249 static GTY(()) section *read_only_private_data_section;
250 static GTY(()) section *sdata2_section;
251 static GTY(()) section *toc_section;
253 /* Control alignment for fields within structures. */
254 /* String from -malign-XXXXX. */
255 int rs6000_alignment_flags;
257 /* True for any options that were explicitly set. */
258 struct {
259 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
260 bool alignment; /* True if -malign- was used. */
261 bool abi; /* True if -mabi=spe/nospe was used. */
262 bool spe; /* True if -mspe= was used. */
263 bool float_gprs; /* True if -mfloat-gprs= was used. */
264 bool isel; /* True if -misel was used. */
265 bool long_double; /* True if -mlong-double- was used. */
266 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
267 } rs6000_explicit_options;
269 struct builtin_description
271 /* mask is not const because we're going to alter it below. This
272 nonsense will go away when we rewrite the -march infrastructure
273 to give us more target flag bits. */
274 unsigned int mask;
275 const enum insn_code icode;
276 const char *const name;
277 const enum rs6000_builtins code;
280 /* Target cpu costs. */
282 struct processor_costs {
283 const int mulsi; /* cost of SImode multiplication. */
284 const int mulsi_const; /* cost of SImode multiplication by constant. */
285 const int mulsi_const9; /* cost of SImode mult by short constant. */
286 const int muldi; /* cost of DImode multiplication. */
287 const int divsi; /* cost of SImode division. */
288 const int divdi; /* cost of DImode division. */
289 const int fp; /* cost of simple SFmode and DFmode insns. */
290 const int dmul; /* cost of DFmode multiplication (and fmadd). */
291 const int sdiv; /* cost of SFmode division (fdivs). */
292 const int ddiv; /* cost of DFmode division (fdiv). */
295 const struct processor_costs *rs6000_cost;
297 /* Processor costs (relative to an add) */
299 /* Instruction size costs on 32bit processors. */
300 static const
301 struct processor_costs size32_cost = {
302 COSTS_N_INSNS (1), /* mulsi */
303 COSTS_N_INSNS (1), /* mulsi_const */
304 COSTS_N_INSNS (1), /* mulsi_const9 */
305 COSTS_N_INSNS (1), /* muldi */
306 COSTS_N_INSNS (1), /* divsi */
307 COSTS_N_INSNS (1), /* divdi */
308 COSTS_N_INSNS (1), /* fp */
309 COSTS_N_INSNS (1), /* dmul */
310 COSTS_N_INSNS (1), /* sdiv */
311 COSTS_N_INSNS (1), /* ddiv */
314 /* Instruction size costs on 64bit processors. */
315 static const
316 struct processor_costs size64_cost = {
317 COSTS_N_INSNS (1), /* mulsi */
318 COSTS_N_INSNS (1), /* mulsi_const */
319 COSTS_N_INSNS (1), /* mulsi_const9 */
320 COSTS_N_INSNS (1), /* muldi */
321 COSTS_N_INSNS (1), /* divsi */
322 COSTS_N_INSNS (1), /* divdi */
323 COSTS_N_INSNS (1), /* fp */
324 COSTS_N_INSNS (1), /* dmul */
325 COSTS_N_INSNS (1), /* sdiv */
326 COSTS_N_INSNS (1), /* ddiv */
329 /* Instruction costs on RIOS1 processors. */
330 static const
331 struct processor_costs rios1_cost = {
332 COSTS_N_INSNS (5), /* mulsi */
333 COSTS_N_INSNS (4), /* mulsi_const */
334 COSTS_N_INSNS (3), /* mulsi_const9 */
335 COSTS_N_INSNS (5), /* muldi */
336 COSTS_N_INSNS (19), /* divsi */
337 COSTS_N_INSNS (19), /* divdi */
338 COSTS_N_INSNS (2), /* fp */
339 COSTS_N_INSNS (2), /* dmul */
340 COSTS_N_INSNS (19), /* sdiv */
341 COSTS_N_INSNS (19), /* ddiv */
344 /* Instruction costs on RIOS2 processors. */
345 static const
346 struct processor_costs rios2_cost = {
347 COSTS_N_INSNS (2), /* mulsi */
348 COSTS_N_INSNS (2), /* mulsi_const */
349 COSTS_N_INSNS (2), /* mulsi_const9 */
350 COSTS_N_INSNS (2), /* muldi */
351 COSTS_N_INSNS (13), /* divsi */
352 COSTS_N_INSNS (13), /* divdi */
353 COSTS_N_INSNS (2), /* fp */
354 COSTS_N_INSNS (2), /* dmul */
355 COSTS_N_INSNS (17), /* sdiv */
356 COSTS_N_INSNS (17), /* ddiv */
359 /* Instruction costs on RS64A processors. */
360 static const
361 struct processor_costs rs64a_cost = {
362 COSTS_N_INSNS (20), /* mulsi */
363 COSTS_N_INSNS (12), /* mulsi_const */
364 COSTS_N_INSNS (8), /* mulsi_const9 */
365 COSTS_N_INSNS (34), /* muldi */
366 COSTS_N_INSNS (65), /* divsi */
367 COSTS_N_INSNS (67), /* divdi */
368 COSTS_N_INSNS (4), /* fp */
369 COSTS_N_INSNS (4), /* dmul */
370 COSTS_N_INSNS (31), /* sdiv */
371 COSTS_N_INSNS (31), /* ddiv */
374 /* Instruction costs on MPCCORE processors. */
375 static const
376 struct processor_costs mpccore_cost = {
377 COSTS_N_INSNS (2), /* mulsi */
378 COSTS_N_INSNS (2), /* mulsi_const */
379 COSTS_N_INSNS (2), /* mulsi_const9 */
380 COSTS_N_INSNS (2), /* muldi */
381 COSTS_N_INSNS (6), /* divsi */
382 COSTS_N_INSNS (6), /* divdi */
383 COSTS_N_INSNS (4), /* fp */
384 COSTS_N_INSNS (5), /* dmul */
385 COSTS_N_INSNS (10), /* sdiv */
386 COSTS_N_INSNS (17), /* ddiv */
389 /* Instruction costs on PPC403 processors. */
390 static const
391 struct processor_costs ppc403_cost = {
392 COSTS_N_INSNS (4), /* mulsi */
393 COSTS_N_INSNS (4), /* mulsi_const */
394 COSTS_N_INSNS (4), /* mulsi_const9 */
395 COSTS_N_INSNS (4), /* muldi */
396 COSTS_N_INSNS (33), /* divsi */
397 COSTS_N_INSNS (33), /* divdi */
398 COSTS_N_INSNS (11), /* fp */
399 COSTS_N_INSNS (11), /* dmul */
400 COSTS_N_INSNS (11), /* sdiv */
401 COSTS_N_INSNS (11), /* ddiv */
404 /* Instruction costs on PPC405 processors. */
405 static const
406 struct processor_costs ppc405_cost = {
407 COSTS_N_INSNS (5), /* mulsi */
408 COSTS_N_INSNS (4), /* mulsi_const */
409 COSTS_N_INSNS (3), /* mulsi_const9 */
410 COSTS_N_INSNS (5), /* muldi */
411 COSTS_N_INSNS (35), /* divsi */
412 COSTS_N_INSNS (35), /* divdi */
413 COSTS_N_INSNS (11), /* fp */
414 COSTS_N_INSNS (11), /* dmul */
415 COSTS_N_INSNS (11), /* sdiv */
416 COSTS_N_INSNS (11), /* ddiv */
419 /* Instruction costs on PPC440 processors. */
420 static const
421 struct processor_costs ppc440_cost = {
422 COSTS_N_INSNS (3), /* mulsi */
423 COSTS_N_INSNS (2), /* mulsi_const */
424 COSTS_N_INSNS (2), /* mulsi_const9 */
425 COSTS_N_INSNS (3), /* muldi */
426 COSTS_N_INSNS (34), /* divsi */
427 COSTS_N_INSNS (34), /* divdi */
428 COSTS_N_INSNS (5), /* fp */
429 COSTS_N_INSNS (5), /* dmul */
430 COSTS_N_INSNS (19), /* sdiv */
431 COSTS_N_INSNS (33), /* ddiv */
434 /* Instruction costs on PPC601 processors. */
435 static const
436 struct processor_costs ppc601_cost = {
437 COSTS_N_INSNS (5), /* mulsi */
438 COSTS_N_INSNS (5), /* mulsi_const */
439 COSTS_N_INSNS (5), /* mulsi_const9 */
440 COSTS_N_INSNS (5), /* muldi */
441 COSTS_N_INSNS (36), /* divsi */
442 COSTS_N_INSNS (36), /* divdi */
443 COSTS_N_INSNS (4), /* fp */
444 COSTS_N_INSNS (5), /* dmul */
445 COSTS_N_INSNS (17), /* sdiv */
446 COSTS_N_INSNS (31), /* ddiv */
449 /* Instruction costs on PPC603 processors. */
450 static const
451 struct processor_costs ppc603_cost = {
452 COSTS_N_INSNS (5), /* mulsi */
453 COSTS_N_INSNS (3), /* mulsi_const */
454 COSTS_N_INSNS (2), /* mulsi_const9 */
455 COSTS_N_INSNS (5), /* muldi */
456 COSTS_N_INSNS (37), /* divsi */
457 COSTS_N_INSNS (37), /* divdi */
458 COSTS_N_INSNS (3), /* fp */
459 COSTS_N_INSNS (4), /* dmul */
460 COSTS_N_INSNS (18), /* sdiv */
461 COSTS_N_INSNS (33), /* ddiv */
464 /* Instruction costs on PPC604 processors. */
465 static const
466 struct processor_costs ppc604_cost = {
467 COSTS_N_INSNS (4), /* mulsi */
468 COSTS_N_INSNS (4), /* mulsi_const */
469 COSTS_N_INSNS (4), /* mulsi_const9 */
470 COSTS_N_INSNS (4), /* muldi */
471 COSTS_N_INSNS (20), /* divsi */
472 COSTS_N_INSNS (20), /* divdi */
473 COSTS_N_INSNS (3), /* fp */
474 COSTS_N_INSNS (3), /* dmul */
475 COSTS_N_INSNS (18), /* sdiv */
476 COSTS_N_INSNS (32), /* ddiv */
479 /* Instruction costs on PPC604e processors. */
480 static const
481 struct processor_costs ppc604e_cost = {
482 COSTS_N_INSNS (2), /* mulsi */
483 COSTS_N_INSNS (2), /* mulsi_const */
484 COSTS_N_INSNS (2), /* mulsi_const9 */
485 COSTS_N_INSNS (2), /* muldi */
486 COSTS_N_INSNS (20), /* divsi */
487 COSTS_N_INSNS (20), /* divdi */
488 COSTS_N_INSNS (3), /* fp */
489 COSTS_N_INSNS (3), /* dmul */
490 COSTS_N_INSNS (18), /* sdiv */
491 COSTS_N_INSNS (32), /* ddiv */
494 /* Instruction costs on PPC620 processors. */
495 static const
496 struct processor_costs ppc620_cost = {
497 COSTS_N_INSNS (5), /* mulsi */
498 COSTS_N_INSNS (4), /* mulsi_const */
499 COSTS_N_INSNS (3), /* mulsi_const9 */
500 COSTS_N_INSNS (7), /* muldi */
501 COSTS_N_INSNS (21), /* divsi */
502 COSTS_N_INSNS (37), /* divdi */
503 COSTS_N_INSNS (3), /* fp */
504 COSTS_N_INSNS (3), /* dmul */
505 COSTS_N_INSNS (18), /* sdiv */
506 COSTS_N_INSNS (32), /* ddiv */
509 /* Instruction costs on PPC630 processors. */
510 static const
511 struct processor_costs ppc630_cost = {
512 COSTS_N_INSNS (5), /* mulsi */
513 COSTS_N_INSNS (4), /* mulsi_const */
514 COSTS_N_INSNS (3), /* mulsi_const9 */
515 COSTS_N_INSNS (7), /* muldi */
516 COSTS_N_INSNS (21), /* divsi */
517 COSTS_N_INSNS (37), /* divdi */
518 COSTS_N_INSNS (3), /* fp */
519 COSTS_N_INSNS (3), /* dmul */
520 COSTS_N_INSNS (17), /* sdiv */
521 COSTS_N_INSNS (21), /* ddiv */
524 /* Instruction costs on Cell processor. */
525 /* COSTS_N_INSNS (1) ~ one add. */
526 static const
527 struct processor_costs ppccell_cost = {
528 COSTS_N_INSNS (9/2)+2, /* mulsi */
529 COSTS_N_INSNS (6/2), /* mulsi_const */
530 COSTS_N_INSNS (6/2), /* mulsi_const9 */
531 COSTS_N_INSNS (15/2)+2, /* muldi */
532 COSTS_N_INSNS (38/2), /* divsi */
533 COSTS_N_INSNS (70/2), /* divdi */
534 COSTS_N_INSNS (10/2), /* fp */
535 COSTS_N_INSNS (10/2), /* dmul */
536 COSTS_N_INSNS (74/2), /* sdiv */
537 COSTS_N_INSNS (74/2), /* ddiv */
540 /* Instruction costs on PPC750 and PPC7400 processors. */
541 static const
542 struct processor_costs ppc750_cost = {
543 COSTS_N_INSNS (5), /* mulsi */
544 COSTS_N_INSNS (3), /* mulsi_const */
545 COSTS_N_INSNS (2), /* mulsi_const9 */
546 COSTS_N_INSNS (5), /* muldi */
547 COSTS_N_INSNS (17), /* divsi */
548 COSTS_N_INSNS (17), /* divdi */
549 COSTS_N_INSNS (3), /* fp */
550 COSTS_N_INSNS (3), /* dmul */
551 COSTS_N_INSNS (17), /* sdiv */
552 COSTS_N_INSNS (31), /* ddiv */
555 /* Instruction costs on PPC7450 processors. */
556 static const
557 struct processor_costs ppc7450_cost = {
558 COSTS_N_INSNS (4), /* mulsi */
559 COSTS_N_INSNS (3), /* mulsi_const */
560 COSTS_N_INSNS (3), /* mulsi_const9 */
561 COSTS_N_INSNS (4), /* muldi */
562 COSTS_N_INSNS (23), /* divsi */
563 COSTS_N_INSNS (23), /* divdi */
564 COSTS_N_INSNS (5), /* fp */
565 COSTS_N_INSNS (5), /* dmul */
566 COSTS_N_INSNS (21), /* sdiv */
567 COSTS_N_INSNS (35), /* ddiv */
570 /* Instruction costs on PPC8540 processors. */
571 static const
572 struct processor_costs ppc8540_cost = {
573 COSTS_N_INSNS (4), /* mulsi */
574 COSTS_N_INSNS (4), /* mulsi_const */
575 COSTS_N_INSNS (4), /* mulsi_const9 */
576 COSTS_N_INSNS (4), /* muldi */
577 COSTS_N_INSNS (19), /* divsi */
578 COSTS_N_INSNS (19), /* divdi */
579 COSTS_N_INSNS (4), /* fp */
580 COSTS_N_INSNS (4), /* dmul */
581 COSTS_N_INSNS (29), /* sdiv */
582 COSTS_N_INSNS (29), /* ddiv */
585 /* Instruction costs on POWER4 and POWER5 processors. */
586 static const
587 struct processor_costs power4_cost = {
588 COSTS_N_INSNS (3), /* mulsi */
589 COSTS_N_INSNS (2), /* mulsi_const */
590 COSTS_N_INSNS (2), /* mulsi_const9 */
591 COSTS_N_INSNS (4), /* muldi */
592 COSTS_N_INSNS (18), /* divsi */
593 COSTS_N_INSNS (34), /* divdi */
594 COSTS_N_INSNS (3), /* fp */
595 COSTS_N_INSNS (3), /* dmul */
596 COSTS_N_INSNS (17), /* sdiv */
597 COSTS_N_INSNS (17), /* ddiv */
600 /* Instruction costs on POWER6 processors. */
601 static const
602 struct processor_costs power6_cost = {
603 COSTS_N_INSNS (8), /* mulsi */
604 COSTS_N_INSNS (8), /* mulsi_const */
605 COSTS_N_INSNS (8), /* mulsi_const9 */
606 COSTS_N_INSNS (8), /* muldi */
607 COSTS_N_INSNS (22), /* divsi */
608 COSTS_N_INSNS (28), /* divdi */
609 COSTS_N_INSNS (3), /* fp */
610 COSTS_N_INSNS (3), /* dmul */
611 COSTS_N_INSNS (13), /* sdiv */
612 COSTS_N_INSNS (16), /* ddiv */
616 static bool rs6000_function_ok_for_sibcall (tree, tree);
617 static const char *rs6000_invalid_within_doloop (rtx);
618 static rtx rs6000_generate_compare (enum rtx_code);
619 static void rs6000_maybe_dead (rtx);
620 static void rs6000_emit_stack_tie (void);
621 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
622 static rtx spe_synthesize_frame_save (rtx);
623 static bool spe_func_has_64bit_regs_p (void);
624 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
625 int, HOST_WIDE_INT);
626 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
627 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
628 static unsigned rs6000_hash_constant (rtx);
629 static unsigned toc_hash_function (const void *);
630 static int toc_hash_eq (const void *, const void *);
631 static int constant_pool_expr_1 (rtx, int *, int *);
632 static bool constant_pool_expr_p (rtx);
633 static bool legitimate_small_data_p (enum machine_mode, rtx);
634 static bool legitimate_indexed_address_p (rtx, int);
635 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
636 static struct machine_function * rs6000_init_machine_status (void);
637 static bool rs6000_assemble_integer (rtx, unsigned int, int);
638 static bool no_global_regs_above (int);
639 #ifdef HAVE_GAS_HIDDEN
640 static void rs6000_assemble_visibility (tree, int);
641 #endif
642 static int rs6000_ra_ever_killed (void);
643 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
644 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
645 static bool rs6000_ms_bitfield_layout_p (tree);
646 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
647 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
648 static const char *rs6000_mangle_fundamental_type (tree);
649 extern const struct attribute_spec rs6000_attribute_table[];
650 static void rs6000_set_default_type_attributes (tree);
651 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
652 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
653 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
654 tree);
655 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
656 static bool rs6000_return_in_memory (tree, tree);
657 static void rs6000_file_start (void);
658 #if TARGET_ELF
659 static unsigned int rs6000_elf_section_type_flags (tree, const char *, int);
660 static void rs6000_elf_asm_out_constructor (rtx, int);
661 static void rs6000_elf_asm_out_destructor (rtx, int);
662 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
663 static void rs6000_elf_asm_init_sections (void);
664 static section *rs6000_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
665 static void rs6000_elf_unique_section (tree, int);
666 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
667 unsigned HOST_WIDE_INT);
668 static void rs6000_elf_encode_section_info (tree, rtx, int)
669 ATTRIBUTE_UNUSED;
670 #endif
671 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, rtx);
672 #if TARGET_XCOFF
673 static void rs6000_xcoff_asm_output_anchor (rtx);
674 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
675 static void rs6000_xcoff_asm_init_sections (void);
676 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
677 static section *rs6000_xcoff_select_section (tree, int,
678 unsigned HOST_WIDE_INT);
679 static void rs6000_xcoff_unique_section (tree, int);
680 static section *rs6000_xcoff_select_rtx_section
681 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
682 static const char * rs6000_xcoff_strip_name_encoding (const char *);
683 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
684 static void rs6000_xcoff_file_start (void);
685 static void rs6000_xcoff_file_end (void);
686 #endif
687 static int rs6000_variable_issue (FILE *, int, rtx, int);
688 static bool rs6000_rtx_costs (rtx, int, int, int *);
689 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
690 static void rs6000_sched_init (FILE *, int, int);
691 static bool is_microcoded_insn (rtx);
692 static bool is_nonpipeline_insn (rtx);
693 static bool is_cracked_insn (rtx);
694 static bool is_branch_slot_insn (rtx);
695 static bool is_load_insn (rtx);
696 static rtx get_store_dest (rtx pat);
697 static bool is_store_insn (rtx);
698 static bool set_to_load_agen (rtx,rtx);
699 static bool adjacent_mem_locations (rtx,rtx);
700 static int rs6000_adjust_priority (rtx, int);
701 static int rs6000_issue_rate (void);
702 static bool rs6000_is_costly_dependence (rtx, rtx, rtx, int, int);
703 static rtx get_next_active_insn (rtx, rtx);
704 static bool insn_terminates_group_p (rtx , enum group_termination);
705 static bool insn_must_be_first_in_group (rtx);
706 static bool insn_must_be_last_in_group (rtx);
707 static bool is_costly_group (rtx *, rtx);
708 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
709 static int redefine_groups (FILE *, int, rtx, rtx);
710 static int pad_groups (FILE *, int, rtx, rtx);
711 static void rs6000_sched_finish (FILE *, int);
712 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
713 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
714 static int rs6000_use_sched_lookahead (void);
715 static int rs6000_use_sched_lookahead_guard (rtx);
716 static tree rs6000_builtin_mask_for_load (void);
717 static tree rs6000_builtin_mul_widen_even (tree);
718 static tree rs6000_builtin_mul_widen_odd (tree);
720 static void def_builtin (int, const char *, tree, int);
721 static void rs6000_init_builtins (void);
722 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
723 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
724 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
725 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
726 static void altivec_init_builtins (void);
727 static void rs6000_common_init_builtins (void);
728 static void rs6000_init_libfuncs (void);
730 static void enable_mask_for_builtins (struct builtin_description *, int,
731 enum rs6000_builtins,
732 enum rs6000_builtins);
733 static tree build_opaque_vector_type (tree, int);
734 static void spe_init_builtins (void);
735 static rtx spe_expand_builtin (tree, rtx, bool *);
736 static rtx spe_expand_stv_builtin (enum insn_code, tree);
737 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
738 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
739 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
740 static rs6000_stack_t *rs6000_stack_info (void);
741 static void debug_stack_info (rs6000_stack_t *);
743 static rtx altivec_expand_builtin (tree, rtx, bool *);
744 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
745 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
746 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
747 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
748 static rtx altivec_expand_predicate_builtin (enum insn_code,
749 const char *, tree, rtx);
750 static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
751 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
752 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
753 static rtx altivec_expand_vec_set_builtin (tree);
754 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
755 static int get_element_number (tree, tree);
756 static bool rs6000_handle_option (size_t, const char *, int);
757 static void rs6000_parse_tls_size_option (void);
758 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
759 static int first_altivec_reg_to_save (void);
760 static unsigned int compute_vrsave_mask (void);
761 static void compute_save_world_info (rs6000_stack_t *info_ptr);
762 static void is_altivec_return_reg (rtx, void *);
763 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
764 int easy_vector_constant (rtx, enum machine_mode);
765 static bool rs6000_is_opaque_type (tree);
766 static rtx rs6000_dwarf_register_span (rtx);
767 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
768 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
769 static rtx rs6000_tls_get_addr (void);
770 static rtx rs6000_got_sym (void);
771 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
772 static const char *rs6000_get_some_local_dynamic_name (void);
773 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
774 static rtx rs6000_complex_function_value (enum machine_mode);
775 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
776 enum machine_mode, tree);
777 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
778 HOST_WIDE_INT);
779 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
780 tree, HOST_WIDE_INT);
781 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
782 HOST_WIDE_INT,
783 rtx[], int *);
784 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
785 tree, HOST_WIDE_INT,
786 rtx[], int *);
787 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, tree, int, bool);
788 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
789 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
790 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
791 enum machine_mode, tree,
792 int *, int);
793 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
794 tree, bool);
795 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
796 tree, bool);
797 static const char *invalid_arg_for_unprototyped_fn (tree, tree, tree);
798 #if TARGET_MACHO
799 static void macho_branch_islands (void);
800 static void add_compiler_branch_island (tree, tree, int);
801 static int no_previous_def (tree function_name);
802 static tree get_prev_label (tree function_name);
803 static void rs6000_darwin_file_start (void);
804 #endif
806 static tree rs6000_build_builtin_va_list (void);
807 static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
808 static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
809 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
810 static bool rs6000_vector_mode_supported_p (enum machine_mode);
811 static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
812 enum machine_mode);
813 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
814 enum machine_mode);
815 static int get_vsel_insn (enum machine_mode);
816 static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
817 static tree rs6000_stack_protect_fail (void);
819 const int INSN_NOT_AVAILABLE = -1;
820 static enum machine_mode rs6000_eh_return_filter_mode (void);
822 /* Hash table stuff for keeping track of TOC entries. */
824 struct toc_hash_struct GTY(())
826 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
827 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
828 rtx key;
829 enum machine_mode key_mode;
830 int labelno;
833 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
835 /* Default register names. */
836 char rs6000_reg_names[][8] =
838 "0", "1", "2", "3", "4", "5", "6", "7",
839 "8", "9", "10", "11", "12", "13", "14", "15",
840 "16", "17", "18", "19", "20", "21", "22", "23",
841 "24", "25", "26", "27", "28", "29", "30", "31",
842 "0", "1", "2", "3", "4", "5", "6", "7",
843 "8", "9", "10", "11", "12", "13", "14", "15",
844 "16", "17", "18", "19", "20", "21", "22", "23",
845 "24", "25", "26", "27", "28", "29", "30", "31",
846 "mq", "lr", "ctr","ap",
847 "0", "1", "2", "3", "4", "5", "6", "7",
848 "xer",
849 /* AltiVec registers. */
850 "0", "1", "2", "3", "4", "5", "6", "7",
851 "8", "9", "10", "11", "12", "13", "14", "15",
852 "16", "17", "18", "19", "20", "21", "22", "23",
853 "24", "25", "26", "27", "28", "29", "30", "31",
854 "vrsave", "vscr",
855 /* SPE registers. */
856 "spe_acc", "spefscr",
857 /* Soft frame pointer. */
858 "sfp"
861 #ifdef TARGET_REGNAMES
862 static const char alt_reg_names[][8] =
864 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
865 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
866 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
867 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
868 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
869 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
870 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
871 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
872 "mq", "lr", "ctr", "ap",
873 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
874 "xer",
875 /* AltiVec registers. */
876 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
877 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
878 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
879 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
880 "vrsave", "vscr",
881 /* SPE registers. */
882 "spe_acc", "spefscr",
883 /* Soft frame pointer. */
884 "sfp"
886 #endif
888 #ifndef MASK_STRICT_ALIGN
889 #define MASK_STRICT_ALIGN 0
890 #endif
891 #ifndef TARGET_PROFILE_KERNEL
892 #define TARGET_PROFILE_KERNEL 0
893 #endif
895 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
896 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
898 /* Initialize the GCC target structure. */
899 #undef TARGET_ATTRIBUTE_TABLE
900 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
901 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
902 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
904 #undef TARGET_ASM_ALIGNED_DI_OP
905 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
907 /* Default unaligned ops are only provided for ELF. Find the ops needed
908 for non-ELF systems. */
909 #ifndef OBJECT_FORMAT_ELF
910 #if TARGET_XCOFF
911 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
912 64-bit targets. */
913 #undef TARGET_ASM_UNALIGNED_HI_OP
914 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
915 #undef TARGET_ASM_UNALIGNED_SI_OP
916 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
917 #undef TARGET_ASM_UNALIGNED_DI_OP
918 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
919 #else
920 /* For Darwin. */
921 #undef TARGET_ASM_UNALIGNED_HI_OP
922 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
923 #undef TARGET_ASM_UNALIGNED_SI_OP
924 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
925 #undef TARGET_ASM_UNALIGNED_DI_OP
926 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
927 #undef TARGET_ASM_ALIGNED_DI_OP
928 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
929 #endif
930 #endif
932 /* This hook deals with fixups for relocatable code and DI-mode objects
933 in 64-bit code. */
934 #undef TARGET_ASM_INTEGER
935 #define TARGET_ASM_INTEGER rs6000_assemble_integer
937 #ifdef HAVE_GAS_HIDDEN
938 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
939 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
940 #endif
942 #undef TARGET_HAVE_TLS
943 #define TARGET_HAVE_TLS HAVE_AS_TLS
945 #undef TARGET_CANNOT_FORCE_CONST_MEM
946 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
948 #undef TARGET_ASM_FUNCTION_PROLOGUE
949 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
950 #undef TARGET_ASM_FUNCTION_EPILOGUE
951 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
953 #undef TARGET_SCHED_VARIABLE_ISSUE
954 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
956 #undef TARGET_SCHED_ISSUE_RATE
957 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
958 #undef TARGET_SCHED_ADJUST_COST
959 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
960 #undef TARGET_SCHED_ADJUST_PRIORITY
961 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
962 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
963 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
964 #undef TARGET_SCHED_INIT
965 #define TARGET_SCHED_INIT rs6000_sched_init
966 #undef TARGET_SCHED_FINISH
967 #define TARGET_SCHED_FINISH rs6000_sched_finish
968 #undef TARGET_SCHED_REORDER
969 #define TARGET_SCHED_REORDER rs6000_sched_reorder
970 #undef TARGET_SCHED_REORDER2
971 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
973 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
974 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
976 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
977 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
979 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
980 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
981 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
982 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
983 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
984 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
986 #undef TARGET_INIT_BUILTINS
987 #define TARGET_INIT_BUILTINS rs6000_init_builtins
989 #undef TARGET_EXPAND_BUILTIN
990 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
992 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
993 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
995 #undef TARGET_INIT_LIBFUNCS
996 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
998 #if TARGET_MACHO
999 #undef TARGET_BINDS_LOCAL_P
1000 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1001 #endif
1003 #undef TARGET_MS_BITFIELD_LAYOUT_P
1004 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1006 #undef TARGET_ASM_OUTPUT_MI_THUNK
1007 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1009 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1010 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
1012 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1013 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1015 #undef TARGET_INVALID_WITHIN_DOLOOP
1016 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1018 #undef TARGET_RTX_COSTS
1019 #define TARGET_RTX_COSTS rs6000_rtx_costs
1020 #undef TARGET_ADDRESS_COST
1021 #define TARGET_ADDRESS_COST hook_int_rtx_0
1023 #undef TARGET_VECTOR_OPAQUE_P
1024 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
1026 #undef TARGET_DWARF_REGISTER_SPAN
1027 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1029 /* On rs6000, function arguments are promoted, as are function return
1030 values. */
1031 #undef TARGET_PROMOTE_FUNCTION_ARGS
1032 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
1033 #undef TARGET_PROMOTE_FUNCTION_RETURN
1034 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
1036 #undef TARGET_RETURN_IN_MEMORY
1037 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1039 #undef TARGET_SETUP_INCOMING_VARARGS
1040 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1042 /* Always strict argument naming on rs6000. */
1043 #undef TARGET_STRICT_ARGUMENT_NAMING
1044 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1045 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1046 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1047 #undef TARGET_SPLIT_COMPLEX_ARG
1048 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
1049 #undef TARGET_MUST_PASS_IN_STACK
1050 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1051 #undef TARGET_PASS_BY_REFERENCE
1052 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1053 #undef TARGET_ARG_PARTIAL_BYTES
1054 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1056 #undef TARGET_BUILD_BUILTIN_VA_LIST
1057 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1059 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1060 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1062 #undef TARGET_EH_RETURN_FILTER_MODE
1063 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1065 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1066 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1068 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1069 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1071 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1072 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1074 #undef TARGET_HANDLE_OPTION
1075 #define TARGET_HANDLE_OPTION rs6000_handle_option
1077 #undef TARGET_DEFAULT_TARGET_FLAGS
1078 #define TARGET_DEFAULT_TARGET_FLAGS \
1079 (TARGET_DEFAULT)
1081 #undef TARGET_STACK_PROTECT_FAIL
1082 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1084 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1085 The PowerPC architecture requires only weak consistency among
1086 processors--that is, memory accesses between processors need not be
1087 sequentially consistent and memory accesses among processors can occur
1088 in any order. The ability to order memory accesses weakly provides
1089 opportunities for more efficient use of the system bus. Unless a
1090 dependency exists, the 604e allows read operations to precede store
1091 operations. */
1092 #undef TARGET_RELAXED_ORDERING
1093 #define TARGET_RELAXED_ORDERING true
1095 #ifdef HAVE_AS_TLS
1096 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1097 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1098 #endif
1100 /* Use a 32-bit anchor range. This leads to sequences like:
1102 addis tmp,anchor,high
1103 add dest,tmp,low
1105 where tmp itself acts as an anchor, and can be shared between
1106 accesses to the same 64k page. */
1107 #undef TARGET_MIN_ANCHOR_OFFSET
1108 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1109 #undef TARGET_MAX_ANCHOR_OFFSET
1110 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1111 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1112 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1114 struct gcc_target targetm = TARGET_INITIALIZER;
1117 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1118 MODE. */
1119 static int
1120 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1122 /* The GPRs can hold any mode, but values bigger than one register
1123 cannot go past R31. */
1124 if (INT_REGNO_P (regno))
1125 return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
1127 /* The float registers can only hold floating modes and DImode.
1128 This also excludes decimal float modes. */
1129 if (FP_REGNO_P (regno))
1130 return
1131 (SCALAR_FLOAT_MODE_P (mode)
1132 && !DECIMAL_FLOAT_MODE_P (mode)
1133 && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
1134 || (GET_MODE_CLASS (mode) == MODE_INT
1135 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
1137 /* The CR register can only hold CC modes. */
1138 if (CR_REGNO_P (regno))
1139 return GET_MODE_CLASS (mode) == MODE_CC;
1141 if (XER_REGNO_P (regno))
1142 return mode == PSImode;
1144 /* AltiVec only in AldyVec registers. */
1145 if (ALTIVEC_REGNO_P (regno))
1146 return ALTIVEC_VECTOR_MODE (mode);
1148 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1149 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1150 return 1;
1152 /* We cannot put TImode anywhere except general register and it must be
1153 able to fit within the register set. */
1155 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1158 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1159 static void
1160 rs6000_init_hard_regno_mode_ok (void)
1162 int r, m;
1164 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1165 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1166 if (rs6000_hard_regno_mode_ok (r, m))
1167 rs6000_hard_regno_mode_ok_p[m][r] = true;
1170 /* If not otherwise specified by a target, make 'long double' equivalent to
1171 'double'. */
1173 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1174 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1175 #endif
1177 /* Override command line options. Mostly we process the processor
1178 type and sometimes adjust other TARGET_ options. */
1180 void
1181 rs6000_override_options (const char *default_cpu)
1183 size_t i, j;
1184 struct rs6000_cpu_select *ptr;
1185 int set_masks;
1187 /* Simplifications for entries below. */
1189 enum {
1190 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1191 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1194 /* This table occasionally claims that a processor does not support
1195 a particular feature even though it does, but the feature is slower
1196 than the alternative. Thus, it shouldn't be relied on as a
1197 complete description of the processor's support.
1199 Please keep this list in order, and don't forget to update the
1200 documentation in invoke.texi when adding a new processor or
1201 flag. */
1202 static struct ptt
1204 const char *const name; /* Canonical processor name. */
1205 const enum processor_type processor; /* Processor type enum value. */
1206 const int target_enable; /* Target flags to enable. */
1207 } const processor_target_table[]
1208 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1209 {"403", PROCESSOR_PPC403,
1210 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1211 {"405", PROCESSOR_PPC405,
1212 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1213 {"405fp", PROCESSOR_PPC405,
1214 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1215 {"440", PROCESSOR_PPC440,
1216 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1217 {"440fp", PROCESSOR_PPC440,
1218 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1219 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1220 {"601", PROCESSOR_PPC601,
1221 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1222 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1223 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1224 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1225 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1226 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1227 {"620", PROCESSOR_PPC620,
1228 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1229 {"630", PROCESSOR_PPC630,
1230 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1231 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1232 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1233 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1234 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1235 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1236 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1237 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1238 {"8540", PROCESSOR_PPC8540,
1239 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_STRICT_ALIGN},
1240 /* 8548 has a dummy entry for now. */
1241 {"8548", PROCESSOR_PPC8540,
1242 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_STRICT_ALIGN},
1243 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1244 {"970", PROCESSOR_POWER4,
1245 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1246 {"cell", PROCESSOR_CELL,
1247 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1248 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1249 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1250 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1251 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1252 {"G5", PROCESSOR_POWER4,
1253 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1254 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1255 {"power2", PROCESSOR_POWER,
1256 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1257 {"power3", PROCESSOR_PPC630,
1258 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1259 {"power4", PROCESSOR_POWER4,
1260 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
1261 {"power5", PROCESSOR_POWER5,
1262 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1263 | MASK_MFCRF | MASK_POPCNTB},
1264 {"power5+", PROCESSOR_POWER5,
1265 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1266 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1267 {"power6", PROCESSOR_POWER6,
1268 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
1269 | MASK_FPRND},
1270 {"power6x", PROCESSOR_POWER6,
1271 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
1272 | MASK_FPRND | MASK_MFPGPR},
1273 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1274 {"powerpc64", PROCESSOR_POWERPC64,
1275 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1276 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1277 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1278 {"rios2", PROCESSOR_RIOS2,
1279 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1280 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1281 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1282 {"rs64", PROCESSOR_RS64A,
1283 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1286 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
1288 /* Some OSs don't support saving the high part of 64-bit registers on
1289 context switch. Other OSs don't support saving Altivec registers.
1290 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1291 settings; if the user wants either, the user must explicitly specify
1292 them and we won't interfere with the user's specification. */
1294 enum {
1295 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1296 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1297 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1298 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1299 | MASK_DLMZB | MASK_MFPGPR)
1302 rs6000_init_hard_regno_mode_ok ();
1304 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
1305 #ifdef OS_MISSING_POWERPC64
1306 if (OS_MISSING_POWERPC64)
1307 set_masks &= ~MASK_POWERPC64;
1308 #endif
1309 #ifdef OS_MISSING_ALTIVEC
1310 if (OS_MISSING_ALTIVEC)
1311 set_masks &= ~MASK_ALTIVEC;
1312 #endif
1314 /* Don't override by the processor default if given explicitly. */
1315 set_masks &= ~target_flags_explicit;
1317 /* Identify the processor type. */
1318 rs6000_select[0].string = default_cpu;
1319 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
1321 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
1323 ptr = &rs6000_select[i];
1324 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
1326 for (j = 0; j < ptt_size; j++)
1327 if (! strcmp (ptr->string, processor_target_table[j].name))
1329 if (ptr->set_tune_p)
1330 rs6000_cpu = processor_target_table[j].processor;
1332 if (ptr->set_arch_p)
1334 target_flags &= ~set_masks;
1335 target_flags |= (processor_target_table[j].target_enable
1336 & set_masks);
1338 break;
1341 if (j == ptt_size)
1342 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
1346 if (TARGET_E500)
1347 rs6000_isel = 1;
1349 /* If we are optimizing big endian systems for space, use the load/store
1350 multiple and string instructions. */
1351 if (BYTES_BIG_ENDIAN && optimize_size)
1352 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
1354 /* Don't allow -mmultiple or -mstring on little endian systems
1355 unless the cpu is a 750, because the hardware doesn't support the
1356 instructions used in little endian mode, and causes an alignment
1357 trap. The 750 does not cause an alignment trap (except when the
1358 target is unaligned). */
1360 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
1362 if (TARGET_MULTIPLE)
1364 target_flags &= ~MASK_MULTIPLE;
1365 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
1366 warning (0, "-mmultiple is not supported on little endian systems");
1369 if (TARGET_STRING)
1371 target_flags &= ~MASK_STRING;
1372 if ((target_flags_explicit & MASK_STRING) != 0)
1373 warning (0, "-mstring is not supported on little endian systems");
1377 /* Set debug flags */
1378 if (rs6000_debug_name)
1380 if (! strcmp (rs6000_debug_name, "all"))
1381 rs6000_debug_stack = rs6000_debug_arg = 1;
1382 else if (! strcmp (rs6000_debug_name, "stack"))
1383 rs6000_debug_stack = 1;
1384 else if (! strcmp (rs6000_debug_name, "arg"))
1385 rs6000_debug_arg = 1;
1386 else
1387 error ("unknown -mdebug-%s switch", rs6000_debug_name);
1390 if (rs6000_traceback_name)
1392 if (! strncmp (rs6000_traceback_name, "full", 4))
1393 rs6000_traceback = traceback_full;
1394 else if (! strncmp (rs6000_traceback_name, "part", 4))
1395 rs6000_traceback = traceback_part;
1396 else if (! strncmp (rs6000_traceback_name, "no", 2))
1397 rs6000_traceback = traceback_none;
1398 else
1399 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1400 rs6000_traceback_name);
1403 if (!rs6000_explicit_options.long_double)
1404 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1406 #ifndef POWERPC_LINUX
1407 if (!rs6000_explicit_options.ieee)
1408 rs6000_ieeequad = 1;
1409 #endif
1411 /* Set Altivec ABI as default for powerpc64 linux. */
1412 if (TARGET_ELF && TARGET_64BIT)
1414 rs6000_altivec_abi = 1;
1415 TARGET_ALTIVEC_VRSAVE = 1;
1418 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1419 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1421 rs6000_darwin64_abi = 1;
1422 #if TARGET_MACHO
1423 darwin_one_byte_bool = 1;
1424 #endif
1425 /* Default to natural alignment, for better performance. */
1426 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
1429 /* Place FP constants in the constant pool instead of TOC
1430 if section anchors enabled. */
1431 if (flag_section_anchors)
1432 TARGET_NO_FP_IN_TOC = 1;
1434 /* Handle -mtls-size option. */
1435 rs6000_parse_tls_size_option ();
1437 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1438 SUBTARGET_OVERRIDE_OPTIONS;
1439 #endif
1440 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1441 SUBSUBTARGET_OVERRIDE_OPTIONS;
1442 #endif
1443 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1444 SUB3TARGET_OVERRIDE_OPTIONS;
1445 #endif
1447 if (TARGET_E500)
1449 /* The e500 does not have string instructions, and we set
1450 MASK_STRING above when optimizing for size. */
1451 if ((target_flags & MASK_STRING) != 0)
1452 target_flags = target_flags & ~MASK_STRING;
1454 else if (rs6000_select[1].string != NULL)
1456 /* For the powerpc-eabispe configuration, we set all these by
1457 default, so let's unset them if we manually set another
1458 CPU that is not the E500. */
1459 if (!rs6000_explicit_options.abi)
1460 rs6000_spe_abi = 0;
1461 if (!rs6000_explicit_options.spe)
1462 rs6000_spe = 0;
1463 if (!rs6000_explicit_options.float_gprs)
1464 rs6000_float_gprs = 0;
1465 if (!rs6000_explicit_options.isel)
1466 rs6000_isel = 0;
1467 if (!rs6000_explicit_options.long_double)
1468 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1471 /* Detect invalid option combinations with E500. */
1472 CHECK_E500_OPTIONS;
1474 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
1475 && rs6000_cpu != PROCESSOR_POWER5
1476 && rs6000_cpu != PROCESSOR_POWER6
1477 && rs6000_cpu != PROCESSOR_CELL);
1478 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
1479 || rs6000_cpu == PROCESSOR_POWER5);
1480 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
1481 || rs6000_cpu == PROCESSOR_POWER5
1482 || rs6000_cpu == PROCESSOR_POWER6);
1484 rs6000_sched_restricted_insns_priority
1485 = (rs6000_sched_groups ? 1 : 0);
1487 /* Handle -msched-costly-dep option. */
1488 rs6000_sched_costly_dep
1489 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
1491 if (rs6000_sched_costly_dep_str)
1493 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
1494 rs6000_sched_costly_dep = no_dep_costly;
1495 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
1496 rs6000_sched_costly_dep = all_deps_costly;
1497 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
1498 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
1499 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
1500 rs6000_sched_costly_dep = store_to_load_dep_costly;
1501 else
1502 rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
1505 /* Handle -minsert-sched-nops option. */
1506 rs6000_sched_insert_nops
1507 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
1509 if (rs6000_sched_insert_nops_str)
1511 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
1512 rs6000_sched_insert_nops = sched_finish_none;
1513 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
1514 rs6000_sched_insert_nops = sched_finish_pad_groups;
1515 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
1516 rs6000_sched_insert_nops = sched_finish_regroup_exact;
1517 else
1518 rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
1521 #ifdef TARGET_REGNAMES
1522 /* If the user desires alternate register names, copy in the
1523 alternate names now. */
1524 if (TARGET_REGNAMES)
1525 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
1526 #endif
1528 /* Set aix_struct_return last, after the ABI is determined.
1529 If -maix-struct-return or -msvr4-struct-return was explicitly
1530 used, don't override with the ABI default. */
1531 if (!rs6000_explicit_options.aix_struct_ret)
1532 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
1534 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
1535 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
1537 if (TARGET_TOC)
1538 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
1540 /* We can only guarantee the availability of DI pseudo-ops when
1541 assembling for 64-bit targets. */
1542 if (!TARGET_64BIT)
1544 targetm.asm_out.aligned_op.di = NULL;
1545 targetm.asm_out.unaligned_op.di = NULL;
1548 /* Set branch target alignment, if not optimizing for size. */
1549 if (!optimize_size)
1551 /* Cell wants to be aligned 8byte for dual issue. */
1552 if (rs6000_cpu == PROCESSOR_CELL)
1554 if (align_functions <= 0)
1555 align_functions = 8;
1556 if (align_jumps <= 0)
1557 align_jumps = 8;
1558 if (align_loops <= 0)
1559 align_loops = 8;
1561 if (rs6000_align_branch_targets)
1563 if (align_functions <= 0)
1564 align_functions = 16;
1565 if (align_jumps <= 0)
1566 align_jumps = 16;
1567 if (align_loops <= 0)
1568 align_loops = 16;
1570 if (align_jumps_max_skip <= 0)
1571 align_jumps_max_skip = 15;
1572 if (align_loops_max_skip <= 0)
1573 align_loops_max_skip = 15;
1576 /* Arrange to save and restore machine status around nested functions. */
1577 init_machine_status = rs6000_init_machine_status;
1579 /* We should always be splitting complex arguments, but we can't break
1580 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1581 if (DEFAULT_ABI != ABI_AIX)
1582 targetm.calls.split_complex_arg = NULL;
1584 /* Initialize rs6000_cost with the appropriate target costs. */
1585 if (optimize_size)
1586 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
1587 else
1588 switch (rs6000_cpu)
1590 case PROCESSOR_RIOS1:
1591 rs6000_cost = &rios1_cost;
1592 break;
1594 case PROCESSOR_RIOS2:
1595 rs6000_cost = &rios2_cost;
1596 break;
1598 case PROCESSOR_RS64A:
1599 rs6000_cost = &rs64a_cost;
1600 break;
1602 case PROCESSOR_MPCCORE:
1603 rs6000_cost = &mpccore_cost;
1604 break;
1606 case PROCESSOR_PPC403:
1607 rs6000_cost = &ppc403_cost;
1608 break;
1610 case PROCESSOR_PPC405:
1611 rs6000_cost = &ppc405_cost;
1612 break;
1614 case PROCESSOR_PPC440:
1615 rs6000_cost = &ppc440_cost;
1616 break;
1618 case PROCESSOR_PPC601:
1619 rs6000_cost = &ppc601_cost;
1620 break;
1622 case PROCESSOR_PPC603:
1623 rs6000_cost = &ppc603_cost;
1624 break;
1626 case PROCESSOR_PPC604:
1627 rs6000_cost = &ppc604_cost;
1628 break;
1630 case PROCESSOR_PPC604e:
1631 rs6000_cost = &ppc604e_cost;
1632 break;
1634 case PROCESSOR_PPC620:
1635 rs6000_cost = &ppc620_cost;
1636 break;
1638 case PROCESSOR_PPC630:
1639 rs6000_cost = &ppc630_cost;
1640 break;
1642 case PROCESSOR_CELL:
1643 rs6000_cost = &ppccell_cost;
1644 break;
1646 case PROCESSOR_PPC750:
1647 case PROCESSOR_PPC7400:
1648 rs6000_cost = &ppc750_cost;
1649 break;
1651 case PROCESSOR_PPC7450:
1652 rs6000_cost = &ppc7450_cost;
1653 break;
1655 case PROCESSOR_PPC8540:
1656 rs6000_cost = &ppc8540_cost;
1657 break;
1659 case PROCESSOR_POWER4:
1660 case PROCESSOR_POWER5:
1661 rs6000_cost = &power4_cost;
1662 break;
1664 case PROCESSOR_POWER6:
1665 rs6000_cost = &power6_cost;
1666 break;
1668 default:
1669 gcc_unreachable ();
1673 /* Implement targetm.vectorize.builtin_mask_for_load. */
1674 static tree
1675 rs6000_builtin_mask_for_load (void)
1677 if (TARGET_ALTIVEC)
1678 return altivec_builtin_mask_for_load;
1679 else
1680 return 0;
1683 /* Implement targetm.vectorize.builtin_mul_widen_even. */
1684 static tree
1685 rs6000_builtin_mul_widen_even (tree type)
1687 if (!TARGET_ALTIVEC)
1688 return NULL_TREE;
1690 switch (TYPE_MODE (type))
1692 case V8HImode:
1693 return TYPE_UNSIGNED (type) ?
1694 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH] :
1695 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
1697 case V16QImode:
1698 return TYPE_UNSIGNED (type) ?
1699 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB] :
1700 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
1701 default:
1702 return NULL_TREE;
1706 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
1707 static tree
1708 rs6000_builtin_mul_widen_odd (tree type)
1710 if (!TARGET_ALTIVEC)
1711 return NULL_TREE;
1713 switch (TYPE_MODE (type))
1715 case V8HImode:
1716 return TYPE_UNSIGNED (type) ?
1717 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH] :
1718 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
1720 case V16QImode:
1721 return TYPE_UNSIGNED (type) ?
1722 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB] :
1723 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
1724 default:
1725 return NULL_TREE;
1729 /* Handle generic options of the form -mfoo=yes/no.
1730 NAME is the option name.
1731 VALUE is the option value.
1732 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1733 whether the option value is 'yes' or 'no' respectively. */
1734 static void
1735 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
1737 if (value == 0)
1738 return;
1739 else if (!strcmp (value, "yes"))
1740 *flag = 1;
1741 else if (!strcmp (value, "no"))
1742 *flag = 0;
1743 else
1744 error ("unknown -m%s= option specified: '%s'", name, value);
1747 /* Validate and record the size specified with the -mtls-size option. */
1749 static void
1750 rs6000_parse_tls_size_option (void)
1752 if (rs6000_tls_size_string == 0)
1753 return;
1754 else if (strcmp (rs6000_tls_size_string, "16") == 0)
1755 rs6000_tls_size = 16;
1756 else if (strcmp (rs6000_tls_size_string, "32") == 0)
1757 rs6000_tls_size = 32;
1758 else if (strcmp (rs6000_tls_size_string, "64") == 0)
1759 rs6000_tls_size = 64;
1760 else
1761 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
1764 void
1765 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1767 if (DEFAULT_ABI == ABI_DARWIN)
1768 /* The Darwin libraries never set errno, so we might as well
1769 avoid calling them when that's the only reason we would. */
1770 flag_errno_math = 0;
1772 /* Double growth factor to counter reduced min jump length. */
1773 set_param_value ("max-grow-copy-bb-insns", 16);
1775 /* Enable section anchors by default.
1776 Skip section anchors for Objective C and Objective C++
1777 until front-ends fixed. */
1778 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
1779 flag_section_anchors = 1;
1782 /* Implement TARGET_HANDLE_OPTION. */
1784 static bool
1785 rs6000_handle_option (size_t code, const char *arg, int value)
1787 switch (code)
1789 case OPT_mno_power:
1790 target_flags &= ~(MASK_POWER | MASK_POWER2
1791 | MASK_MULTIPLE | MASK_STRING);
1792 target_flags_explicit |= (MASK_POWER | MASK_POWER2
1793 | MASK_MULTIPLE | MASK_STRING);
1794 break;
1795 case OPT_mno_powerpc:
1796 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
1797 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1798 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
1799 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1800 break;
1801 case OPT_mfull_toc:
1802 target_flags &= ~MASK_MINIMAL_TOC;
1803 TARGET_NO_FP_IN_TOC = 0;
1804 TARGET_NO_SUM_IN_TOC = 0;
1805 target_flags_explicit |= MASK_MINIMAL_TOC;
1806 #ifdef TARGET_USES_SYSV4_OPT
1807 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1808 just the same as -mminimal-toc. */
1809 target_flags |= MASK_MINIMAL_TOC;
1810 target_flags_explicit |= MASK_MINIMAL_TOC;
1811 #endif
1812 break;
1814 #ifdef TARGET_USES_SYSV4_OPT
1815 case OPT_mtoc:
1816 /* Make -mtoc behave like -mminimal-toc. */
1817 target_flags |= MASK_MINIMAL_TOC;
1818 target_flags_explicit |= MASK_MINIMAL_TOC;
1819 break;
1820 #endif
1822 #ifdef TARGET_USES_AIX64_OPT
1823 case OPT_maix64:
1824 #else
1825 case OPT_m64:
1826 #endif
1827 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
1828 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
1829 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
1830 break;
1832 #ifdef TARGET_USES_AIX64_OPT
1833 case OPT_maix32:
1834 #else
1835 case OPT_m32:
1836 #endif
1837 target_flags &= ~MASK_POWERPC64;
1838 target_flags_explicit |= MASK_POWERPC64;
1839 break;
1841 case OPT_minsert_sched_nops_:
1842 rs6000_sched_insert_nops_str = arg;
1843 break;
1845 case OPT_mminimal_toc:
1846 if (value == 1)
1848 TARGET_NO_FP_IN_TOC = 0;
1849 TARGET_NO_SUM_IN_TOC = 0;
1851 break;
1853 case OPT_mpower:
1854 if (value == 1)
1856 target_flags |= (MASK_MULTIPLE | MASK_STRING);
1857 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
1859 break;
1861 case OPT_mpower2:
1862 if (value == 1)
1864 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1865 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1867 break;
1869 case OPT_mpowerpc_gpopt:
1870 case OPT_mpowerpc_gfxopt:
1871 if (value == 1)
1873 target_flags |= MASK_POWERPC;
1874 target_flags_explicit |= MASK_POWERPC;
1876 break;
1878 case OPT_maix_struct_return:
1879 case OPT_msvr4_struct_return:
1880 rs6000_explicit_options.aix_struct_ret = true;
1881 break;
1883 case OPT_mvrsave_:
1884 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
1885 break;
1887 case OPT_misel_:
1888 rs6000_explicit_options.isel = true;
1889 rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
1890 break;
1892 case OPT_mspe_:
1893 rs6000_explicit_options.spe = true;
1894 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
1895 /* No SPE means 64-bit long doubles, even if an E500. */
1896 if (!rs6000_spe)
1897 rs6000_long_double_type_size = 64;
1898 break;
1900 case OPT_mdebug_:
1901 rs6000_debug_name = arg;
1902 break;
1904 #ifdef TARGET_USES_SYSV4_OPT
1905 case OPT_mcall_:
1906 rs6000_abi_name = arg;
1907 break;
1909 case OPT_msdata_:
1910 rs6000_sdata_name = arg;
1911 break;
1913 case OPT_mtls_size_:
1914 rs6000_tls_size_string = arg;
1915 break;
1917 case OPT_mrelocatable:
1918 if (value == 1)
1920 target_flags |= MASK_MINIMAL_TOC;
1921 target_flags_explicit |= MASK_MINIMAL_TOC;
1922 TARGET_NO_FP_IN_TOC = 1;
1924 break;
1926 case OPT_mrelocatable_lib:
1927 if (value == 1)
1929 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
1930 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
1931 TARGET_NO_FP_IN_TOC = 1;
1933 else
1935 target_flags &= ~MASK_RELOCATABLE;
1936 target_flags_explicit |= MASK_RELOCATABLE;
1938 break;
1939 #endif
1941 case OPT_mabi_:
1942 if (!strcmp (arg, "altivec"))
1944 rs6000_explicit_options.abi = true;
1945 rs6000_altivec_abi = 1;
1946 rs6000_spe_abi = 0;
1948 else if (! strcmp (arg, "no-altivec"))
1950 /* ??? Don't set rs6000_explicit_options.abi here, to allow
1951 the default for rs6000_spe_abi to be chosen later. */
1952 rs6000_altivec_abi = 0;
1954 else if (! strcmp (arg, "spe"))
1956 rs6000_explicit_options.abi = true;
1957 rs6000_spe_abi = 1;
1958 rs6000_altivec_abi = 0;
1959 if (!TARGET_SPE_ABI)
1960 error ("not configured for ABI: '%s'", arg);
1962 else if (! strcmp (arg, "no-spe"))
1964 rs6000_explicit_options.abi = true;
1965 rs6000_spe_abi = 0;
1968 /* These are here for testing during development only, do not
1969 document in the manual please. */
1970 else if (! strcmp (arg, "d64"))
1972 rs6000_darwin64_abi = 1;
1973 warning (0, "Using darwin64 ABI");
1975 else if (! strcmp (arg, "d32"))
1977 rs6000_darwin64_abi = 0;
1978 warning (0, "Using old darwin ABI");
1981 else if (! strcmp (arg, "ibmlongdouble"))
1983 rs6000_explicit_options.ieee = true;
1984 rs6000_ieeequad = 0;
1985 warning (0, "Using IBM extended precision long double");
1987 else if (! strcmp (arg, "ieeelongdouble"))
1989 rs6000_explicit_options.ieee = true;
1990 rs6000_ieeequad = 1;
1991 warning (0, "Using IEEE extended precision long double");
1994 else
1996 error ("unknown ABI specified: '%s'", arg);
1997 return false;
1999 break;
2001 case OPT_mcpu_:
2002 rs6000_select[1].string = arg;
2003 break;
2005 case OPT_mtune_:
2006 rs6000_select[2].string = arg;
2007 break;
2009 case OPT_mtraceback_:
2010 rs6000_traceback_name = arg;
2011 break;
2013 case OPT_mfloat_gprs_:
2014 rs6000_explicit_options.float_gprs = true;
2015 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
2016 rs6000_float_gprs = 1;
2017 else if (! strcmp (arg, "double"))
2018 rs6000_float_gprs = 2;
2019 else if (! strcmp (arg, "no"))
2020 rs6000_float_gprs = 0;
2021 else
2023 error ("invalid option for -mfloat-gprs: '%s'", arg);
2024 return false;
2026 break;
2028 case OPT_mlong_double_:
2029 rs6000_explicit_options.long_double = true;
2030 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2031 if (value != 64 && value != 128)
2033 error ("Unknown switch -mlong-double-%s", arg);
2034 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2035 return false;
2037 else
2038 rs6000_long_double_type_size = value;
2039 break;
2041 case OPT_msched_costly_dep_:
2042 rs6000_sched_costly_dep_str = arg;
2043 break;
2045 case OPT_malign_:
2046 rs6000_explicit_options.alignment = true;
2047 if (! strcmp (arg, "power"))
2049 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2050 some C library functions, so warn about it. The flag may be
2051 useful for performance studies from time to time though, so
2052 don't disable it entirely. */
2053 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2054 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2055 " it is incompatible with the installed C and C++ libraries");
2056 rs6000_alignment_flags = MASK_ALIGN_POWER;
2058 else if (! strcmp (arg, "natural"))
2059 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2060 else
2062 error ("unknown -malign-XXXXX option specified: '%s'", arg);
2063 return false;
2065 break;
2067 return true;
2070 /* Do anything needed at the start of the asm file. */
2072 static void
2073 rs6000_file_start (void)
2075 size_t i;
2076 char buffer[80];
2077 const char *start = buffer;
2078 struct rs6000_cpu_select *ptr;
2079 const char *default_cpu = TARGET_CPU_DEFAULT;
2080 FILE *file = asm_out_file;
2082 default_file_start ();
2084 #ifdef TARGET_BI_ARCH
2085 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
2086 default_cpu = 0;
2087 #endif
2089 if (flag_verbose_asm)
2091 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
2092 rs6000_select[0].string = default_cpu;
2094 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2096 ptr = &rs6000_select[i];
2097 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2099 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
2100 start = "";
2104 if (PPC405_ERRATUM77)
2106 fprintf (file, "%s PPC405CR_ERRATUM77", start);
2107 start = "";
2110 #ifdef USING_ELFOS_H
2111 switch (rs6000_sdata)
2113 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
2114 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
2115 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
2116 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
2119 if (rs6000_sdata && g_switch_value)
2121 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
2122 g_switch_value);
2123 start = "";
2125 #endif
2127 if (*start == '\0')
2128 putc ('\n', file);
2131 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
2133 switch_to_section (toc_section);
2134 switch_to_section (text_section);
2139 /* Return nonzero if this function is known to have a null epilogue. */
2142 direct_return (void)
2144 if (reload_completed)
2146 rs6000_stack_t *info = rs6000_stack_info ();
2148 if (info->first_gp_reg_save == 32
2149 && info->first_fp_reg_save == 64
2150 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
2151 && ! info->lr_save_p
2152 && ! info->cr_save_p
2153 && info->vrsave_mask == 0
2154 && ! info->push_p)
2155 return 1;
2158 return 0;
2161 /* Return the number of instructions it takes to form a constant in an
2162 integer register. */
2165 num_insns_constant_wide (HOST_WIDE_INT value)
2167 /* signed constant loadable with {cal|addi} */
2168 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
2169 return 1;
2171 /* constant loadable with {cau|addis} */
2172 else if ((value & 0xffff) == 0
2173 && (value >> 31 == -1 || value >> 31 == 0))
2174 return 1;
2176 #if HOST_BITS_PER_WIDE_INT == 64
2177 else if (TARGET_POWERPC64)
2179 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
2180 HOST_WIDE_INT high = value >> 31;
2182 if (high == 0 || high == -1)
2183 return 2;
2185 high >>= 1;
2187 if (low == 0)
2188 return num_insns_constant_wide (high) + 1;
2189 else
2190 return (num_insns_constant_wide (high)
2191 + num_insns_constant_wide (low) + 1);
2193 #endif
2195 else
2196 return 2;
2200 num_insns_constant (rtx op, enum machine_mode mode)
2202 HOST_WIDE_INT low, high;
2204 switch (GET_CODE (op))
2206 case CONST_INT:
2207 #if HOST_BITS_PER_WIDE_INT == 64
2208 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
2209 && mask64_operand (op, mode))
2210 return 2;
2211 else
2212 #endif
2213 return num_insns_constant_wide (INTVAL (op));
2215 case CONST_DOUBLE:
2216 if (mode == SFmode)
2218 long l;
2219 REAL_VALUE_TYPE rv;
2221 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2222 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
2223 return num_insns_constant_wide ((HOST_WIDE_INT) l);
2226 if (mode == VOIDmode || mode == DImode)
2228 high = CONST_DOUBLE_HIGH (op);
2229 low = CONST_DOUBLE_LOW (op);
2231 else
2233 long l[2];
2234 REAL_VALUE_TYPE rv;
2236 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2237 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
2238 high = l[WORDS_BIG_ENDIAN == 0];
2239 low = l[WORDS_BIG_ENDIAN != 0];
2242 if (TARGET_32BIT)
2243 return (num_insns_constant_wide (low)
2244 + num_insns_constant_wide (high));
2245 else
2247 if ((high == 0 && low >= 0)
2248 || (high == -1 && low < 0))
2249 return num_insns_constant_wide (low);
2251 else if (mask64_operand (op, mode))
2252 return 2;
2254 else if (low == 0)
2255 return num_insns_constant_wide (high) + 1;
2257 else
2258 return (num_insns_constant_wide (high)
2259 + num_insns_constant_wide (low) + 1);
2262 default:
2263 gcc_unreachable ();
2267 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2268 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2269 corresponding element of the vector, but for V4SFmode and V2SFmode,
2270 the corresponding "float" is interpreted as an SImode integer. */
2272 static HOST_WIDE_INT
2273 const_vector_elt_as_int (rtx op, unsigned int elt)
2275 rtx tmp = CONST_VECTOR_ELT (op, elt);
2276 if (GET_MODE (op) == V4SFmode
2277 || GET_MODE (op) == V2SFmode)
2278 tmp = gen_lowpart (SImode, tmp);
2279 return INTVAL (tmp);
2282 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2283 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2284 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2285 all items are set to the same value and contain COPIES replicas of the
2286 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2287 operand and the others are set to the value of the operand's msb. */
2289 static bool
2290 vspltis_constant (rtx op, unsigned step, unsigned copies)
2292 enum machine_mode mode = GET_MODE (op);
2293 enum machine_mode inner = GET_MODE_INNER (mode);
2295 unsigned i;
2296 unsigned nunits = GET_MODE_NUNITS (mode);
2297 unsigned bitsize = GET_MODE_BITSIZE (inner);
2298 unsigned mask = GET_MODE_MASK (inner);
2300 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
2301 HOST_WIDE_INT splat_val = val;
2302 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
2304 /* Construct the value to be splatted, if possible. If not, return 0. */
2305 for (i = 2; i <= copies; i *= 2)
2307 HOST_WIDE_INT small_val;
2308 bitsize /= 2;
2309 small_val = splat_val >> bitsize;
2310 mask >>= bitsize;
2311 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
2312 return false;
2313 splat_val = small_val;
2316 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2317 if (EASY_VECTOR_15 (splat_val))
2320 /* Also check if we can splat, and then add the result to itself. Do so if
2321 the value is positive, of if the splat instruction is using OP's mode;
2322 for splat_val < 0, the splat and the add should use the same mode. */
2323 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
2324 && (splat_val >= 0 || (step == 1 && copies == 1)))
2327 else
2328 return false;
2330 /* Check if VAL is present in every STEP-th element, and the
2331 other elements are filled with its most significant bit. */
2332 for (i = 0; i < nunits - 1; ++i)
2334 HOST_WIDE_INT desired_val;
2335 if (((i + 1) & (step - 1)) == 0)
2336 desired_val = val;
2337 else
2338 desired_val = msb_val;
2340 if (desired_val != const_vector_elt_as_int (op, i))
2341 return false;
2344 return true;
2348 /* Return true if OP is of the given MODE and can be synthesized
2349 with a vspltisb, vspltish or vspltisw. */
2351 bool
2352 easy_altivec_constant (rtx op, enum machine_mode mode)
2354 unsigned step, copies;
2356 if (mode == VOIDmode)
2357 mode = GET_MODE (op);
2358 else if (mode != GET_MODE (op))
2359 return false;
2361 /* Start with a vspltisw. */
2362 step = GET_MODE_NUNITS (mode) / 4;
2363 copies = 1;
2365 if (vspltis_constant (op, step, copies))
2366 return true;
2368 /* Then try with a vspltish. */
2369 if (step == 1)
2370 copies <<= 1;
2371 else
2372 step >>= 1;
2374 if (vspltis_constant (op, step, copies))
2375 return true;
2377 /* And finally a vspltisb. */
2378 if (step == 1)
2379 copies <<= 1;
2380 else
2381 step >>= 1;
2383 if (vspltis_constant (op, step, copies))
2384 return true;
2386 return false;
2389 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2390 result is OP. Abort if it is not possible. */
2393 gen_easy_altivec_constant (rtx op)
2395 enum machine_mode mode = GET_MODE (op);
2396 int nunits = GET_MODE_NUNITS (mode);
2397 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
2398 unsigned step = nunits / 4;
2399 unsigned copies = 1;
2401 /* Start with a vspltisw. */
2402 if (vspltis_constant (op, step, copies))
2403 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
2405 /* Then try with a vspltish. */
2406 if (step == 1)
2407 copies <<= 1;
2408 else
2409 step >>= 1;
2411 if (vspltis_constant (op, step, copies))
2412 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
2414 /* And finally a vspltisb. */
2415 if (step == 1)
2416 copies <<= 1;
2417 else
2418 step >>= 1;
2420 if (vspltis_constant (op, step, copies))
2421 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
2423 gcc_unreachable ();
2426 const char *
2427 output_vec_const_move (rtx *operands)
2429 int cst, cst2;
2430 enum machine_mode mode;
2431 rtx dest, vec;
2433 dest = operands[0];
2434 vec = operands[1];
2435 mode = GET_MODE (dest);
2437 if (TARGET_ALTIVEC)
2439 rtx splat_vec;
2440 if (zero_constant (vec, mode))
2441 return "vxor %0,%0,%0";
2443 splat_vec = gen_easy_altivec_constant (vec);
2444 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
2445 operands[1] = XEXP (splat_vec, 0);
2446 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
2447 return "#";
2449 switch (GET_MODE (splat_vec))
2451 case V4SImode:
2452 return "vspltisw %0,%1";
2454 case V8HImode:
2455 return "vspltish %0,%1";
2457 case V16QImode:
2458 return "vspltisb %0,%1";
2460 default:
2461 gcc_unreachable ();
2465 gcc_assert (TARGET_SPE);
2467 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2468 pattern of V1DI, V4HI, and V2SF.
2470 FIXME: We should probably return # and add post reload
2471 splitters for these, but this way is so easy ;-). */
2472 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
2473 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
2474 operands[1] = CONST_VECTOR_ELT (vec, 0);
2475 operands[2] = CONST_VECTOR_ELT (vec, 1);
2476 if (cst == cst2)
2477 return "li %0,%1\n\tevmergelo %0,%0,%0";
2478 else
2479 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2482 /* Initialize vector TARGET to VALS. */
2484 void
2485 rs6000_expand_vector_init (rtx target, rtx vals)
2487 enum machine_mode mode = GET_MODE (target);
2488 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2489 int n_elts = GET_MODE_NUNITS (mode);
2490 int n_var = 0, one_var = -1;
2491 bool all_same = true, all_const_zero = true;
2492 rtx x, mem;
2493 int i;
2495 for (i = 0; i < n_elts; ++i)
2497 x = XVECEXP (vals, 0, i);
2498 if (!CONSTANT_P (x))
2499 ++n_var, one_var = i;
2500 else if (x != CONST0_RTX (inner_mode))
2501 all_const_zero = false;
2503 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
2504 all_same = false;
2507 if (n_var == 0)
2509 if (mode != V4SFmode && all_const_zero)
2511 /* Zero register. */
2512 emit_insn (gen_rtx_SET (VOIDmode, target,
2513 gen_rtx_XOR (mode, target, target)));
2514 return;
2516 else if (mode != V4SFmode && easy_vector_constant (vals, mode))
2518 /* Splat immediate. */
2519 emit_insn (gen_rtx_SET (VOIDmode, target, vals));
2520 return;
2522 else if (all_same)
2523 ; /* Splat vector element. */
2524 else
2526 /* Load from constant pool. */
2527 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
2528 return;
2532 /* Store value to stack temp. Load vector element. Splat. */
2533 if (all_same)
2535 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2536 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
2537 XVECEXP (vals, 0, 0));
2538 x = gen_rtx_UNSPEC (VOIDmode,
2539 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2540 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2541 gen_rtvec (2,
2542 gen_rtx_SET (VOIDmode,
2543 target, mem),
2544 x)));
2545 x = gen_rtx_VEC_SELECT (inner_mode, target,
2546 gen_rtx_PARALLEL (VOIDmode,
2547 gen_rtvec (1, const0_rtx)));
2548 emit_insn (gen_rtx_SET (VOIDmode, target,
2549 gen_rtx_VEC_DUPLICATE (mode, x)));
2550 return;
2553 /* One field is non-constant. Load constant then overwrite
2554 varying field. */
2555 if (n_var == 1)
2557 rtx copy = copy_rtx (vals);
2559 /* Load constant part of vector, substitute neighboring value for
2560 varying element. */
2561 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
2562 rs6000_expand_vector_init (target, copy);
2564 /* Insert variable. */
2565 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
2566 return;
2569 /* Construct the vector in memory one field at a time
2570 and load the whole vector. */
2571 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2572 for (i = 0; i < n_elts; i++)
2573 emit_move_insn (adjust_address_nv (mem, inner_mode,
2574 i * GET_MODE_SIZE (inner_mode)),
2575 XVECEXP (vals, 0, i));
2576 emit_move_insn (target, mem);
2579 /* Set field ELT of TARGET to VAL. */
2581 void
2582 rs6000_expand_vector_set (rtx target, rtx val, int elt)
2584 enum machine_mode mode = GET_MODE (target);
2585 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2586 rtx reg = gen_reg_rtx (mode);
2587 rtx mask, mem, x;
2588 int width = GET_MODE_SIZE (inner_mode);
2589 int i;
2591 /* Load single variable value. */
2592 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2593 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
2594 x = gen_rtx_UNSPEC (VOIDmode,
2595 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2596 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2597 gen_rtvec (2,
2598 gen_rtx_SET (VOIDmode,
2599 reg, mem),
2600 x)));
2602 /* Linear sequence. */
2603 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
2604 for (i = 0; i < 16; ++i)
2605 XVECEXP (mask, 0, i) = GEN_INT (i);
2607 /* Set permute mask to insert element into target. */
2608 for (i = 0; i < width; ++i)
2609 XVECEXP (mask, 0, elt*width + i)
2610 = GEN_INT (i + 0x10);
2611 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
2612 x = gen_rtx_UNSPEC (mode,
2613 gen_rtvec (3, target, reg,
2614 force_reg (V16QImode, x)),
2615 UNSPEC_VPERM);
2616 emit_insn (gen_rtx_SET (VOIDmode, target, x));
2619 /* Extract field ELT from VEC into TARGET. */
2621 void
2622 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
2624 enum machine_mode mode = GET_MODE (vec);
2625 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2626 rtx mem, x;
2628 /* Allocate mode-sized buffer. */
2629 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2631 /* Add offset to field within buffer matching vector element. */
2632 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
2634 /* Store single field into mode-sized buffer. */
2635 x = gen_rtx_UNSPEC (VOIDmode,
2636 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
2637 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2638 gen_rtvec (2,
2639 gen_rtx_SET (VOIDmode,
2640 mem, vec),
2641 x)));
2642 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
2645 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2646 implement ANDing by the mask IN. */
2647 void
2648 build_mask64_2_operands (rtx in, rtx *out)
2650 #if HOST_BITS_PER_WIDE_INT >= 64
2651 unsigned HOST_WIDE_INT c, lsb, m1, m2;
2652 int shift;
2654 gcc_assert (GET_CODE (in) == CONST_INT);
2656 c = INTVAL (in);
2657 if (c & 1)
2659 /* Assume c initially something like 0x00fff000000fffff. The idea
2660 is to rotate the word so that the middle ^^^^^^ group of zeros
2661 is at the MS end and can be cleared with an rldicl mask. We then
2662 rotate back and clear off the MS ^^ group of zeros with a
2663 second rldicl. */
2664 c = ~c; /* c == 0xff000ffffff00000 */
2665 lsb = c & -c; /* lsb == 0x0000000000100000 */
2666 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
2667 c = ~c; /* c == 0x00fff000000fffff */
2668 c &= -lsb; /* c == 0x00fff00000000000 */
2669 lsb = c & -c; /* lsb == 0x0000100000000000 */
2670 c = ~c; /* c == 0xff000fffffffffff */
2671 c &= -lsb; /* c == 0xff00000000000000 */
2672 shift = 0;
2673 while ((lsb >>= 1) != 0)
2674 shift++; /* shift == 44 on exit from loop */
2675 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
2676 m1 = ~m1; /* m1 == 0x000000ffffffffff */
2677 m2 = ~c; /* m2 == 0x00ffffffffffffff */
2679 else
2681 /* Assume c initially something like 0xff000f0000000000. The idea
2682 is to rotate the word so that the ^^^ middle group of zeros
2683 is at the LS end and can be cleared with an rldicr mask. We then
2684 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2685 a second rldicr. */
2686 lsb = c & -c; /* lsb == 0x0000010000000000 */
2687 m2 = -lsb; /* m2 == 0xffffff0000000000 */
2688 c = ~c; /* c == 0x00fff0ffffffffff */
2689 c &= -lsb; /* c == 0x00fff00000000000 */
2690 lsb = c & -c; /* lsb == 0x0000100000000000 */
2691 c = ~c; /* c == 0xff000fffffffffff */
2692 c &= -lsb; /* c == 0xff00000000000000 */
2693 shift = 0;
2694 while ((lsb >>= 1) != 0)
2695 shift++; /* shift == 44 on exit from loop */
2696 m1 = ~c; /* m1 == 0x00ffffffffffffff */
2697 m1 >>= shift; /* m1 == 0x0000000000000fff */
2698 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
2701 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2702 masks will be all 1's. We are guaranteed more than one transition. */
2703 out[0] = GEN_INT (64 - shift);
2704 out[1] = GEN_INT (m1);
2705 out[2] = GEN_INT (shift);
2706 out[3] = GEN_INT (m2);
2707 #else
2708 (void)in;
2709 (void)out;
2710 gcc_unreachable ();
2711 #endif
2714 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2716 bool
2717 invalid_e500_subreg (rtx op, enum machine_mode mode)
2719 if (TARGET_E500_DOUBLE)
2721 /* Reject (subreg:SI (reg:DF)). */
2722 if (GET_CODE (op) == SUBREG
2723 && mode == SImode
2724 && REG_P (SUBREG_REG (op))
2725 && GET_MODE (SUBREG_REG (op)) == DFmode)
2726 return true;
2728 /* Reject (subreg:DF (reg:DI)). */
2729 if (GET_CODE (op) == SUBREG
2730 && mode == DFmode
2731 && REG_P (SUBREG_REG (op))
2732 && GET_MODE (SUBREG_REG (op)) == DImode)
2733 return true;
2736 if (TARGET_SPE
2737 && GET_CODE (op) == SUBREG
2738 && mode == SImode
2739 && REG_P (SUBREG_REG (op))
2740 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
2741 return true;
2743 return false;
2746 /* AIX increases natural record alignment to doubleword if the first
2747 field is an FP double while the FP fields remain word aligned. */
2749 unsigned int
2750 rs6000_special_round_type_align (tree type, unsigned int computed,
2751 unsigned int specified)
2753 unsigned int align = MAX (computed, specified);
2754 tree field = TYPE_FIELDS (type);
2756 /* Skip all non field decls */
2757 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
2758 field = TREE_CHAIN (field);
2760 if (field != NULL && field != type)
2762 type = TREE_TYPE (field);
2763 while (TREE_CODE (type) == ARRAY_TYPE)
2764 type = TREE_TYPE (type);
2766 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
2767 align = MAX (align, 64);
2770 return align;
2773 /* Darwin increases record alignment to the natural alignment of
2774 the first field. */
2776 unsigned int
2777 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
2778 unsigned int specified)
2780 unsigned int align = MAX (computed, specified);
2782 if (TYPE_PACKED (type))
2783 return align;
2785 /* Find the first field, looking down into aggregates. */
2786 do {
2787 tree field = TYPE_FIELDS (type);
2788 /* Skip all non field decls */
2789 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
2790 field = TREE_CHAIN (field);
2791 if (! field)
2792 break;
2793 type = TREE_TYPE (field);
2794 while (TREE_CODE (type) == ARRAY_TYPE)
2795 type = TREE_TYPE (type);
2796 } while (AGGREGATE_TYPE_P (type));
2798 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
2799 align = MAX (align, TYPE_ALIGN (type));
2801 return align;
2804 /* Return 1 for an operand in small memory on V.4/eabi. */
2807 small_data_operand (rtx op ATTRIBUTE_UNUSED,
2808 enum machine_mode mode ATTRIBUTE_UNUSED)
2810 #if TARGET_ELF
2811 rtx sym_ref;
2813 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
2814 return 0;
2816 if (DEFAULT_ABI != ABI_V4)
2817 return 0;
2819 if (GET_CODE (op) == SYMBOL_REF)
2820 sym_ref = op;
2822 else if (GET_CODE (op) != CONST
2823 || GET_CODE (XEXP (op, 0)) != PLUS
2824 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2825 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
2826 return 0;
2828 else
2830 rtx sum = XEXP (op, 0);
2831 HOST_WIDE_INT summand;
2833 /* We have to be careful here, because it is the referenced address
2834 that must be 32k from _SDA_BASE_, not just the symbol. */
2835 summand = INTVAL (XEXP (sum, 1));
2836 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
2837 return 0;
2839 sym_ref = XEXP (sum, 0);
2842 return SYMBOL_REF_SMALL_P (sym_ref);
2843 #else
2844 return 0;
2845 #endif
2848 /* Return true if either operand is a general purpose register. */
2850 bool
2851 gpr_or_gpr_p (rtx op0, rtx op1)
2853 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
2854 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
2858 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2860 static int
2861 constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
2863 switch (GET_CODE (op))
2865 case SYMBOL_REF:
2866 if (RS6000_SYMBOL_REF_TLS_P (op))
2867 return 0;
2868 else if (CONSTANT_POOL_ADDRESS_P (op))
2870 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2872 *have_sym = 1;
2873 return 1;
2875 else
2876 return 0;
2878 else if (! strcmp (XSTR (op, 0), toc_label_name))
2880 *have_toc = 1;
2881 return 1;
2883 else
2884 return 0;
2885 case PLUS:
2886 case MINUS:
2887 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2888 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
2889 case CONST:
2890 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
2891 case CONST_INT:
2892 return 1;
2893 default:
2894 return 0;
2898 static bool
2899 constant_pool_expr_p (rtx op)
2901 int have_sym = 0;
2902 int have_toc = 0;
2903 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2906 bool
2907 toc_relative_expr_p (rtx op)
2909 int have_sym = 0;
2910 int have_toc = 0;
2911 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2914 bool
2915 legitimate_constant_pool_address_p (rtx x)
2917 return (TARGET_TOC
2918 && GET_CODE (x) == PLUS
2919 && GET_CODE (XEXP (x, 0)) == REG
2920 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
2921 && constant_pool_expr_p (XEXP (x, 1)));
2924 static bool
2925 legitimate_small_data_p (enum machine_mode mode, rtx x)
2927 return (DEFAULT_ABI == ABI_V4
2928 && !flag_pic && !TARGET_TOC
2929 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
2930 && small_data_operand (x, mode));
2933 /* SPE offset addressing is limited to 5-bits worth of double words. */
2934 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2936 bool
2937 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
2939 unsigned HOST_WIDE_INT offset, extra;
2941 if (GET_CODE (x) != PLUS)
2942 return false;
2943 if (GET_CODE (XEXP (x, 0)) != REG)
2944 return false;
2945 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2946 return false;
2947 if (legitimate_constant_pool_address_p (x))
2948 return true;
2949 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2950 return false;
2952 offset = INTVAL (XEXP (x, 1));
2953 extra = 0;
2954 switch (mode)
2956 case V16QImode:
2957 case V8HImode:
2958 case V4SFmode:
2959 case V4SImode:
2960 /* AltiVec vector modes. Only reg+reg addressing is valid and
2961 constant offset zero should not occur due to canonicalization.
2962 Allow any offset when not strict before reload. */
2963 return !strict;
2965 case V4HImode:
2966 case V2SImode:
2967 case V1DImode:
2968 case V2SFmode:
2969 /* SPE vector modes. */
2970 return SPE_CONST_OFFSET_OK (offset);
2972 case DFmode:
2973 if (TARGET_E500_DOUBLE)
2974 return SPE_CONST_OFFSET_OK (offset);
2976 case DImode:
2977 /* On e500v2, we may have:
2979 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
2981 Which gets addressed with evldd instructions. */
2982 if (TARGET_E500_DOUBLE)
2983 return SPE_CONST_OFFSET_OK (offset);
2985 if (mode == DFmode || !TARGET_POWERPC64)
2986 extra = 4;
2987 else if (offset & 3)
2988 return false;
2989 break;
2991 case TFmode:
2992 case TImode:
2993 if (mode == TFmode || !TARGET_POWERPC64)
2994 extra = 12;
2995 else if (offset & 3)
2996 return false;
2997 else
2998 extra = 8;
2999 break;
3001 default:
3002 break;
3005 offset += 0x8000;
3006 return (offset < 0x10000) && (offset + extra < 0x10000);
3009 static bool
3010 legitimate_indexed_address_p (rtx x, int strict)
3012 rtx op0, op1;
3014 if (GET_CODE (x) != PLUS)
3015 return false;
3017 op0 = XEXP (x, 0);
3018 op1 = XEXP (x, 1);
3020 /* Recognize the rtl generated by reload which we know will later be
3021 replaced with proper base and index regs. */
3022 if (!strict
3023 && reload_in_progress
3024 && (REG_P (op0) || GET_CODE (op0) == PLUS)
3025 && REG_P (op1))
3026 return true;
3028 return (REG_P (op0) && REG_P (op1)
3029 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
3030 && INT_REG_OK_FOR_INDEX_P (op1, strict))
3031 || (INT_REG_OK_FOR_BASE_P (op1, strict)
3032 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
3035 inline bool
3036 legitimate_indirect_address_p (rtx x, int strict)
3038 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
3041 bool
3042 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
3044 if (!TARGET_MACHO || !flag_pic
3045 || mode != SImode || GET_CODE (x) != MEM)
3046 return false;
3047 x = XEXP (x, 0);
3049 if (GET_CODE (x) != LO_SUM)
3050 return false;
3051 if (GET_CODE (XEXP (x, 0)) != REG)
3052 return false;
3053 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
3054 return false;
3055 x = XEXP (x, 1);
3057 return CONSTANT_P (x);
3060 static bool
3061 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
3063 if (GET_CODE (x) != LO_SUM)
3064 return false;
3065 if (GET_CODE (XEXP (x, 0)) != REG)
3066 return false;
3067 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
3068 return false;
3069 /* Restrict addressing for DI because of our SUBREG hackery. */
3070 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
3071 return false;
3072 x = XEXP (x, 1);
3074 if (TARGET_ELF || TARGET_MACHO)
3076 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
3077 return false;
3078 if (TARGET_TOC)
3079 return false;
3080 if (GET_MODE_NUNITS (mode) != 1)
3081 return false;
3082 if (GET_MODE_BITSIZE (mode) > 64
3083 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
3084 && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode)))
3085 return false;
3087 return CONSTANT_P (x);
3090 return false;
3094 /* Try machine-dependent ways of modifying an illegitimate address
3095 to be legitimate. If we find one, return the new, valid address.
3096 This is used from only one place: `memory_address' in explow.c.
3098 OLDX is the address as it was before break_out_memory_refs was
3099 called. In some cases it is useful to look at this to decide what
3100 needs to be done.
3102 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3104 It is always safe for this function to do nothing. It exists to
3105 recognize opportunities to optimize the output.
3107 On RS/6000, first check for the sum of a register with a constant
3108 integer that is out of range. If so, generate code to add the
3109 constant with the low-order 16 bits masked to the register and force
3110 this result into another register (this can be done with `cau').
3111 Then generate an address of REG+(CONST&0xffff), allowing for the
3112 possibility of bit 16 being a one.
3114 Then check for the sum of a register and something not constant, try to
3115 load the other things into a register and return the sum. */
3118 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3119 enum machine_mode mode)
3121 if (GET_CODE (x) == SYMBOL_REF)
3123 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
3124 if (model != 0)
3125 return rs6000_legitimize_tls_address (x, model);
3128 if (GET_CODE (x) == PLUS
3129 && GET_CODE (XEXP (x, 0)) == REG
3130 && GET_CODE (XEXP (x, 1)) == CONST_INT
3131 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
3133 HOST_WIDE_INT high_int, low_int;
3134 rtx sum;
3135 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3136 high_int = INTVAL (XEXP (x, 1)) - low_int;
3137 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
3138 GEN_INT (high_int)), 0);
3139 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
3141 else if (GET_CODE (x) == PLUS
3142 && GET_CODE (XEXP (x, 0)) == REG
3143 && GET_CODE (XEXP (x, 1)) != CONST_INT
3144 && GET_MODE_NUNITS (mode) == 1
3145 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3146 || TARGET_POWERPC64
3147 || (((mode != DImode && mode != DFmode) || TARGET_E500_DOUBLE)
3148 && mode != TFmode))
3149 && (TARGET_POWERPC64 || mode != DImode)
3150 && mode != TImode)
3152 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
3153 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
3155 else if (ALTIVEC_VECTOR_MODE (mode))
3157 rtx reg;
3159 /* Make sure both operands are registers. */
3160 if (GET_CODE (x) == PLUS)
3161 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
3162 force_reg (Pmode, XEXP (x, 1)));
3164 reg = force_reg (Pmode, x);
3165 return reg;
3167 else if (SPE_VECTOR_MODE (mode)
3168 || (TARGET_E500_DOUBLE && (mode == DFmode
3169 || mode == DImode)))
3171 if (mode == DImode)
3172 return NULL_RTX;
3173 /* We accept [reg + reg] and [reg + OFFSET]. */
3175 if (GET_CODE (x) == PLUS)
3177 rtx op1 = XEXP (x, 0);
3178 rtx op2 = XEXP (x, 1);
3180 op1 = force_reg (Pmode, op1);
3182 if (GET_CODE (op2) != REG
3183 && (GET_CODE (op2) != CONST_INT
3184 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
3185 op2 = force_reg (Pmode, op2);
3187 return gen_rtx_PLUS (Pmode, op1, op2);
3190 return force_reg (Pmode, x);
3192 else if (TARGET_ELF
3193 && TARGET_32BIT
3194 && TARGET_NO_TOC
3195 && ! flag_pic
3196 && GET_CODE (x) != CONST_INT
3197 && GET_CODE (x) != CONST_DOUBLE
3198 && CONSTANT_P (x)
3199 && GET_MODE_NUNITS (mode) == 1
3200 && (GET_MODE_BITSIZE (mode) <= 32
3201 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
3203 rtx reg = gen_reg_rtx (Pmode);
3204 emit_insn (gen_elf_high (reg, x));
3205 return gen_rtx_LO_SUM (Pmode, reg, x);
3207 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
3208 && ! flag_pic
3209 #if TARGET_MACHO
3210 && ! MACHO_DYNAMIC_NO_PIC_P
3211 #endif
3212 && GET_CODE (x) != CONST_INT
3213 && GET_CODE (x) != CONST_DOUBLE
3214 && CONSTANT_P (x)
3215 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
3216 && mode != DImode
3217 && mode != TImode)
3219 rtx reg = gen_reg_rtx (Pmode);
3220 emit_insn (gen_macho_high (reg, x));
3221 return gen_rtx_LO_SUM (Pmode, reg, x);
3223 else if (TARGET_TOC
3224 && constant_pool_expr_p (x)
3225 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
3227 return create_TOC_reference (x);
3229 else
3230 return NULL_RTX;
3233 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3234 We need to emit DTP-relative relocations. */
3236 static void
3237 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
3239 switch (size)
3241 case 4:
3242 fputs ("\t.long\t", file);
3243 break;
3244 case 8:
3245 fputs (DOUBLE_INT_ASM_OP, file);
3246 break;
3247 default:
3248 gcc_unreachable ();
3250 output_addr_const (file, x);
3251 fputs ("@dtprel+0x8000", file);
3254 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3256 static GTY(()) rtx rs6000_tls_symbol;
3257 static rtx
3258 rs6000_tls_get_addr (void)
3260 if (!rs6000_tls_symbol)
3261 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
3263 return rs6000_tls_symbol;
3266 /* Construct the SYMBOL_REF for TLS GOT references. */
3268 static GTY(()) rtx rs6000_got_symbol;
3269 static rtx
3270 rs6000_got_sym (void)
3272 if (!rs6000_got_symbol)
3274 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
3275 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
3276 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
3279 return rs6000_got_symbol;
3282 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3283 this (thread-local) address. */
3285 static rtx
3286 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
3288 rtx dest, insn;
3290 dest = gen_reg_rtx (Pmode);
3291 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
3293 rtx tlsreg;
3295 if (TARGET_64BIT)
3297 tlsreg = gen_rtx_REG (Pmode, 13);
3298 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
3300 else
3302 tlsreg = gen_rtx_REG (Pmode, 2);
3303 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
3305 emit_insn (insn);
3307 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
3309 rtx tlsreg, tmp;
3311 tmp = gen_reg_rtx (Pmode);
3312 if (TARGET_64BIT)
3314 tlsreg = gen_rtx_REG (Pmode, 13);
3315 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
3317 else
3319 tlsreg = gen_rtx_REG (Pmode, 2);
3320 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
3322 emit_insn (insn);
3323 if (TARGET_64BIT)
3324 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
3325 else
3326 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
3327 emit_insn (insn);
3329 else
3331 rtx r3, got, tga, tmp1, tmp2, eqv;
3333 /* We currently use relocations like @got@tlsgd for tls, which
3334 means the linker will handle allocation of tls entries, placing
3335 them in the .got section. So use a pointer to the .got section,
3336 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3337 or to secondary GOT sections used by 32-bit -fPIC. */
3338 if (TARGET_64BIT)
3339 got = gen_rtx_REG (Pmode, 2);
3340 else
3342 if (flag_pic == 1)
3343 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
3344 else
3346 rtx gsym = rs6000_got_sym ();
3347 got = gen_reg_rtx (Pmode);
3348 if (flag_pic == 0)
3349 rs6000_emit_move (got, gsym, Pmode);
3350 else
3352 rtx tempLR, tmp3, mem;
3353 rtx first, last;
3355 tempLR = gen_reg_rtx (Pmode);
3356 tmp1 = gen_reg_rtx (Pmode);
3357 tmp2 = gen_reg_rtx (Pmode);
3358 tmp3 = gen_reg_rtx (Pmode);
3359 mem = gen_const_mem (Pmode, tmp1);
3361 first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, gsym));
3362 emit_move_insn (tmp1, tempLR);
3363 emit_move_insn (tmp2, mem);
3364 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
3365 last = emit_move_insn (got, tmp3);
3366 set_unique_reg_note (last, REG_EQUAL, gsym);
3367 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3368 REG_NOTES (first));
3369 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3370 REG_NOTES (last));
3375 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
3377 r3 = gen_rtx_REG (Pmode, 3);
3378 if (TARGET_64BIT)
3379 insn = gen_tls_gd_64 (r3, got, addr);
3380 else
3381 insn = gen_tls_gd_32 (r3, got, addr);
3382 start_sequence ();
3383 emit_insn (insn);
3384 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3385 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3386 insn = emit_call_insn (insn);
3387 CONST_OR_PURE_CALL_P (insn) = 1;
3388 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3389 insn = get_insns ();
3390 end_sequence ();
3391 emit_libcall_block (insn, dest, r3, addr);
3393 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3395 r3 = gen_rtx_REG (Pmode, 3);
3396 if (TARGET_64BIT)
3397 insn = gen_tls_ld_64 (r3, got);
3398 else
3399 insn = gen_tls_ld_32 (r3, got);
3400 start_sequence ();
3401 emit_insn (insn);
3402 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3403 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3404 insn = emit_call_insn (insn);
3405 CONST_OR_PURE_CALL_P (insn) = 1;
3406 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3407 insn = get_insns ();
3408 end_sequence ();
3409 tmp1 = gen_reg_rtx (Pmode);
3410 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3411 UNSPEC_TLSLD);
3412 emit_libcall_block (insn, tmp1, r3, eqv);
3413 if (rs6000_tls_size == 16)
3415 if (TARGET_64BIT)
3416 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3417 else
3418 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3420 else if (rs6000_tls_size == 32)
3422 tmp2 = gen_reg_rtx (Pmode);
3423 if (TARGET_64BIT)
3424 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3425 else
3426 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3427 emit_insn (insn);
3428 if (TARGET_64BIT)
3429 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3430 else
3431 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3433 else
3435 tmp2 = gen_reg_rtx (Pmode);
3436 if (TARGET_64BIT)
3437 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3438 else
3439 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3440 emit_insn (insn);
3441 insn = gen_rtx_SET (Pmode, dest,
3442 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3444 emit_insn (insn);
3446 else
3448 /* IE, or 64 bit offset LE. */
3449 tmp2 = gen_reg_rtx (Pmode);
3450 if (TARGET_64BIT)
3451 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3452 else
3453 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3454 emit_insn (insn);
3455 if (TARGET_64BIT)
3456 insn = gen_tls_tls_64 (dest, tmp2, addr);
3457 else
3458 insn = gen_tls_tls_32 (dest, tmp2, addr);
3459 emit_insn (insn);
3463 return dest;
3466 /* Return 1 if X contains a thread-local symbol. */
3468 bool
3469 rs6000_tls_referenced_p (rtx x)
3471 if (! TARGET_HAVE_TLS)
3472 return false;
3474 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
3477 /* Return 1 if *X is a thread-local symbol. This is the same as
3478 rs6000_tls_symbol_ref except for the type of the unused argument. */
3480 static int
3481 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
3483 return RS6000_SYMBOL_REF_TLS_P (*x);
3486 /* The convention appears to be to define this wherever it is used.
3487 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3488 is now used here. */
3489 #ifndef REG_MODE_OK_FOR_BASE_P
3490 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3491 #endif
3493 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3494 replace the input X, or the original X if no replacement is called for.
3495 The output parameter *WIN is 1 if the calling macro should goto WIN,
3496 0 if it should not.
3498 For RS/6000, we wish to handle large displacements off a base
3499 register by splitting the addend across an addiu/addis and the mem insn.
3500 This cuts number of extra insns needed from 3 to 1.
3502 On Darwin, we use this to generate code for floating point constants.
3503 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3504 The Darwin code is inside #if TARGET_MACHO because only then is
3505 machopic_function_base_name() defined. */
3507 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
3508 int opnum, int type,
3509 int ind_levels ATTRIBUTE_UNUSED, int *win)
3511 /* We must recognize output that we have already generated ourselves. */
3512 if (GET_CODE (x) == PLUS
3513 && GET_CODE (XEXP (x, 0)) == PLUS
3514 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3515 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3516 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3518 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3519 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3520 opnum, (enum reload_type)type);
3521 *win = 1;
3522 return x;
3525 #if TARGET_MACHO
3526 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
3527 && GET_CODE (x) == LO_SUM
3528 && GET_CODE (XEXP (x, 0)) == PLUS
3529 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
3530 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
3531 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
3532 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
3533 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
3534 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
3535 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
3537 /* Result of previous invocation of this function on Darwin
3538 floating point constant. */
3539 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3540 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3541 opnum, (enum reload_type)type);
3542 *win = 1;
3543 return x;
3545 #endif
3547 /* Force ld/std non-word aligned offset into base register by wrapping
3548 in offset 0. */
3549 if (GET_CODE (x) == PLUS
3550 && GET_CODE (XEXP (x, 0)) == REG
3551 && REGNO (XEXP (x, 0)) < 32
3552 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3553 && GET_CODE (XEXP (x, 1)) == CONST_INT
3554 && (INTVAL (XEXP (x, 1)) & 3) != 0
3555 && !ALTIVEC_VECTOR_MODE (mode)
3556 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
3557 && TARGET_POWERPC64)
3559 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
3560 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3561 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3562 opnum, (enum reload_type) type);
3563 *win = 1;
3564 return x;
3567 if (GET_CODE (x) == PLUS
3568 && GET_CODE (XEXP (x, 0)) == REG
3569 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
3570 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3571 && GET_CODE (XEXP (x, 1)) == CONST_INT
3572 && !SPE_VECTOR_MODE (mode)
3573 && !(TARGET_E500_DOUBLE && (mode == DFmode
3574 || mode == DImode))
3575 && !ALTIVEC_VECTOR_MODE (mode))
3577 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3578 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
3579 HOST_WIDE_INT high
3580 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3582 /* Check for 32-bit overflow. */
3583 if (high + low != val)
3585 *win = 0;
3586 return x;
3589 /* Reload the high part into a base reg; leave the low part
3590 in the mem directly. */
3592 x = gen_rtx_PLUS (GET_MODE (x),
3593 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
3594 GEN_INT (high)),
3595 GEN_INT (low));
3597 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3598 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3599 opnum, (enum reload_type)type);
3600 *win = 1;
3601 return x;
3604 if (GET_CODE (x) == SYMBOL_REF
3605 && !ALTIVEC_VECTOR_MODE (mode)
3606 && !SPE_VECTOR_MODE (mode)
3607 #if TARGET_MACHO
3608 && DEFAULT_ABI == ABI_DARWIN
3609 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
3610 #else
3611 && DEFAULT_ABI == ABI_V4
3612 && !flag_pic
3613 #endif
3614 /* Don't do this for TFmode, since the result isn't offsettable.
3615 The same goes for DImode without 64-bit gprs and DFmode
3616 without fprs. */
3617 && mode != TFmode
3618 && (mode != DImode || TARGET_POWERPC64)
3619 && (mode != DFmode || TARGET_POWERPC64
3620 || (TARGET_FPRS && TARGET_HARD_FLOAT)))
3622 #if TARGET_MACHO
3623 if (flag_pic)
3625 rtx offset = gen_rtx_CONST (Pmode,
3626 gen_rtx_MINUS (Pmode, x,
3627 machopic_function_base_sym ()));
3628 x = gen_rtx_LO_SUM (GET_MODE (x),
3629 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
3630 gen_rtx_HIGH (Pmode, offset)), offset);
3632 else
3633 #endif
3634 x = gen_rtx_LO_SUM (GET_MODE (x),
3635 gen_rtx_HIGH (Pmode, x), x);
3637 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3638 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3639 opnum, (enum reload_type)type);
3640 *win = 1;
3641 return x;
3644 /* Reload an offset address wrapped by an AND that represents the
3645 masking of the lower bits. Strip the outer AND and let reload
3646 convert the offset address into an indirect address. */
3647 if (TARGET_ALTIVEC
3648 && ALTIVEC_VECTOR_MODE (mode)
3649 && GET_CODE (x) == AND
3650 && GET_CODE (XEXP (x, 0)) == PLUS
3651 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3652 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3653 && GET_CODE (XEXP (x, 1)) == CONST_INT
3654 && INTVAL (XEXP (x, 1)) == -16)
3656 x = XEXP (x, 0);
3657 *win = 1;
3658 return x;
3661 if (TARGET_TOC
3662 && constant_pool_expr_p (x)
3663 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
3665 x = create_TOC_reference (x);
3666 *win = 1;
3667 return x;
3669 *win = 0;
3670 return x;
3673 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3674 that is a valid memory address for an instruction.
3675 The MODE argument is the machine mode for the MEM expression
3676 that wants to use this address.
3678 On the RS/6000, there are four valid address: a SYMBOL_REF that
3679 refers to a constant pool entry of an address (or the sum of it
3680 plus a constant), a short (16-bit signed) constant plus a register,
3681 the sum of two registers, or a register indirect, possibly with an
3682 auto-increment. For DFmode and DImode with a constant plus register,
3683 we must ensure that both words are addressable or PowerPC64 with offset
3684 word aligned.
3686 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3687 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3688 adjacent memory cells are accessed by adding word-sized offsets
3689 during assembly output. */
3691 rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
3693 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3694 if (TARGET_ALTIVEC
3695 && ALTIVEC_VECTOR_MODE (mode)
3696 && GET_CODE (x) == AND
3697 && GET_CODE (XEXP (x, 1)) == CONST_INT
3698 && INTVAL (XEXP (x, 1)) == -16)
3699 x = XEXP (x, 0);
3701 if (RS6000_SYMBOL_REF_TLS_P (x))
3702 return 0;
3703 if (legitimate_indirect_address_p (x, reg_ok_strict))
3704 return 1;
3705 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
3706 && !ALTIVEC_VECTOR_MODE (mode)
3707 && !SPE_VECTOR_MODE (mode)
3708 && mode != TFmode
3709 /* Restrict addressing for DI because of our SUBREG hackery. */
3710 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
3711 && TARGET_UPDATE
3712 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
3713 return 1;
3714 if (legitimate_small_data_p (mode, x))
3715 return 1;
3716 if (legitimate_constant_pool_address_p (x))
3717 return 1;
3718 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3719 if (! reg_ok_strict
3720 && GET_CODE (x) == PLUS
3721 && GET_CODE (XEXP (x, 0)) == REG
3722 && (XEXP (x, 0) == virtual_stack_vars_rtx
3723 || XEXP (x, 0) == arg_pointer_rtx)
3724 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3725 return 1;
3726 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
3727 return 1;
3728 if (mode != TImode
3729 && mode != TFmode
3730 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3731 || TARGET_POWERPC64
3732 || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
3733 && (TARGET_POWERPC64 || mode != DImode)
3734 && legitimate_indexed_address_p (x, reg_ok_strict))
3735 return 1;
3736 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
3737 return 1;
3738 return 0;
3741 /* Go to LABEL if ADDR (a legitimate address expression)
3742 has an effect that depends on the machine mode it is used for.
3744 On the RS/6000 this is true of all integral offsets (since AltiVec
3745 modes don't allow them) or is a pre-increment or decrement.
3747 ??? Except that due to conceptual problems in offsettable_address_p
3748 we can't really report the problems of integral offsets. So leave
3749 this assuming that the adjustable offset must be valid for the
3750 sub-words of a TFmode operand, which is what we had before. */
3752 bool
3753 rs6000_mode_dependent_address (rtx addr)
3755 switch (GET_CODE (addr))
3757 case PLUS:
3758 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
3760 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
3761 return val + 12 + 0x8000 >= 0x10000;
3763 break;
3765 case LO_SUM:
3766 return true;
3768 /* Auto-increment cases are now treated generically in recog.c. */
3770 default:
3771 break;
3774 return false;
3777 /* More elaborate version of recog's offsettable_memref_p predicate
3778 that works around the ??? note of rs6000_mode_dependent_address.
3779 In particular it accepts
3781 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
3783 in 32-bit mode, that the recog predicate rejects. */
3785 bool
3786 rs6000_offsettable_memref_p (rtx op)
3788 if (!MEM_P (op))
3789 return false;
3791 /* First mimic offsettable_memref_p. */
3792 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
3793 return true;
3795 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
3796 the latter predicate knows nothing about the mode of the memory
3797 reference and, therefore, assumes that it is the largest supported
3798 mode (TFmode). As a consequence, legitimate offsettable memory
3799 references are rejected. rs6000_legitimate_offset_address_p contains
3800 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
3801 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
3804 /* Return number of consecutive hard regs needed starting at reg REGNO
3805 to hold something of mode MODE.
3806 This is ordinarily the length in words of a value of mode MODE
3807 but can be less for certain modes in special long registers.
3809 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3810 scalar instructions. The upper 32 bits are only available to the
3811 SIMD instructions.
3813 POWER and PowerPC GPRs hold 32 bits worth;
3814 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3817 rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
3819 if (FP_REGNO_P (regno))
3820 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3822 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
3823 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
3825 if (ALTIVEC_REGNO_P (regno))
3826 return
3827 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
3829 /* The value returned for SCmode in the E500 double case is 2 for
3830 ABI compatibility; storing an SCmode value in a single register
3831 would require function_arg and rs6000_spe_function_arg to handle
3832 SCmode so as to pass the value correctly in a pair of
3833 registers. */
3834 if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode)
3835 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3837 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3840 /* Change register usage conditional on target flags. */
3841 void
3842 rs6000_conditional_register_usage (void)
3844 int i;
3846 /* Set MQ register fixed (already call_used) if not POWER
3847 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3848 be allocated. */
3849 if (! TARGET_POWER)
3850 fixed_regs[64] = 1;
3852 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3853 if (TARGET_64BIT)
3854 fixed_regs[13] = call_used_regs[13]
3855 = call_really_used_regs[13] = 1;
3857 /* Conditionally disable FPRs. */
3858 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
3859 for (i = 32; i < 64; i++)
3860 fixed_regs[i] = call_used_regs[i]
3861 = call_really_used_regs[i] = 1;
3863 /* The TOC register is not killed across calls in a way that is
3864 visible to the compiler. */
3865 if (DEFAULT_ABI == ABI_AIX)
3866 call_really_used_regs[2] = 0;
3868 if (DEFAULT_ABI == ABI_V4
3869 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3870 && flag_pic == 2)
3871 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3873 if (DEFAULT_ABI == ABI_V4
3874 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3875 && flag_pic == 1)
3876 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3877 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3878 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3880 if (DEFAULT_ABI == ABI_DARWIN
3881 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
3882 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3883 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3884 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3886 if (TARGET_TOC && TARGET_MINIMAL_TOC)
3887 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3888 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3890 if (TARGET_ALTIVEC)
3891 global_regs[VSCR_REGNO] = 1;
3893 if (TARGET_SPE)
3895 global_regs[SPEFSCR_REGNO] = 1;
3896 fixed_regs[FIXED_SCRATCH]
3897 = call_used_regs[FIXED_SCRATCH]
3898 = call_really_used_regs[FIXED_SCRATCH] = 1;
3901 if (! TARGET_ALTIVEC)
3903 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
3904 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
3905 call_really_used_regs[VRSAVE_REGNO] = 1;
3908 if (TARGET_ALTIVEC_ABI)
3909 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
3910 call_used_regs[i] = call_really_used_regs[i] = 1;
3913 /* Try to output insns to set TARGET equal to the constant C if it can
3914 be done in less than N insns. Do all computations in MODE.
3915 Returns the place where the output has been placed if it can be
3916 done and the insns have been emitted. If it would take more than N
3917 insns, zero is returned and no insns and emitted. */
3920 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
3921 rtx source, int n ATTRIBUTE_UNUSED)
3923 rtx result, insn, set;
3924 HOST_WIDE_INT c0, c1;
3926 switch (mode)
3928 case QImode:
3929 case HImode:
3930 if (dest == NULL)
3931 dest = gen_reg_rtx (mode);
3932 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
3933 return dest;
3935 case SImode:
3936 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
3938 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
3939 GEN_INT (INTVAL (source)
3940 & (~ (HOST_WIDE_INT) 0xffff))));
3941 emit_insn (gen_rtx_SET (VOIDmode, dest,
3942 gen_rtx_IOR (SImode, copy_rtx (result),
3943 GEN_INT (INTVAL (source) & 0xffff))));
3944 result = dest;
3945 break;
3947 case DImode:
3948 switch (GET_CODE (source))
3950 case CONST_INT:
3951 c0 = INTVAL (source);
3952 c1 = -(c0 < 0);
3953 break;
3955 case CONST_DOUBLE:
3956 #if HOST_BITS_PER_WIDE_INT >= 64
3957 c0 = CONST_DOUBLE_LOW (source);
3958 c1 = -(c0 < 0);
3959 #else
3960 c0 = CONST_DOUBLE_LOW (source);
3961 c1 = CONST_DOUBLE_HIGH (source);
3962 #endif
3963 break;
3965 default:
3966 gcc_unreachable ();
3969 result = rs6000_emit_set_long_const (dest, c0, c1);
3970 break;
3972 default:
3973 gcc_unreachable ();
3976 insn = get_last_insn ();
3977 set = single_set (insn);
3978 if (! CONSTANT_P (SET_SRC (set)))
3979 set_unique_reg_note (insn, REG_EQUAL, source);
3981 return result;
3984 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
3985 fall back to a straight forward decomposition. We do this to avoid
3986 exponential run times encountered when looking for longer sequences
3987 with rs6000_emit_set_const. */
3988 static rtx
3989 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
3991 if (!TARGET_POWERPC64)
3993 rtx operand1, operand2;
3995 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
3996 DImode);
3997 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
3998 DImode);
3999 emit_move_insn (operand1, GEN_INT (c1));
4000 emit_move_insn (operand2, GEN_INT (c2));
4002 else
4004 HOST_WIDE_INT ud1, ud2, ud3, ud4;
4006 ud1 = c1 & 0xffff;
4007 ud2 = (c1 & 0xffff0000) >> 16;
4008 #if HOST_BITS_PER_WIDE_INT >= 64
4009 c2 = c1 >> 32;
4010 #endif
4011 ud3 = c2 & 0xffff;
4012 ud4 = (c2 & 0xffff0000) >> 16;
4014 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
4015 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
4017 if (ud1 & 0x8000)
4018 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
4019 else
4020 emit_move_insn (dest, GEN_INT (ud1));
4023 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
4024 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
4026 if (ud2 & 0x8000)
4027 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
4028 - 0x80000000));
4029 else
4030 emit_move_insn (dest, GEN_INT (ud2 << 16));
4031 if (ud1 != 0)
4032 emit_move_insn (copy_rtx (dest),
4033 gen_rtx_IOR (DImode, copy_rtx (dest),
4034 GEN_INT (ud1)));
4036 else if ((ud4 == 0xffff && (ud3 & 0x8000))
4037 || (ud4 == 0 && ! (ud3 & 0x8000)))
4039 if (ud3 & 0x8000)
4040 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
4041 - 0x80000000));
4042 else
4043 emit_move_insn (dest, GEN_INT (ud3 << 16));
4045 if (ud2 != 0)
4046 emit_move_insn (copy_rtx (dest),
4047 gen_rtx_IOR (DImode, copy_rtx (dest),
4048 GEN_INT (ud2)));
4049 emit_move_insn (copy_rtx (dest),
4050 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4051 GEN_INT (16)));
4052 if (ud1 != 0)
4053 emit_move_insn (copy_rtx (dest),
4054 gen_rtx_IOR (DImode, copy_rtx (dest),
4055 GEN_INT (ud1)));
4057 else
4059 if (ud4 & 0x8000)
4060 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
4061 - 0x80000000));
4062 else
4063 emit_move_insn (dest, GEN_INT (ud4 << 16));
4065 if (ud3 != 0)
4066 emit_move_insn (copy_rtx (dest),
4067 gen_rtx_IOR (DImode, copy_rtx (dest),
4068 GEN_INT (ud3)));
4070 emit_move_insn (copy_rtx (dest),
4071 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4072 GEN_INT (32)));
4073 if (ud2 != 0)
4074 emit_move_insn (copy_rtx (dest),
4075 gen_rtx_IOR (DImode, copy_rtx (dest),
4076 GEN_INT (ud2 << 16)));
4077 if (ud1 != 0)
4078 emit_move_insn (copy_rtx (dest),
4079 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
4082 return dest;
4085 /* Helper for the following. Get rid of [r+r] memory refs
4086 in cases where it won't work (TImode, TFmode). */
4088 static void
4089 rs6000_eliminate_indexed_memrefs (rtx operands[2])
4091 if (GET_CODE (operands[0]) == MEM
4092 && GET_CODE (XEXP (operands[0], 0)) != REG
4093 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
4094 && ! reload_in_progress)
4095 operands[0]
4096 = replace_equiv_address (operands[0],
4097 copy_addr_to_reg (XEXP (operands[0], 0)));
4099 if (GET_CODE (operands[1]) == MEM
4100 && GET_CODE (XEXP (operands[1], 0)) != REG
4101 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
4102 && ! reload_in_progress)
4103 operands[1]
4104 = replace_equiv_address (operands[1],
4105 copy_addr_to_reg (XEXP (operands[1], 0)));
4108 /* Emit a move from SOURCE to DEST in mode MODE. */
4109 void
4110 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
4112 rtx operands[2];
4113 operands[0] = dest;
4114 operands[1] = source;
4116 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4117 if (GET_CODE (operands[1]) == CONST_DOUBLE
4118 && ! FLOAT_MODE_P (mode)
4119 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
4121 /* FIXME. This should never happen. */
4122 /* Since it seems that it does, do the safe thing and convert
4123 to a CONST_INT. */
4124 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
4126 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
4127 || FLOAT_MODE_P (mode)
4128 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
4129 || CONST_DOUBLE_LOW (operands[1]) < 0)
4130 && (CONST_DOUBLE_HIGH (operands[1]) != -1
4131 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
4133 /* Check if GCC is setting up a block move that will end up using FP
4134 registers as temporaries. We must make sure this is acceptable. */
4135 if (GET_CODE (operands[0]) == MEM
4136 && GET_CODE (operands[1]) == MEM
4137 && mode == DImode
4138 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
4139 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
4140 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
4141 ? 32 : MEM_ALIGN (operands[0])))
4142 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
4143 ? 32
4144 : MEM_ALIGN (operands[1]))))
4145 && ! MEM_VOLATILE_P (operands [0])
4146 && ! MEM_VOLATILE_P (operands [1]))
4148 emit_move_insn (adjust_address (operands[0], SImode, 0),
4149 adjust_address (operands[1], SImode, 0));
4150 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
4151 adjust_address (copy_rtx (operands[1]), SImode, 4));
4152 return;
4155 if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
4156 && !gpc_reg_operand (operands[1], mode))
4157 operands[1] = force_reg (mode, operands[1]);
4159 if (mode == SFmode && ! TARGET_POWERPC
4160 && TARGET_HARD_FLOAT && TARGET_FPRS
4161 && GET_CODE (operands[0]) == MEM)
4163 int regnum;
4165 if (reload_in_progress || reload_completed)
4166 regnum = true_regnum (operands[1]);
4167 else if (GET_CODE (operands[1]) == REG)
4168 regnum = REGNO (operands[1]);
4169 else
4170 regnum = -1;
4172 /* If operands[1] is a register, on POWER it may have
4173 double-precision data in it, so truncate it to single
4174 precision. */
4175 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
4177 rtx newreg;
4178 newreg = (no_new_pseudos ? copy_rtx (operands[1])
4179 : gen_reg_rtx (mode));
4180 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
4181 operands[1] = newreg;
4185 /* Recognize the case where operand[1] is a reference to thread-local
4186 data and load its address to a register. */
4187 if (rs6000_tls_referenced_p (operands[1]))
4189 enum tls_model model;
4190 rtx tmp = operands[1];
4191 rtx addend = NULL;
4193 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
4195 addend = XEXP (XEXP (tmp, 0), 1);
4196 tmp = XEXP (XEXP (tmp, 0), 0);
4199 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
4200 model = SYMBOL_REF_TLS_MODEL (tmp);
4201 gcc_assert (model != 0);
4203 tmp = rs6000_legitimize_tls_address (tmp, model);
4204 if (addend)
4206 tmp = gen_rtx_PLUS (mode, tmp, addend);
4207 tmp = force_operand (tmp, operands[0]);
4209 operands[1] = tmp;
4212 /* Handle the case where reload calls us with an invalid address. */
4213 if (reload_in_progress && mode == Pmode
4214 && (! general_operand (operands[1], mode)
4215 || ! nonimmediate_operand (operands[0], mode)))
4216 goto emit_set;
4218 /* 128-bit constant floating-point values on Darwin should really be
4219 loaded as two parts. */
4220 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
4221 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
4223 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4224 know how to get a DFmode SUBREG of a TFmode. */
4225 rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
4226 simplify_gen_subreg (DImode, operands[1], mode, 0),
4227 DImode);
4228 rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
4229 GET_MODE_SIZE (DImode)),
4230 simplify_gen_subreg (DImode, operands[1], mode,
4231 GET_MODE_SIZE (DImode)),
4232 DImode);
4233 return;
4236 /* FIXME: In the long term, this switch statement should go away
4237 and be replaced by a sequence of tests based on things like
4238 mode == Pmode. */
4239 switch (mode)
4241 case HImode:
4242 case QImode:
4243 if (CONSTANT_P (operands[1])
4244 && GET_CODE (operands[1]) != CONST_INT)
4245 operands[1] = force_const_mem (mode, operands[1]);
4246 break;
4248 case TFmode:
4249 rs6000_eliminate_indexed_memrefs (operands);
4250 /* fall through */
4252 case DFmode:
4253 case SFmode:
4254 if (CONSTANT_P (operands[1])
4255 && ! easy_fp_constant (operands[1], mode))
4256 operands[1] = force_const_mem (mode, operands[1]);
4257 break;
4259 case V16QImode:
4260 case V8HImode:
4261 case V4SFmode:
4262 case V4SImode:
4263 case V4HImode:
4264 case V2SFmode:
4265 case V2SImode:
4266 case V1DImode:
4267 if (CONSTANT_P (operands[1])
4268 && !easy_vector_constant (operands[1], mode))
4269 operands[1] = force_const_mem (mode, operands[1]);
4270 break;
4272 case SImode:
4273 case DImode:
4274 /* Use default pattern for address of ELF small data */
4275 if (TARGET_ELF
4276 && mode == Pmode
4277 && DEFAULT_ABI == ABI_V4
4278 && (GET_CODE (operands[1]) == SYMBOL_REF
4279 || GET_CODE (operands[1]) == CONST)
4280 && small_data_operand (operands[1], mode))
4282 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4283 return;
4286 if (DEFAULT_ABI == ABI_V4
4287 && mode == Pmode && mode == SImode
4288 && flag_pic == 1 && got_operand (operands[1], mode))
4290 emit_insn (gen_movsi_got (operands[0], operands[1]));
4291 return;
4294 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
4295 && TARGET_NO_TOC
4296 && ! flag_pic
4297 && mode == Pmode
4298 && CONSTANT_P (operands[1])
4299 && GET_CODE (operands[1]) != HIGH
4300 && GET_CODE (operands[1]) != CONST_INT)
4302 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
4304 /* If this is a function address on -mcall-aixdesc,
4305 convert it to the address of the descriptor. */
4306 if (DEFAULT_ABI == ABI_AIX
4307 && GET_CODE (operands[1]) == SYMBOL_REF
4308 && XSTR (operands[1], 0)[0] == '.')
4310 const char *name = XSTR (operands[1], 0);
4311 rtx new_ref;
4312 while (*name == '.')
4313 name++;
4314 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
4315 CONSTANT_POOL_ADDRESS_P (new_ref)
4316 = CONSTANT_POOL_ADDRESS_P (operands[1]);
4317 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
4318 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4319 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
4320 operands[1] = new_ref;
4323 if (DEFAULT_ABI == ABI_DARWIN)
4325 #if TARGET_MACHO
4326 if (MACHO_DYNAMIC_NO_PIC_P)
4328 /* Take care of any required data indirection. */
4329 operands[1] = rs6000_machopic_legitimize_pic_address (
4330 operands[1], mode, operands[0]);
4331 if (operands[0] != operands[1])
4332 emit_insn (gen_rtx_SET (VOIDmode,
4333 operands[0], operands[1]));
4334 return;
4336 #endif
4337 emit_insn (gen_macho_high (target, operands[1]));
4338 emit_insn (gen_macho_low (operands[0], target, operands[1]));
4339 return;
4342 emit_insn (gen_elf_high (target, operands[1]));
4343 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4344 return;
4347 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4348 and we have put it in the TOC, we just need to make a TOC-relative
4349 reference to it. */
4350 if (TARGET_TOC
4351 && GET_CODE (operands[1]) == SYMBOL_REF
4352 && constant_pool_expr_p (operands[1])
4353 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
4354 get_pool_mode (operands[1])))
4356 operands[1] = create_TOC_reference (operands[1]);
4358 else if (mode == Pmode
4359 && CONSTANT_P (operands[1])
4360 && ((GET_CODE (operands[1]) != CONST_INT
4361 && ! easy_fp_constant (operands[1], mode))
4362 || (GET_CODE (operands[1]) == CONST_INT
4363 && num_insns_constant (operands[1], mode) > 2)
4364 || (GET_CODE (operands[0]) == REG
4365 && FP_REGNO_P (REGNO (operands[0]))))
4366 && GET_CODE (operands[1]) != HIGH
4367 && ! legitimate_constant_pool_address_p (operands[1])
4368 && ! toc_relative_expr_p (operands[1]))
4370 /* Emit a USE operation so that the constant isn't deleted if
4371 expensive optimizations are turned on because nobody
4372 references it. This should only be done for operands that
4373 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4374 This should not be done for operands that contain LABEL_REFs.
4375 For now, we just handle the obvious case. */
4376 if (GET_CODE (operands[1]) != LABEL_REF)
4377 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
4379 #if TARGET_MACHO
4380 /* Darwin uses a special PIC legitimizer. */
4381 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
4383 operands[1] =
4384 rs6000_machopic_legitimize_pic_address (operands[1], mode,
4385 operands[0]);
4386 if (operands[0] != operands[1])
4387 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4388 return;
4390 #endif
4392 /* If we are to limit the number of things we put in the TOC and
4393 this is a symbol plus a constant we can add in one insn,
4394 just put the symbol in the TOC and add the constant. Don't do
4395 this if reload is in progress. */
4396 if (GET_CODE (operands[1]) == CONST
4397 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4398 && GET_CODE (XEXP (operands[1], 0)) == PLUS
4399 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
4400 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4401 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4402 && ! side_effects_p (operands[0]))
4404 rtx sym =
4405 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
4406 rtx other = XEXP (XEXP (operands[1], 0), 1);
4408 sym = force_reg (mode, sym);
4409 if (mode == SImode)
4410 emit_insn (gen_addsi3 (operands[0], sym, other));
4411 else
4412 emit_insn (gen_adddi3 (operands[0], sym, other));
4413 return;
4416 operands[1] = force_const_mem (mode, operands[1]);
4418 if (TARGET_TOC
4419 && constant_pool_expr_p (XEXP (operands[1], 0))
4420 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4421 get_pool_constant (XEXP (operands[1], 0)),
4422 get_pool_mode (XEXP (operands[1], 0))))
4424 operands[1]
4425 = gen_const_mem (mode,
4426 create_TOC_reference (XEXP (operands[1], 0)));
4427 set_mem_alias_set (operands[1], get_TOC_alias_set ());
4430 break;
4432 case TImode:
4433 rs6000_eliminate_indexed_memrefs (operands);
4435 if (TARGET_POWER)
4437 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4438 gen_rtvec (2,
4439 gen_rtx_SET (VOIDmode,
4440 operands[0], operands[1]),
4441 gen_rtx_CLOBBER (VOIDmode,
4442 gen_rtx_SCRATCH (SImode)))));
4443 return;
4445 break;
4447 default:
4448 gcc_unreachable ();
4451 /* Above, we may have called force_const_mem which may have returned
4452 an invalid address. If we can, fix this up; otherwise, reload will
4453 have to deal with it. */
4454 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
4455 operands[1] = validize_mem (operands[1]);
4457 emit_set:
4458 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4461 /* Nonzero if we can use a floating-point register to pass this arg. */
4462 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4463 (SCALAR_FLOAT_MODE_P (MODE) \
4464 && !DECIMAL_FLOAT_MODE_P (MODE) \
4465 && (CUM)->fregno <= FP_ARG_MAX_REG \
4466 && TARGET_HARD_FLOAT && TARGET_FPRS)
4468 /* Nonzero if we can use an AltiVec register to pass this arg. */
4469 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4470 (ALTIVEC_VECTOR_MODE (MODE) \
4471 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4472 && TARGET_ALTIVEC_ABI \
4473 && (NAMED))
4475 /* Return a nonzero value to say to return the function value in
4476 memory, just as large structures are always returned. TYPE will be
4477 the data type of the value, and FNTYPE will be the type of the
4478 function doing the returning, or @code{NULL} for libcalls.
4480 The AIX ABI for the RS/6000 specifies that all structures are
4481 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4482 specifies that structures <= 8 bytes are returned in r3/r4, but a
4483 draft put them in memory, and GCC used to implement the draft
4484 instead of the final standard. Therefore, aix_struct_return
4485 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4486 compatibility can change DRAFT_V4_STRUCT_RET to override the
4487 default, and -m switches get the final word. See
4488 rs6000_override_options for more details.
4490 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4491 long double support is enabled. These values are returned in memory.
4493 int_size_in_bytes returns -1 for variable size objects, which go in
4494 memory always. The cast to unsigned makes -1 > 8. */
4496 static bool
4497 rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
4499 /* In the darwin64 abi, try to use registers for larger structs
4500 if possible. */
4501 if (rs6000_darwin64_abi
4502 && TREE_CODE (type) == RECORD_TYPE
4503 && int_size_in_bytes (type) > 0)
4505 CUMULATIVE_ARGS valcum;
4506 rtx valret;
4508 valcum.words = 0;
4509 valcum.fregno = FP_ARG_MIN_REG;
4510 valcum.vregno = ALTIVEC_ARG_MIN_REG;
4511 /* Do a trial code generation as if this were going to be passed
4512 as an argument; if any part goes in memory, we return NULL. */
4513 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
4514 if (valret)
4515 return false;
4516 /* Otherwise fall through to more conventional ABI rules. */
4519 if (AGGREGATE_TYPE_P (type)
4520 && (aix_struct_return
4521 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
4522 return true;
4524 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4525 modes only exist for GCC vector types if -maltivec. */
4526 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
4527 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
4528 return false;
4530 /* Return synthetic vectors in memory. */
4531 if (TREE_CODE (type) == VECTOR_TYPE
4532 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
4534 static bool warned_for_return_big_vectors = false;
4535 if (!warned_for_return_big_vectors)
4537 warning (0, "GCC vector returned by reference: "
4538 "non-standard ABI extension with no compatibility guarantee");
4539 warned_for_return_big_vectors = true;
4541 return true;
4544 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
4545 return true;
4547 return false;
4550 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4551 for a call to a function whose data type is FNTYPE.
4552 For a library call, FNTYPE is 0.
4554 For incoming args we set the number of arguments in the prototype large
4555 so we never return a PARALLEL. */
4557 void
4558 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
4559 rtx libname ATTRIBUTE_UNUSED, int incoming,
4560 int libcall, int n_named_args)
4562 static CUMULATIVE_ARGS zero_cumulative;
4564 *cum = zero_cumulative;
4565 cum->words = 0;
4566 cum->fregno = FP_ARG_MIN_REG;
4567 cum->vregno = ALTIVEC_ARG_MIN_REG;
4568 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
4569 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
4570 ? CALL_LIBCALL : CALL_NORMAL);
4571 cum->sysv_gregno = GP_ARG_MIN_REG;
4572 cum->stdarg = fntype
4573 && (TYPE_ARG_TYPES (fntype) != 0
4574 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4575 != void_type_node));
4577 cum->nargs_prototype = 0;
4578 if (incoming || cum->prototype)
4579 cum->nargs_prototype = n_named_args;
4581 /* Check for a longcall attribute. */
4582 if ((!fntype && rs6000_default_long_calls)
4583 || (fntype
4584 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
4585 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
4586 cum->call_cookie |= CALL_LONG;
4588 if (TARGET_DEBUG_ARG)
4590 fprintf (stderr, "\ninit_cumulative_args:");
4591 if (fntype)
4593 tree ret_type = TREE_TYPE (fntype);
4594 fprintf (stderr, " ret code = %s,",
4595 tree_code_name[ (int)TREE_CODE (ret_type) ]);
4598 if (cum->call_cookie & CALL_LONG)
4599 fprintf (stderr, " longcall,");
4601 fprintf (stderr, " proto = %d, nargs = %d\n",
4602 cum->prototype, cum->nargs_prototype);
4605 if (fntype
4606 && !TARGET_ALTIVEC
4607 && TARGET_ALTIVEC_ABI
4608 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
4610 error ("cannot return value in vector register because"
4611 " altivec instructions are disabled, use -maltivec"
4612 " to enable them");
4616 /* Return true if TYPE must be passed on the stack and not in registers. */
4618 static bool
4619 rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
4621 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
4622 return must_pass_in_stack_var_size (mode, type);
4623 else
4624 return must_pass_in_stack_var_size_or_pad (mode, type);
4627 /* If defined, a C expression which determines whether, and in which
4628 direction, to pad out an argument with extra space. The value
4629 should be of type `enum direction': either `upward' to pad above
4630 the argument, `downward' to pad below, or `none' to inhibit
4631 padding.
4633 For the AIX ABI structs are always stored left shifted in their
4634 argument slot. */
4636 enum direction
4637 function_arg_padding (enum machine_mode mode, tree type)
4639 #ifndef AGGREGATE_PADDING_FIXED
4640 #define AGGREGATE_PADDING_FIXED 0
4641 #endif
4642 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4643 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4644 #endif
4646 if (!AGGREGATE_PADDING_FIXED)
4648 /* GCC used to pass structures of the same size as integer types as
4649 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4650 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4651 passed padded downward, except that -mstrict-align further
4652 muddied the water in that multi-component structures of 2 and 4
4653 bytes in size were passed padded upward.
4655 The following arranges for best compatibility with previous
4656 versions of gcc, but removes the -mstrict-align dependency. */
4657 if (BYTES_BIG_ENDIAN)
4659 HOST_WIDE_INT size = 0;
4661 if (mode == BLKmode)
4663 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
4664 size = int_size_in_bytes (type);
4666 else
4667 size = GET_MODE_SIZE (mode);
4669 if (size == 1 || size == 2 || size == 4)
4670 return downward;
4672 return upward;
4675 if (AGGREGATES_PAD_UPWARD_ALWAYS)
4677 if (type != 0 && AGGREGATE_TYPE_P (type))
4678 return upward;
4681 /* Fall back to the default. */
4682 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
4685 /* If defined, a C expression that gives the alignment boundary, in bits,
4686 of an argument with the specified mode and type. If it is not defined,
4687 PARM_BOUNDARY is used for all arguments.
4689 V.4 wants long longs and doubles to be double word aligned. Just
4690 testing the mode size is a boneheaded way to do this as it means
4691 that other types such as complex int are also double word aligned.
4692 However, we're stuck with this because changing the ABI might break
4693 existing library interfaces.
4695 Doubleword align SPE vectors.
4696 Quadword align Altivec vectors.
4697 Quadword align large synthetic vector types. */
4700 function_arg_boundary (enum machine_mode mode, tree type)
4702 if (DEFAULT_ABI == ABI_V4
4703 && (GET_MODE_SIZE (mode) == 8
4704 || (TARGET_HARD_FLOAT
4705 && TARGET_FPRS
4706 && mode == TFmode)))
4707 return 64;
4708 else if (SPE_VECTOR_MODE (mode)
4709 || (type && TREE_CODE (type) == VECTOR_TYPE
4710 && int_size_in_bytes (type) >= 8
4711 && int_size_in_bytes (type) < 16))
4712 return 64;
4713 else if (ALTIVEC_VECTOR_MODE (mode)
4714 || (type && TREE_CODE (type) == VECTOR_TYPE
4715 && int_size_in_bytes (type) >= 16))
4716 return 128;
4717 else if (rs6000_darwin64_abi && mode == BLKmode
4718 && type && TYPE_ALIGN (type) > 64)
4719 return 128;
4720 else
4721 return PARM_BOUNDARY;
4724 /* For a function parm of MODE and TYPE, return the starting word in
4725 the parameter area. NWORDS of the parameter area are already used. */
4727 static unsigned int
4728 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
4730 unsigned int align;
4731 unsigned int parm_offset;
4733 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
4734 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
4735 return nwords + (-(parm_offset + nwords) & align);
4738 /* Compute the size (in words) of a function argument. */
4740 static unsigned long
4741 rs6000_arg_size (enum machine_mode mode, tree type)
4743 unsigned long size;
4745 if (mode != BLKmode)
4746 size = GET_MODE_SIZE (mode);
4747 else
4748 size = int_size_in_bytes (type);
4750 if (TARGET_32BIT)
4751 return (size + 3) >> 2;
4752 else
4753 return (size + 7) >> 3;
4756 /* Use this to flush pending int fields. */
4758 static void
4759 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
4760 HOST_WIDE_INT bitpos)
4762 unsigned int startbit, endbit;
4763 int intregs, intoffset;
4764 enum machine_mode mode;
4766 if (cum->intoffset == -1)
4767 return;
4769 intoffset = cum->intoffset;
4770 cum->intoffset = -1;
4772 if (intoffset % BITS_PER_WORD != 0)
4774 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4775 MODE_INT, 0);
4776 if (mode == BLKmode)
4778 /* We couldn't find an appropriate mode, which happens,
4779 e.g., in packed structs when there are 3 bytes to load.
4780 Back intoffset back to the beginning of the word in this
4781 case. */
4782 intoffset = intoffset & -BITS_PER_WORD;
4786 startbit = intoffset & -BITS_PER_WORD;
4787 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4788 intregs = (endbit - startbit) / BITS_PER_WORD;
4789 cum->words += intregs;
4792 /* The darwin64 ABI calls for us to recurse down through structs,
4793 looking for elements passed in registers. Unfortunately, we have
4794 to track int register count here also because of misalignments
4795 in powerpc alignment mode. */
4797 static void
4798 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
4799 tree type,
4800 HOST_WIDE_INT startbitpos)
4802 tree f;
4804 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4805 if (TREE_CODE (f) == FIELD_DECL)
4807 HOST_WIDE_INT bitpos = startbitpos;
4808 tree ftype = TREE_TYPE (f);
4809 enum machine_mode mode;
4810 if (ftype == error_mark_node)
4811 continue;
4812 mode = TYPE_MODE (ftype);
4814 if (DECL_SIZE (f) != 0
4815 && host_integerp (bit_position (f), 1))
4816 bitpos += int_bit_position (f);
4818 /* ??? FIXME: else assume zero offset. */
4820 if (TREE_CODE (ftype) == RECORD_TYPE)
4821 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
4822 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
4824 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4825 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4826 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
4828 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
4830 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4831 cum->vregno++;
4832 cum->words += 2;
4834 else if (cum->intoffset == -1)
4835 cum->intoffset = bitpos;
4839 /* Update the data in CUM to advance over an argument
4840 of mode MODE and data type TYPE.
4841 (TYPE is null for libcalls where that information may not be available.)
4843 Note that for args passed by reference, function_arg will be called
4844 with MODE and TYPE set to that of the pointer to the arg, not the arg
4845 itself. */
4847 void
4848 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4849 tree type, int named, int depth)
4851 int size;
4853 /* Only tick off an argument if we're not recursing. */
4854 if (depth == 0)
4855 cum->nargs_prototype--;
4857 if (TARGET_ALTIVEC_ABI
4858 && (ALTIVEC_VECTOR_MODE (mode)
4859 || (type && TREE_CODE (type) == VECTOR_TYPE
4860 && int_size_in_bytes (type) == 16)))
4862 bool stack = false;
4864 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
4866 cum->vregno++;
4867 if (!TARGET_ALTIVEC)
4868 error ("cannot pass argument in vector register because"
4869 " altivec instructions are disabled, use -maltivec"
4870 " to enable them");
4872 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4873 even if it is going to be passed in a vector register.
4874 Darwin does the same for variable-argument functions. */
4875 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
4876 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
4877 stack = true;
4879 else
4880 stack = true;
4882 if (stack)
4884 int align;
4886 /* Vector parameters must be 16-byte aligned. This places
4887 them at 2 mod 4 in terms of words in 32-bit mode, since
4888 the parameter save area starts at offset 24 from the
4889 stack. In 64-bit mode, they just have to start on an
4890 even word, since the parameter save area is 16-byte
4891 aligned. Space for GPRs is reserved even if the argument
4892 will be passed in memory. */
4893 if (TARGET_32BIT)
4894 align = (2 - cum->words) & 3;
4895 else
4896 align = cum->words & 1;
4897 cum->words += align + rs6000_arg_size (mode, type);
4899 if (TARGET_DEBUG_ARG)
4901 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
4902 cum->words, align);
4903 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
4904 cum->nargs_prototype, cum->prototype,
4905 GET_MODE_NAME (mode));
4909 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
4910 && !cum->stdarg
4911 && cum->sysv_gregno <= GP_ARG_MAX_REG)
4912 cum->sysv_gregno++;
4914 else if (rs6000_darwin64_abi
4915 && mode == BLKmode
4916 && TREE_CODE (type) == RECORD_TYPE
4917 && (size = int_size_in_bytes (type)) > 0)
4919 /* Variable sized types have size == -1 and are
4920 treated as if consisting entirely of ints.
4921 Pad to 16 byte boundary if needed. */
4922 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4923 && (cum->words % 2) != 0)
4924 cum->words++;
4925 /* For varargs, we can just go up by the size of the struct. */
4926 if (!named)
4927 cum->words += (size + 7) / 8;
4928 else
4930 /* It is tempting to say int register count just goes up by
4931 sizeof(type)/8, but this is wrong in a case such as
4932 { int; double; int; } [powerpc alignment]. We have to
4933 grovel through the fields for these too. */
4934 cum->intoffset = 0;
4935 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
4936 rs6000_darwin64_record_arg_advance_flush (cum,
4937 size * BITS_PER_UNIT);
4940 else if (DEFAULT_ABI == ABI_V4)
4942 if (TARGET_HARD_FLOAT && TARGET_FPRS
4943 && (mode == SFmode || mode == DFmode
4944 || (mode == TFmode && !TARGET_IEEEQUAD)))
4946 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
4947 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4948 else
4950 cum->fregno = FP_ARG_V4_MAX_REG + 1;
4951 if (mode == DFmode || mode == TFmode)
4952 cum->words += cum->words & 1;
4953 cum->words += rs6000_arg_size (mode, type);
4956 else
4958 int n_words = rs6000_arg_size (mode, type);
4959 int gregno = cum->sysv_gregno;
4961 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4962 (r7,r8) or (r9,r10). As does any other 2 word item such
4963 as complex int due to a historical mistake. */
4964 if (n_words == 2)
4965 gregno += (1 - gregno) & 1;
4967 /* Multi-reg args are not split between registers and stack. */
4968 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
4970 /* Long long and SPE vectors are aligned on the stack.
4971 So are other 2 word items such as complex int due to
4972 a historical mistake. */
4973 if (n_words == 2)
4974 cum->words += cum->words & 1;
4975 cum->words += n_words;
4978 /* Note: continuing to accumulate gregno past when we've started
4979 spilling to the stack indicates the fact that we've started
4980 spilling to the stack to expand_builtin_saveregs. */
4981 cum->sysv_gregno = gregno + n_words;
4984 if (TARGET_DEBUG_ARG)
4986 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
4987 cum->words, cum->fregno);
4988 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
4989 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
4990 fprintf (stderr, "mode = %4s, named = %d\n",
4991 GET_MODE_NAME (mode), named);
4994 else
4996 int n_words = rs6000_arg_size (mode, type);
4997 int start_words = cum->words;
4998 int align_words = rs6000_parm_start (mode, type, start_words);
5000 cum->words = align_words + n_words;
5002 if (SCALAR_FLOAT_MODE_P (mode)
5003 && !DECIMAL_FLOAT_MODE_P (mode)
5004 && TARGET_HARD_FLOAT && TARGET_FPRS)
5005 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5007 if (TARGET_DEBUG_ARG)
5009 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5010 cum->words, cum->fregno);
5011 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
5012 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
5013 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
5014 named, align_words - start_words, depth);
5019 static rtx
5020 spe_build_register_parallel (enum machine_mode mode, int gregno)
5022 rtx r1, r3;
5024 switch (mode)
5026 case DFmode:
5027 r1 = gen_rtx_REG (DImode, gregno);
5028 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5029 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
5031 case DCmode:
5032 r1 = gen_rtx_REG (DImode, gregno);
5033 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5034 r3 = gen_rtx_REG (DImode, gregno + 2);
5035 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5036 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
5038 default:
5039 gcc_unreachable ();
5043 /* Determine where to put a SIMD argument on the SPE. */
5044 static rtx
5045 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5046 tree type)
5048 int gregno = cum->sysv_gregno;
5050 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5051 are passed and returned in a pair of GPRs for ABI compatibility. */
5052 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode))
5054 int n_words = rs6000_arg_size (mode, type);
5056 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5057 if (mode == DFmode)
5058 gregno += (1 - gregno) & 1;
5060 /* Multi-reg args are not split between registers and stack. */
5061 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5062 return NULL_RTX;
5064 return spe_build_register_parallel (mode, gregno);
5066 if (cum->stdarg)
5068 int n_words = rs6000_arg_size (mode, type);
5070 /* SPE vectors are put in odd registers. */
5071 if (n_words == 2 && (gregno & 1) == 0)
5072 gregno += 1;
5074 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
5076 rtx r1, r2;
5077 enum machine_mode m = SImode;
5079 r1 = gen_rtx_REG (m, gregno);
5080 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
5081 r2 = gen_rtx_REG (m, gregno + 1);
5082 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
5083 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
5085 else
5086 return NULL_RTX;
5088 else
5090 if (gregno <= GP_ARG_MAX_REG)
5091 return gen_rtx_REG (mode, gregno);
5092 else
5093 return NULL_RTX;
5097 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5098 structure between cum->intoffset and bitpos to integer registers. */
5100 static void
5101 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
5102 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
5104 enum machine_mode mode;
5105 unsigned int regno;
5106 unsigned int startbit, endbit;
5107 int this_regno, intregs, intoffset;
5108 rtx reg;
5110 if (cum->intoffset == -1)
5111 return;
5113 intoffset = cum->intoffset;
5114 cum->intoffset = -1;
5116 /* If this is the trailing part of a word, try to only load that
5117 much into the register. Otherwise load the whole register. Note
5118 that in the latter case we may pick up unwanted bits. It's not a
5119 problem at the moment but may wish to revisit. */
5121 if (intoffset % BITS_PER_WORD != 0)
5123 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5124 MODE_INT, 0);
5125 if (mode == BLKmode)
5127 /* We couldn't find an appropriate mode, which happens,
5128 e.g., in packed structs when there are 3 bytes to load.
5129 Back intoffset back to the beginning of the word in this
5130 case. */
5131 intoffset = intoffset & -BITS_PER_WORD;
5132 mode = word_mode;
5135 else
5136 mode = word_mode;
5138 startbit = intoffset & -BITS_PER_WORD;
5139 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5140 intregs = (endbit - startbit) / BITS_PER_WORD;
5141 this_regno = cum->words + intoffset / BITS_PER_WORD;
5143 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
5144 cum->use_stack = 1;
5146 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
5147 if (intregs <= 0)
5148 return;
5150 intoffset /= BITS_PER_UNIT;
5153 regno = GP_ARG_MIN_REG + this_regno;
5154 reg = gen_rtx_REG (mode, regno);
5155 rvec[(*k)++] =
5156 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
5158 this_regno += 1;
5159 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
5160 mode = word_mode;
5161 intregs -= 1;
5163 while (intregs > 0);
5166 /* Recursive workhorse for the following. */
5168 static void
5169 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
5170 HOST_WIDE_INT startbitpos, rtx rvec[],
5171 int *k)
5173 tree f;
5175 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5176 if (TREE_CODE (f) == FIELD_DECL)
5178 HOST_WIDE_INT bitpos = startbitpos;
5179 tree ftype = TREE_TYPE (f);
5180 enum machine_mode mode;
5181 if (ftype == error_mark_node)
5182 continue;
5183 mode = TYPE_MODE (ftype);
5185 if (DECL_SIZE (f) != 0
5186 && host_integerp (bit_position (f), 1))
5187 bitpos += int_bit_position (f);
5189 /* ??? FIXME: else assume zero offset. */
5191 if (TREE_CODE (ftype) == RECORD_TYPE)
5192 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
5193 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
5195 #if 0
5196 switch (mode)
5198 case SCmode: mode = SFmode; break;
5199 case DCmode: mode = DFmode; break;
5200 case TCmode: mode = TFmode; break;
5201 default: break;
5203 #endif
5204 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5205 rvec[(*k)++]
5206 = gen_rtx_EXPR_LIST (VOIDmode,
5207 gen_rtx_REG (mode, cum->fregno++),
5208 GEN_INT (bitpos / BITS_PER_UNIT));
5209 if (mode == TFmode)
5210 cum->fregno++;
5212 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
5214 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5215 rvec[(*k)++]
5216 = gen_rtx_EXPR_LIST (VOIDmode,
5217 gen_rtx_REG (mode, cum->vregno++),
5218 GEN_INT (bitpos / BITS_PER_UNIT));
5220 else if (cum->intoffset == -1)
5221 cum->intoffset = bitpos;
5225 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5226 the register(s) to be used for each field and subfield of a struct
5227 being passed by value, along with the offset of where the
5228 register's value may be found in the block. FP fields go in FP
5229 register, vector fields go in vector registers, and everything
5230 else goes in int registers, packed as in memory.
5232 This code is also used for function return values. RETVAL indicates
5233 whether this is the case.
5235 Much of this is taken from the SPARC V9 port, which has a similar
5236 calling convention. */
5238 static rtx
5239 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, tree type,
5240 int named, bool retval)
5242 rtx rvec[FIRST_PSEUDO_REGISTER];
5243 int k = 1, kbase = 1;
5244 HOST_WIDE_INT typesize = int_size_in_bytes (type);
5245 /* This is a copy; modifications are not visible to our caller. */
5246 CUMULATIVE_ARGS copy_cum = *orig_cum;
5247 CUMULATIVE_ARGS *cum = &copy_cum;
5249 /* Pad to 16 byte boundary if needed. */
5250 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5251 && (cum->words % 2) != 0)
5252 cum->words++;
5254 cum->intoffset = 0;
5255 cum->use_stack = 0;
5256 cum->named = named;
5258 /* Put entries into rvec[] for individual FP and vector fields, and
5259 for the chunks of memory that go in int regs. Note we start at
5260 element 1; 0 is reserved for an indication of using memory, and
5261 may or may not be filled in below. */
5262 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
5263 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
5265 /* If any part of the struct went on the stack put all of it there.
5266 This hack is because the generic code for
5267 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5268 parts of the struct are not at the beginning. */
5269 if (cum->use_stack)
5271 if (retval)
5272 return NULL_RTX; /* doesn't go in registers at all */
5273 kbase = 0;
5274 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5276 if (k > 1 || cum->use_stack)
5277 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
5278 else
5279 return NULL_RTX;
5282 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5284 static rtx
5285 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
5287 int n_units;
5288 int i, k;
5289 rtx rvec[GP_ARG_NUM_REG + 1];
5291 if (align_words >= GP_ARG_NUM_REG)
5292 return NULL_RTX;
5294 n_units = rs6000_arg_size (mode, type);
5296 /* Optimize the simple case where the arg fits in one gpr, except in
5297 the case of BLKmode due to assign_parms assuming that registers are
5298 BITS_PER_WORD wide. */
5299 if (n_units == 0
5300 || (n_units == 1 && mode != BLKmode))
5301 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5303 k = 0;
5304 if (align_words + n_units > GP_ARG_NUM_REG)
5305 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5306 using a magic NULL_RTX component.
5307 This is not strictly correct. Only some of the arg belongs in
5308 memory, not all of it. However, the normal scheme using
5309 function_arg_partial_nregs can result in unusual subregs, eg.
5310 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5311 store the whole arg to memory is often more efficient than code
5312 to store pieces, and we know that space is available in the right
5313 place for the whole arg. */
5314 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5316 i = 0;
5319 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
5320 rtx off = GEN_INT (i++ * 4);
5321 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5323 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
5325 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5328 /* Determine where to put an argument to a function.
5329 Value is zero to push the argument on the stack,
5330 or a hard register in which to store the argument.
5332 MODE is the argument's machine mode.
5333 TYPE is the data type of the argument (as a tree).
5334 This is null for libcalls where that information may
5335 not be available.
5336 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5337 the preceding args and about the function being called. It is
5338 not modified in this routine.
5339 NAMED is nonzero if this argument is a named parameter
5340 (otherwise it is an extra parameter matching an ellipsis).
5342 On RS/6000 the first eight words of non-FP are normally in registers
5343 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5344 Under V.4, the first 8 FP args are in registers.
5346 If this is floating-point and no prototype is specified, we use
5347 both an FP and integer register (or possibly FP reg and stack). Library
5348 functions (when CALL_LIBCALL is set) always have the proper types for args,
5349 so we can pass the FP value just in one register. emit_library_function
5350 doesn't support PARALLEL anyway.
5352 Note that for args passed by reference, function_arg will be called
5353 with MODE and TYPE set to that of the pointer to the arg, not the arg
5354 itself. */
5357 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5358 tree type, int named)
5360 enum rs6000_abi abi = DEFAULT_ABI;
5362 /* Return a marker to indicate whether CR1 needs to set or clear the
5363 bit that V.4 uses to say fp args were passed in registers.
5364 Assume that we don't need the marker for software floating point,
5365 or compiler generated library calls. */
5366 if (mode == VOIDmode)
5368 if (abi == ABI_V4
5369 && (cum->call_cookie & CALL_LIBCALL) == 0
5370 && (cum->stdarg
5371 || (cum->nargs_prototype < 0
5372 && (cum->prototype || TARGET_NO_PROTOTYPE))))
5374 /* For the SPE, we need to crxor CR6 always. */
5375 if (TARGET_SPE_ABI)
5376 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
5377 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
5378 return GEN_INT (cum->call_cookie
5379 | ((cum->fregno == FP_ARG_MIN_REG)
5380 ? CALL_V4_SET_FP_ARGS
5381 : CALL_V4_CLEAR_FP_ARGS));
5384 return GEN_INT (cum->call_cookie);
5387 if (rs6000_darwin64_abi && mode == BLKmode
5388 && TREE_CODE (type) == RECORD_TYPE)
5390 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
5391 if (rslt != NULL_RTX)
5392 return rslt;
5393 /* Else fall through to usual handling. */
5396 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
5397 if (TARGET_64BIT && ! cum->prototype)
5399 /* Vector parameters get passed in vector register
5400 and also in GPRs or memory, in absence of prototype. */
5401 int align_words;
5402 rtx slot;
5403 align_words = (cum->words + 1) & ~1;
5405 if (align_words >= GP_ARG_NUM_REG)
5407 slot = NULL_RTX;
5409 else
5411 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5413 return gen_rtx_PARALLEL (mode,
5414 gen_rtvec (2,
5415 gen_rtx_EXPR_LIST (VOIDmode,
5416 slot, const0_rtx),
5417 gen_rtx_EXPR_LIST (VOIDmode,
5418 gen_rtx_REG (mode, cum->vregno),
5419 const0_rtx)));
5421 else
5422 return gen_rtx_REG (mode, cum->vregno);
5423 else if (TARGET_ALTIVEC_ABI
5424 && (ALTIVEC_VECTOR_MODE (mode)
5425 || (type && TREE_CODE (type) == VECTOR_TYPE
5426 && int_size_in_bytes (type) == 16)))
5428 if (named || abi == ABI_V4)
5429 return NULL_RTX;
5430 else
5432 /* Vector parameters to varargs functions under AIX or Darwin
5433 get passed in memory and possibly also in GPRs. */
5434 int align, align_words, n_words;
5435 enum machine_mode part_mode;
5437 /* Vector parameters must be 16-byte aligned. This places them at
5438 2 mod 4 in terms of words in 32-bit mode, since the parameter
5439 save area starts at offset 24 from the stack. In 64-bit mode,
5440 they just have to start on an even word, since the parameter
5441 save area is 16-byte aligned. */
5442 if (TARGET_32BIT)
5443 align = (2 - cum->words) & 3;
5444 else
5445 align = cum->words & 1;
5446 align_words = cum->words + align;
5448 /* Out of registers? Memory, then. */
5449 if (align_words >= GP_ARG_NUM_REG)
5450 return NULL_RTX;
5452 if (TARGET_32BIT && TARGET_POWERPC64)
5453 return rs6000_mixed_function_arg (mode, type, align_words);
5455 /* The vector value goes in GPRs. Only the part of the
5456 value in GPRs is reported here. */
5457 part_mode = mode;
5458 n_words = rs6000_arg_size (mode, type);
5459 if (align_words + n_words > GP_ARG_NUM_REG)
5460 /* Fortunately, there are only two possibilities, the value
5461 is either wholly in GPRs or half in GPRs and half not. */
5462 part_mode = DImode;
5464 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
5467 else if (TARGET_SPE_ABI && TARGET_SPE
5468 && (SPE_VECTOR_MODE (mode)
5469 || (TARGET_E500_DOUBLE && (mode == DFmode
5470 || mode == DCmode))))
5471 return rs6000_spe_function_arg (cum, mode, type);
5473 else if (abi == ABI_V4)
5475 if (TARGET_HARD_FLOAT && TARGET_FPRS
5476 && (mode == SFmode || mode == DFmode
5477 || (mode == TFmode && !TARGET_IEEEQUAD)))
5479 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
5480 return gen_rtx_REG (mode, cum->fregno);
5481 else
5482 return NULL_RTX;
5484 else
5486 int n_words = rs6000_arg_size (mode, type);
5487 int gregno = cum->sysv_gregno;
5489 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5490 (r7,r8) or (r9,r10). As does any other 2 word item such
5491 as complex int due to a historical mistake. */
5492 if (n_words == 2)
5493 gregno += (1 - gregno) & 1;
5495 /* Multi-reg args are not split between registers and stack. */
5496 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5497 return NULL_RTX;
5499 if (TARGET_32BIT && TARGET_POWERPC64)
5500 return rs6000_mixed_function_arg (mode, type,
5501 gregno - GP_ARG_MIN_REG);
5502 return gen_rtx_REG (mode, gregno);
5505 else
5507 int align_words = rs6000_parm_start (mode, type, cum->words);
5509 if (USE_FP_FOR_ARG_P (cum, mode, type))
5511 rtx rvec[GP_ARG_NUM_REG + 1];
5512 rtx r;
5513 int k;
5514 bool needs_psave;
5515 enum machine_mode fmode = mode;
5516 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
5518 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
5520 /* Currently, we only ever need one reg here because complex
5521 doubles are split. */
5522 gcc_assert (cum->fregno == FP_ARG_MAX_REG && fmode == TFmode);
5524 /* Long double split over regs and memory. */
5525 fmode = DFmode;
5528 /* Do we also need to pass this arg in the parameter save
5529 area? */
5530 needs_psave = (type
5531 && (cum->nargs_prototype <= 0
5532 || (DEFAULT_ABI == ABI_AIX
5533 && TARGET_XL_COMPAT
5534 && align_words >= GP_ARG_NUM_REG)));
5536 if (!needs_psave && mode == fmode)
5537 return gen_rtx_REG (fmode, cum->fregno);
5539 k = 0;
5540 if (needs_psave)
5542 /* Describe the part that goes in gprs or the stack.
5543 This piece must come first, before the fprs. */
5544 if (align_words < GP_ARG_NUM_REG)
5546 unsigned long n_words = rs6000_arg_size (mode, type);
5548 if (align_words + n_words > GP_ARG_NUM_REG
5549 || (TARGET_32BIT && TARGET_POWERPC64))
5551 /* If this is partially on the stack, then we only
5552 include the portion actually in registers here. */
5553 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
5554 rtx off;
5555 int i = 0;
5556 if (align_words + n_words > GP_ARG_NUM_REG)
5557 /* Not all of the arg fits in gprs. Say that it
5558 goes in memory too, using a magic NULL_RTX
5559 component. Also see comment in
5560 rs6000_mixed_function_arg for why the normal
5561 function_arg_partial_nregs scheme doesn't work
5562 in this case. */
5563 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
5564 const0_rtx);
5567 r = gen_rtx_REG (rmode,
5568 GP_ARG_MIN_REG + align_words);
5569 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
5570 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5572 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
5574 else
5576 /* The whole arg fits in gprs. */
5577 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5578 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5581 else
5582 /* It's entirely in memory. */
5583 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5586 /* Describe where this piece goes in the fprs. */
5587 r = gen_rtx_REG (fmode, cum->fregno);
5588 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5590 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5592 else if (align_words < GP_ARG_NUM_REG)
5594 if (TARGET_32BIT && TARGET_POWERPC64)
5595 return rs6000_mixed_function_arg (mode, type, align_words);
5597 if (mode == BLKmode)
5598 mode = Pmode;
5600 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5602 else
5603 return NULL_RTX;
5607 /* For an arg passed partly in registers and partly in memory, this is
5608 the number of bytes passed in registers. For args passed entirely in
5609 registers or entirely in memory, zero. When an arg is described by a
5610 PARALLEL, perhaps using more than one register type, this function
5611 returns the number of bytes used by the first element of the PARALLEL. */
5613 static int
5614 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5615 tree type, bool named)
5617 int ret = 0;
5618 int align_words;
5620 if (DEFAULT_ABI == ABI_V4)
5621 return 0;
5623 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
5624 && cum->nargs_prototype >= 0)
5625 return 0;
5627 /* In this complicated case we just disable the partial_nregs code. */
5628 if (rs6000_darwin64_abi && mode == BLKmode
5629 && TREE_CODE (type) == RECORD_TYPE
5630 && int_size_in_bytes (type) > 0)
5631 return 0;
5633 align_words = rs6000_parm_start (mode, type, cum->words);
5635 if (USE_FP_FOR_ARG_P (cum, mode, type))
5637 /* If we are passing this arg in the fixed parameter save area
5638 (gprs or memory) as well as fprs, then this function should
5639 return the number of partial bytes passed in the parameter
5640 save area rather than partial bytes passed in fprs. */
5641 if (type
5642 && (cum->nargs_prototype <= 0
5643 || (DEFAULT_ABI == ABI_AIX
5644 && TARGET_XL_COMPAT
5645 && align_words >= GP_ARG_NUM_REG)))
5646 return 0;
5647 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
5648 > FP_ARG_MAX_REG + 1)
5649 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
5650 else if (cum->nargs_prototype >= 0)
5651 return 0;
5654 if (align_words < GP_ARG_NUM_REG
5655 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
5656 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
5658 if (ret != 0 && TARGET_DEBUG_ARG)
5659 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
5661 return ret;
5664 /* A C expression that indicates when an argument must be passed by
5665 reference. If nonzero for an argument, a copy of that argument is
5666 made in memory and a pointer to the argument is passed instead of
5667 the argument itself. The pointer is passed in whatever way is
5668 appropriate for passing a pointer to that type.
5670 Under V.4, aggregates and long double are passed by reference.
5672 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5673 reference unless the AltiVec vector extension ABI is in force.
5675 As an extension to all ABIs, variable sized types are passed by
5676 reference. */
5678 static bool
5679 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5680 enum machine_mode mode, tree type,
5681 bool named ATTRIBUTE_UNUSED)
5683 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
5685 if (TARGET_DEBUG_ARG)
5686 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
5687 return 1;
5690 if (!type)
5691 return 0;
5693 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
5695 if (TARGET_DEBUG_ARG)
5696 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
5697 return 1;
5700 if (int_size_in_bytes (type) < 0)
5702 if (TARGET_DEBUG_ARG)
5703 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
5704 return 1;
5707 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5708 modes only exist for GCC vector types if -maltivec. */
5709 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
5711 if (TARGET_DEBUG_ARG)
5712 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
5713 return 1;
5716 /* Pass synthetic vectors in memory. */
5717 if (TREE_CODE (type) == VECTOR_TYPE
5718 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
5720 static bool warned_for_pass_big_vectors = false;
5721 if (TARGET_DEBUG_ARG)
5722 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
5723 if (!warned_for_pass_big_vectors)
5725 warning (0, "GCC vector passed by reference: "
5726 "non-standard ABI extension with no compatibility guarantee");
5727 warned_for_pass_big_vectors = true;
5729 return 1;
5732 return 0;
5735 static void
5736 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
5738 int i;
5739 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
5741 if (nregs == 0)
5742 return;
5744 for (i = 0; i < nregs; i++)
5746 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
5747 if (reload_completed)
5749 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
5750 tem = NULL_RTX;
5751 else
5752 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
5753 i * GET_MODE_SIZE (reg_mode));
5755 else
5756 tem = replace_equiv_address (tem, XEXP (tem, 0));
5758 gcc_assert (tem);
5760 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
5764 /* Perform any needed actions needed for a function that is receiving a
5765 variable number of arguments.
5767 CUM is as above.
5769 MODE and TYPE are the mode and type of the current parameter.
5771 PRETEND_SIZE is a variable that should be set to the amount of stack
5772 that must be pushed by the prolog to pretend that our caller pushed
5775 Normally, this macro will push all remaining incoming registers on the
5776 stack and set PRETEND_SIZE to the length of the registers pushed. */
5778 static void
5779 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5780 tree type, int *pretend_size ATTRIBUTE_UNUSED,
5781 int no_rtl)
5783 CUMULATIVE_ARGS next_cum;
5784 int reg_size = TARGET_32BIT ? 4 : 8;
5785 rtx save_area = NULL_RTX, mem;
5786 int first_reg_offset, set;
5788 /* Skip the last named argument. */
5789 next_cum = *cum;
5790 function_arg_advance (&next_cum, mode, type, 1, 0);
5792 if (DEFAULT_ABI == ABI_V4)
5794 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
5796 if (! no_rtl)
5798 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
5799 HOST_WIDE_INT offset = 0;
5801 /* Try to optimize the size of the varargs save area.
5802 The ABI requires that ap.reg_save_area is doubleword
5803 aligned, but we don't need to allocate space for all
5804 the bytes, only those to which we actually will save
5805 anything. */
5806 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
5807 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
5808 if (TARGET_HARD_FLOAT && TARGET_FPRS
5809 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5810 && cfun->va_list_fpr_size)
5812 if (gpr_reg_num)
5813 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
5814 * UNITS_PER_FP_WORD;
5815 if (cfun->va_list_fpr_size
5816 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5817 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
5818 else
5819 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5820 * UNITS_PER_FP_WORD;
5822 if (gpr_reg_num)
5824 offset = -((first_reg_offset * reg_size) & ~7);
5825 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
5827 gpr_reg_num = cfun->va_list_gpr_size;
5828 if (reg_size == 4 && (first_reg_offset & 1))
5829 gpr_reg_num++;
5831 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
5833 else if (fpr_size)
5834 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
5835 * UNITS_PER_FP_WORD
5836 - (int) (GP_ARG_NUM_REG * reg_size);
5838 if (gpr_size + fpr_size)
5840 rtx reg_save_area
5841 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
5842 gcc_assert (GET_CODE (reg_save_area) == MEM);
5843 reg_save_area = XEXP (reg_save_area, 0);
5844 if (GET_CODE (reg_save_area) == PLUS)
5846 gcc_assert (XEXP (reg_save_area, 0)
5847 == virtual_stack_vars_rtx);
5848 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
5849 offset += INTVAL (XEXP (reg_save_area, 1));
5851 else
5852 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
5855 cfun->machine->varargs_save_offset = offset;
5856 save_area = plus_constant (virtual_stack_vars_rtx, offset);
5859 else
5861 first_reg_offset = next_cum.words;
5862 save_area = virtual_incoming_args_rtx;
5864 if (targetm.calls.must_pass_in_stack (mode, type))
5865 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
5868 set = get_varargs_alias_set ();
5869 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
5870 && cfun->va_list_gpr_size)
5872 int nregs = GP_ARG_NUM_REG - first_reg_offset;
5874 if (va_list_gpr_counter_field)
5876 /* V4 va_list_gpr_size counts number of registers needed. */
5877 if (nregs > cfun->va_list_gpr_size)
5878 nregs = cfun->va_list_gpr_size;
5880 else
5882 /* char * va_list instead counts number of bytes needed. */
5883 if (nregs > cfun->va_list_gpr_size / reg_size)
5884 nregs = cfun->va_list_gpr_size / reg_size;
5887 mem = gen_rtx_MEM (BLKmode,
5888 plus_constant (save_area,
5889 first_reg_offset * reg_size));
5890 MEM_NOTRAP_P (mem) = 1;
5891 set_mem_alias_set (mem, set);
5892 set_mem_align (mem, BITS_PER_WORD);
5894 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
5895 nregs);
5898 /* Save FP registers if needed. */
5899 if (DEFAULT_ABI == ABI_V4
5900 && TARGET_HARD_FLOAT && TARGET_FPRS
5901 && ! no_rtl
5902 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5903 && cfun->va_list_fpr_size)
5905 int fregno = next_cum.fregno, nregs;
5906 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
5907 rtx lab = gen_label_rtx ();
5908 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
5909 * UNITS_PER_FP_WORD);
5911 emit_jump_insn
5912 (gen_rtx_SET (VOIDmode,
5913 pc_rtx,
5914 gen_rtx_IF_THEN_ELSE (VOIDmode,
5915 gen_rtx_NE (VOIDmode, cr1,
5916 const0_rtx),
5917 gen_rtx_LABEL_REF (VOIDmode, lab),
5918 pc_rtx)));
5920 for (nregs = 0;
5921 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
5922 fregno++, off += UNITS_PER_FP_WORD, nregs++)
5924 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
5925 MEM_NOTRAP_P (mem) = 1;
5926 set_mem_alias_set (mem, set);
5927 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
5928 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
5931 emit_label (lab);
5935 /* Create the va_list data type. */
5937 static tree
5938 rs6000_build_builtin_va_list (void)
5940 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
5942 /* For AIX, prefer 'char *' because that's what the system
5943 header files like. */
5944 if (DEFAULT_ABI != ABI_V4)
5945 return build_pointer_type (char_type_node);
5947 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5948 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5950 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
5951 unsigned_char_type_node);
5952 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
5953 unsigned_char_type_node);
5954 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
5955 every user file. */
5956 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
5957 short_unsigned_type_node);
5958 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
5959 ptr_type_node);
5960 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
5961 ptr_type_node);
5963 va_list_gpr_counter_field = f_gpr;
5964 va_list_fpr_counter_field = f_fpr;
5966 DECL_FIELD_CONTEXT (f_gpr) = record;
5967 DECL_FIELD_CONTEXT (f_fpr) = record;
5968 DECL_FIELD_CONTEXT (f_res) = record;
5969 DECL_FIELD_CONTEXT (f_ovf) = record;
5970 DECL_FIELD_CONTEXT (f_sav) = record;
5972 TREE_CHAIN (record) = type_decl;
5973 TYPE_NAME (record) = type_decl;
5974 TYPE_FIELDS (record) = f_gpr;
5975 TREE_CHAIN (f_gpr) = f_fpr;
5976 TREE_CHAIN (f_fpr) = f_res;
5977 TREE_CHAIN (f_res) = f_ovf;
5978 TREE_CHAIN (f_ovf) = f_sav;
5980 layout_type (record);
5982 /* The correct type is an array type of one element. */
5983 return build_array_type (record, build_index_type (size_zero_node));
5986 /* Implement va_start. */
5988 void
5989 rs6000_va_start (tree valist, rtx nextarg)
5991 HOST_WIDE_INT words, n_gpr, n_fpr;
5992 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
5993 tree gpr, fpr, ovf, sav, t;
5995 /* Only SVR4 needs something special. */
5996 if (DEFAULT_ABI != ABI_V4)
5998 std_expand_builtin_va_start (valist, nextarg);
5999 return;
6002 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6003 f_fpr = TREE_CHAIN (f_gpr);
6004 f_res = TREE_CHAIN (f_fpr);
6005 f_ovf = TREE_CHAIN (f_res);
6006 f_sav = TREE_CHAIN (f_ovf);
6008 valist = build_va_arg_indirect_ref (valist);
6009 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6010 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6011 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6012 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6014 /* Count number of gp and fp argument registers used. */
6015 words = current_function_args_info.words;
6016 n_gpr = MIN (current_function_args_info.sysv_gregno - GP_ARG_MIN_REG,
6017 GP_ARG_NUM_REG);
6018 n_fpr = MIN (current_function_args_info.fregno - FP_ARG_MIN_REG,
6019 FP_ARG_NUM_REG);
6021 if (TARGET_DEBUG_ARG)
6022 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
6023 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
6024 words, n_gpr, n_fpr);
6026 if (cfun->va_list_gpr_size)
6028 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr,
6029 build_int_cst (NULL_TREE, n_gpr));
6030 TREE_SIDE_EFFECTS (t) = 1;
6031 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6034 if (cfun->va_list_fpr_size)
6036 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr,
6037 build_int_cst (NULL_TREE, n_fpr));
6038 TREE_SIDE_EFFECTS (t) = 1;
6039 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6042 /* Find the overflow area. */
6043 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6044 if (words != 0)
6045 t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t,
6046 build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
6047 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6048 TREE_SIDE_EFFECTS (t) = 1;
6049 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6051 /* If there were no va_arg invocations, don't set up the register
6052 save area. */
6053 if (!cfun->va_list_gpr_size
6054 && !cfun->va_list_fpr_size
6055 && n_gpr < GP_ARG_NUM_REG
6056 && n_fpr < FP_ARG_V4_MAX_REG)
6057 return;
6059 /* Find the register save area. */
6060 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
6061 if (cfun->machine->varargs_save_offset)
6062 t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
6063 build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
6064 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
6065 TREE_SIDE_EFFECTS (t) = 1;
6066 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6069 /* Implement va_arg. */
6071 tree
6072 rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
6074 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6075 tree gpr, fpr, ovf, sav, reg, t, u;
6076 int size, rsize, n_reg, sav_ofs, sav_scale;
6077 tree lab_false, lab_over, addr;
6078 int align;
6079 tree ptrtype = build_pointer_type (type);
6081 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
6083 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
6084 return build_va_arg_indirect_ref (t);
6087 if (DEFAULT_ABI != ABI_V4)
6089 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
6091 tree elem_type = TREE_TYPE (type);
6092 enum machine_mode elem_mode = TYPE_MODE (elem_type);
6093 int elem_size = GET_MODE_SIZE (elem_mode);
6095 if (elem_size < UNITS_PER_WORD)
6097 tree real_part, imag_part;
6098 tree post = NULL_TREE;
6100 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6101 &post);
6102 /* Copy the value into a temporary, lest the formal temporary
6103 be reused out from under us. */
6104 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
6105 append_to_statement_list (post, pre_p);
6107 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6108 post_p);
6110 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
6114 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6117 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6118 f_fpr = TREE_CHAIN (f_gpr);
6119 f_res = TREE_CHAIN (f_fpr);
6120 f_ovf = TREE_CHAIN (f_res);
6121 f_sav = TREE_CHAIN (f_ovf);
6123 valist = build_va_arg_indirect_ref (valist);
6124 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6125 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6126 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6127 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6129 size = int_size_in_bytes (type);
6130 rsize = (size + 3) / 4;
6131 align = 1;
6133 if (TARGET_HARD_FLOAT && TARGET_FPRS
6134 && (TYPE_MODE (type) == SFmode
6135 || TYPE_MODE (type) == DFmode
6136 || TYPE_MODE (type) == TFmode))
6138 /* FP args go in FP registers, if present. */
6139 reg = fpr;
6140 n_reg = (size + 7) / 8;
6141 sav_ofs = 8*4;
6142 sav_scale = 8;
6143 if (TYPE_MODE (type) != SFmode)
6144 align = 8;
6146 else
6148 /* Otherwise into GP registers. */
6149 reg = gpr;
6150 n_reg = rsize;
6151 sav_ofs = 0;
6152 sav_scale = 4;
6153 if (n_reg == 2)
6154 align = 8;
6157 /* Pull the value out of the saved registers.... */
6159 lab_over = NULL;
6160 addr = create_tmp_var (ptr_type_node, "addr");
6161 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
6163 /* AltiVec vectors never go in registers when -mabi=altivec. */
6164 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6165 align = 16;
6166 else
6168 lab_false = create_artificial_label ();
6169 lab_over = create_artificial_label ();
6171 /* Long long and SPE vectors are aligned in the registers.
6172 As are any other 2 gpr item such as complex int due to a
6173 historical mistake. */
6174 u = reg;
6175 if (n_reg == 2 && reg == gpr)
6177 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
6178 size_int (n_reg - 1));
6179 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
6182 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
6183 t = build2 (GE_EXPR, boolean_type_node, u, t);
6184 u = build1 (GOTO_EXPR, void_type_node, lab_false);
6185 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
6186 gimplify_and_add (t, pre_p);
6188 t = sav;
6189 if (sav_ofs)
6190 t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
6192 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
6193 u = build1 (CONVERT_EXPR, integer_type_node, u);
6194 u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
6195 t = build2 (PLUS_EXPR, ptr_type_node, t, u);
6197 t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6198 gimplify_and_add (t, pre_p);
6200 t = build1 (GOTO_EXPR, void_type_node, lab_over);
6201 gimplify_and_add (t, pre_p);
6203 t = build1 (LABEL_EXPR, void_type_node, lab_false);
6204 append_to_statement_list (t, pre_p);
6206 if ((n_reg == 2 && reg != gpr) || n_reg > 2)
6208 /* Ensure that we don't find any more args in regs.
6209 Alignment has taken care of the n_reg == 2 gpr case. */
6210 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (reg), reg, size_int (8));
6211 gimplify_and_add (t, pre_p);
6215 /* ... otherwise out of the overflow area. */
6217 /* Care for on-stack alignment if needed. */
6218 t = ovf;
6219 if (align != 1)
6221 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
6222 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
6223 build_int_cst (NULL_TREE, -align));
6225 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
6227 u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6228 gimplify_and_add (u, pre_p);
6230 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
6231 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6232 gimplify_and_add (t, pre_p);
6234 if (lab_over)
6236 t = build1 (LABEL_EXPR, void_type_node, lab_over);
6237 append_to_statement_list (t, pre_p);
6240 if (STRICT_ALIGNMENT
6241 && (TYPE_ALIGN (type)
6242 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
6244 /* The value (of type complex double, for example) may not be
6245 aligned in memory in the saved registers, so copy via a
6246 temporary. (This is the same code as used for SPARC.) */
6247 tree tmp = create_tmp_var (type, "va_arg_tmp");
6248 tree dest_addr = build_fold_addr_expr (tmp);
6250 tree copy = build_function_call_expr
6251 (implicit_built_in_decls[BUILT_IN_MEMCPY],
6252 tree_cons (NULL_TREE, dest_addr,
6253 tree_cons (NULL_TREE, addr,
6254 tree_cons (NULL_TREE, size_int (rsize * 4),
6255 NULL_TREE))));
6257 gimplify_and_add (copy, pre_p);
6258 addr = dest_addr;
6261 addr = fold_convert (ptrtype, addr);
6262 return build_va_arg_indirect_ref (addr);
6265 /* Builtins. */
6267 static void
6268 def_builtin (int mask, const char *name, tree type, int code)
6270 if (mask & target_flags)
6272 if (rs6000_builtin_decls[code])
6273 abort ();
6275 rs6000_builtin_decls[code] =
6276 add_builtin_function (name, type, code, BUILT_IN_MD,
6277 NULL, NULL_TREE);
6281 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6283 static const struct builtin_description bdesc_3arg[] =
6285 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
6286 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
6287 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
6288 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
6289 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
6290 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
6291 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
6292 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
6293 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
6294 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
6295 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
6296 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
6297 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
6298 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
6299 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
6300 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
6301 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
6302 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
6303 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
6304 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
6305 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
6306 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
6307 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
6309 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
6310 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
6311 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
6312 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
6313 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
6314 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
6315 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
6316 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
6317 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
6318 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
6319 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
6320 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
6321 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
6322 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
6323 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
6326 /* DST operations: void foo (void *, const int, const char). */
6328 static const struct builtin_description bdesc_dst[] =
6330 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
6331 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
6332 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
6333 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
6335 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
6336 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
6337 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
6338 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
6341 /* Simple binary operations: VECc = foo (VECa, VECb). */
6343 static struct builtin_description bdesc_2arg[] =
6345 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
6346 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
6347 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
6348 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
6349 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
6350 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
6351 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
6352 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
6353 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
6354 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
6355 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
6356 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
6357 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
6358 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
6359 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
6360 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
6361 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
6362 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
6363 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
6364 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
6365 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
6366 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
6367 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
6368 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
6369 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
6370 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
6371 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
6372 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
6373 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
6374 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
6375 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
6376 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
6377 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
6378 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
6379 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
6380 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
6381 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
6382 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
6383 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
6384 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
6385 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
6386 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
6387 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
6388 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
6389 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
6390 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
6391 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
6392 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
6393 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
6394 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
6395 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
6396 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
6397 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
6398 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
6399 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
6400 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
6401 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
6402 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
6403 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
6404 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
6405 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
6406 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
6407 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
6408 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
6409 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
6410 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
6411 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
6412 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
6413 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
6414 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
6415 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
6416 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
6417 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
6418 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
6419 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
6420 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
6421 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
6422 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
6423 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
6424 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
6425 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
6426 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
6427 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
6428 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
6429 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
6430 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
6431 { MASK_ALTIVEC, CODE_FOR_lshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
6432 { MASK_ALTIVEC, CODE_FOR_lshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
6433 { MASK_ALTIVEC, CODE_FOR_lshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
6434 { MASK_ALTIVEC, CODE_FOR_ashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
6435 { MASK_ALTIVEC, CODE_FOR_ashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
6436 { MASK_ALTIVEC, CODE_FOR_ashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
6437 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
6438 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
6439 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
6440 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
6441 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
6442 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
6443 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
6444 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
6445 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
6446 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
6447 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
6448 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
6449 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
6450 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
6451 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
6452 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
6453 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
6454 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
6455 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
6457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
6458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
6459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
6460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
6461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
6462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
6463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
6464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
6465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
6466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
6467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
6468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
6469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
6470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
6471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
6472 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
6473 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
6474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
6475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
6476 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
6477 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
6478 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
6479 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
6480 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
6481 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
6482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
6483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
6484 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
6485 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
6486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
6487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
6488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
6489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
6490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
6491 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
6492 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
6493 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
6494 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
6495 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
6496 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
6497 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
6498 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
6499 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
6500 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
6501 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
6502 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
6503 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
6504 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
6505 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
6506 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
6507 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
6508 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
6509 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
6510 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
6511 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
6512 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
6513 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
6514 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
6515 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
6516 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
6517 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
6518 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
6519 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
6520 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
6521 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
6522 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
6523 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
6524 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
6525 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
6526 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
6527 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
6528 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
6529 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
6530 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
6531 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
6532 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
6533 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
6534 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
6535 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
6536 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
6537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
6538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
6539 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
6540 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
6541 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
6542 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
6543 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
6544 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
6545 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
6546 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
6547 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
6548 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
6549 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
6550 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
6551 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
6552 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
6553 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
6554 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
6555 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
6556 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
6557 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
6558 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
6559 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
6560 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
6561 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
6562 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
6563 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
6564 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
6565 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
6566 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
6567 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
6568 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
6569 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
6570 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
6571 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
6572 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
6573 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
6574 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
6575 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
6576 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
6577 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
6578 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
6579 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
6580 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
6581 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
6582 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
6583 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
6585 /* Place holder, leave as first spe builtin. */
6586 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
6587 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
6588 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
6589 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
6590 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
6591 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
6592 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
6593 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
6594 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
6595 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
6596 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
6597 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
6598 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
6599 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
6600 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
6601 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
6602 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
6603 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
6604 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
6605 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
6606 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
6607 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
6608 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
6609 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
6610 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
6611 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
6612 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
6613 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
6614 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
6615 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
6616 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
6617 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
6618 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
6619 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
6620 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
6621 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
6622 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
6623 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
6624 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
6625 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
6626 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
6627 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
6628 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
6629 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
6630 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
6631 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
6632 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
6633 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
6634 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
6635 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
6636 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
6637 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
6638 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
6639 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
6640 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
6641 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
6642 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
6643 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
6644 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
6645 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
6646 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
6647 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
6648 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
6649 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
6650 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
6651 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
6652 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
6653 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
6654 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
6655 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
6656 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
6657 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
6658 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
6659 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
6660 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
6661 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
6662 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
6663 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
6664 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
6665 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
6666 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
6667 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
6668 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
6669 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
6670 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
6671 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
6672 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
6673 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
6674 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
6675 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
6676 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
6677 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
6678 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
6679 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
6680 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
6681 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
6682 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
6683 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
6684 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
6685 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
6686 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
6687 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
6688 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
6689 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
6690 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
6691 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
6692 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
6693 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
6694 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
6696 /* SPE binary operations expecting a 5-bit unsigned literal. */
6697 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
6699 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
6700 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
6701 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
6702 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
6703 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
6704 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
6705 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
6706 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
6707 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
6708 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
6709 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
6710 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
6711 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
6712 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
6713 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
6714 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
6715 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
6716 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
6717 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
6718 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
6719 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
6720 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
6721 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
6722 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
6723 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
6724 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
6726 /* Place-holder. Leave as last binary SPE builtin. */
6727 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
6730 /* AltiVec predicates. */
6732 struct builtin_description_predicates
6734 const unsigned int mask;
6735 const enum insn_code icode;
6736 const char *opcode;
6737 const char *const name;
6738 const enum rs6000_builtins code;
6741 static const struct builtin_description_predicates bdesc_altivec_preds[] =
6743 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
6744 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
6745 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
6746 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
6747 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
6748 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
6749 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
6750 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
6751 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
6752 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
6753 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
6754 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
6755 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
6757 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
6758 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
6759 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
6762 /* SPE predicates. */
6763 static struct builtin_description bdesc_spe_predicates[] =
6765 /* Place-holder. Leave as first. */
6766 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
6767 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
6768 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
6769 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
6770 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
6771 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
6772 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
6773 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
6774 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
6775 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
6776 /* Place-holder. Leave as last. */
6777 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
6780 /* SPE evsel predicates. */
6781 static struct builtin_description bdesc_spe_evsel[] =
6783 /* Place-holder. Leave as first. */
6784 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
6785 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
6786 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
6787 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
6788 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
6789 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
6790 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
6791 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
6792 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
6793 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
6794 /* Place-holder. Leave as last. */
6795 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
6798 /* ABS* operations. */
6800 static const struct builtin_description bdesc_abs[] =
6802 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
6803 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
6804 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
6805 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
6806 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
6807 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
6808 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
6811 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6812 foo (VECa). */
6814 static struct builtin_description bdesc_1arg[] =
6816 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
6817 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
6818 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
6819 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
6820 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
6821 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
6822 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
6823 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
6824 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
6825 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
6826 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
6827 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
6828 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
6829 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
6830 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
6831 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
6832 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
6834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
6835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
6836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
6837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
6838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
6839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
6840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
6841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
6842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
6843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
6844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
6845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
6846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
6847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
6848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
6849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
6850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
6851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
6852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
6854 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6855 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6856 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
6857 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
6858 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
6859 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
6860 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
6861 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
6862 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
6863 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
6864 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
6865 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
6866 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
6867 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
6868 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
6869 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
6870 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
6871 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
6872 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
6873 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
6874 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
6875 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
6876 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
6877 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
6878 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
6879 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
6880 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
6881 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
6882 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
6883 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
6885 /* Place-holder. Leave as last unary SPE builtin. */
6886 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW }
6889 static rtx
6890 rs6000_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
6892 rtx pat;
6893 tree arg0 = TREE_VALUE (arglist);
6894 rtx op0 = expand_normal (arg0);
6895 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6896 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6898 if (icode == CODE_FOR_nothing)
6899 /* Builtin not supported on this processor. */
6900 return 0;
6902 /* If we got invalid arguments bail out before generating bad rtl. */
6903 if (arg0 == error_mark_node)
6904 return const0_rtx;
6906 if (icode == CODE_FOR_altivec_vspltisb
6907 || icode == CODE_FOR_altivec_vspltish
6908 || icode == CODE_FOR_altivec_vspltisw
6909 || icode == CODE_FOR_spe_evsplatfi
6910 || icode == CODE_FOR_spe_evsplati)
6912 /* Only allow 5-bit *signed* literals. */
6913 if (GET_CODE (op0) != CONST_INT
6914 || INTVAL (op0) > 15
6915 || INTVAL (op0) < -16)
6917 error ("argument 1 must be a 5-bit signed literal");
6918 return const0_rtx;
6922 if (target == 0
6923 || GET_MODE (target) != tmode
6924 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6925 target = gen_reg_rtx (tmode);
6927 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6928 op0 = copy_to_mode_reg (mode0, op0);
6930 pat = GEN_FCN (icode) (target, op0);
6931 if (! pat)
6932 return 0;
6933 emit_insn (pat);
6935 return target;
6938 static rtx
6939 altivec_expand_abs_builtin (enum insn_code icode, tree arglist, rtx target)
6941 rtx pat, scratch1, scratch2;
6942 tree arg0 = TREE_VALUE (arglist);
6943 rtx op0 = expand_normal (arg0);
6944 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6945 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6947 /* If we have invalid arguments, bail out before generating bad rtl. */
6948 if (arg0 == error_mark_node)
6949 return const0_rtx;
6951 if (target == 0
6952 || GET_MODE (target) != tmode
6953 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6954 target = gen_reg_rtx (tmode);
6956 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6957 op0 = copy_to_mode_reg (mode0, op0);
6959 scratch1 = gen_reg_rtx (mode0);
6960 scratch2 = gen_reg_rtx (mode0);
6962 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
6963 if (! pat)
6964 return 0;
6965 emit_insn (pat);
6967 return target;
6970 static rtx
6971 rs6000_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
6973 rtx pat;
6974 tree arg0 = TREE_VALUE (arglist);
6975 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6976 rtx op0 = expand_normal (arg0);
6977 rtx op1 = expand_normal (arg1);
6978 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6979 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6980 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6982 if (icode == CODE_FOR_nothing)
6983 /* Builtin not supported on this processor. */
6984 return 0;
6986 /* If we got invalid arguments bail out before generating bad rtl. */
6987 if (arg0 == error_mark_node || arg1 == error_mark_node)
6988 return const0_rtx;
6990 if (icode == CODE_FOR_altivec_vcfux
6991 || icode == CODE_FOR_altivec_vcfsx
6992 || icode == CODE_FOR_altivec_vctsxs
6993 || icode == CODE_FOR_altivec_vctuxs
6994 || icode == CODE_FOR_altivec_vspltb
6995 || icode == CODE_FOR_altivec_vsplth
6996 || icode == CODE_FOR_altivec_vspltw
6997 || icode == CODE_FOR_spe_evaddiw
6998 || icode == CODE_FOR_spe_evldd
6999 || icode == CODE_FOR_spe_evldh
7000 || icode == CODE_FOR_spe_evldw
7001 || icode == CODE_FOR_spe_evlhhesplat
7002 || icode == CODE_FOR_spe_evlhhossplat
7003 || icode == CODE_FOR_spe_evlhhousplat
7004 || icode == CODE_FOR_spe_evlwhe
7005 || icode == CODE_FOR_spe_evlwhos
7006 || icode == CODE_FOR_spe_evlwhou
7007 || icode == CODE_FOR_spe_evlwhsplat
7008 || icode == CODE_FOR_spe_evlwwsplat
7009 || icode == CODE_FOR_spe_evrlwi
7010 || icode == CODE_FOR_spe_evslwi
7011 || icode == CODE_FOR_spe_evsrwis
7012 || icode == CODE_FOR_spe_evsubifw
7013 || icode == CODE_FOR_spe_evsrwiu)
7015 /* Only allow 5-bit unsigned literals. */
7016 STRIP_NOPS (arg1);
7017 if (TREE_CODE (arg1) != INTEGER_CST
7018 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7020 error ("argument 2 must be a 5-bit unsigned literal");
7021 return const0_rtx;
7025 if (target == 0
7026 || GET_MODE (target) != tmode
7027 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7028 target = gen_reg_rtx (tmode);
7030 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7031 op0 = copy_to_mode_reg (mode0, op0);
7032 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7033 op1 = copy_to_mode_reg (mode1, op1);
7035 pat = GEN_FCN (icode) (target, op0, op1);
7036 if (! pat)
7037 return 0;
7038 emit_insn (pat);
7040 return target;
7043 static rtx
7044 altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
7045 tree arglist, rtx target)
7047 rtx pat, scratch;
7048 tree cr6_form = TREE_VALUE (arglist);
7049 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
7050 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7051 rtx op0 = expand_normal (arg0);
7052 rtx op1 = expand_normal (arg1);
7053 enum machine_mode tmode = SImode;
7054 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7055 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7056 int cr6_form_int;
7058 if (TREE_CODE (cr6_form) != INTEGER_CST)
7060 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7061 return const0_rtx;
7063 else
7064 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
7066 gcc_assert (mode0 == mode1);
7068 /* If we have invalid arguments, bail out before generating bad rtl. */
7069 if (arg0 == error_mark_node || arg1 == error_mark_node)
7070 return const0_rtx;
7072 if (target == 0
7073 || GET_MODE (target) != tmode
7074 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7075 target = gen_reg_rtx (tmode);
7077 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7078 op0 = copy_to_mode_reg (mode0, op0);
7079 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7080 op1 = copy_to_mode_reg (mode1, op1);
7082 scratch = gen_reg_rtx (mode0);
7084 pat = GEN_FCN (icode) (scratch, op0, op1,
7085 gen_rtx_SYMBOL_REF (Pmode, opcode));
7086 if (! pat)
7087 return 0;
7088 emit_insn (pat);
7090 /* The vec_any* and vec_all* predicates use the same opcodes for two
7091 different operations, but the bits in CR6 will be different
7092 depending on what information we want. So we have to play tricks
7093 with CR6 to get the right bits out.
7095 If you think this is disgusting, look at the specs for the
7096 AltiVec predicates. */
7098 switch (cr6_form_int)
7100 case 0:
7101 emit_insn (gen_cr6_test_for_zero (target));
7102 break;
7103 case 1:
7104 emit_insn (gen_cr6_test_for_zero_reverse (target));
7105 break;
7106 case 2:
7107 emit_insn (gen_cr6_test_for_lt (target));
7108 break;
7109 case 3:
7110 emit_insn (gen_cr6_test_for_lt_reverse (target));
7111 break;
7112 default:
7113 error ("argument 1 of __builtin_altivec_predicate is out of range");
7114 break;
7117 return target;
7120 static rtx
7121 altivec_expand_lv_builtin (enum insn_code icode, tree arglist, rtx target)
7123 rtx pat, addr;
7124 tree arg0 = TREE_VALUE (arglist);
7125 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7126 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7127 enum machine_mode mode0 = Pmode;
7128 enum machine_mode mode1 = Pmode;
7129 rtx op0 = expand_normal (arg0);
7130 rtx op1 = expand_normal (arg1);
7132 if (icode == CODE_FOR_nothing)
7133 /* Builtin not supported on this processor. */
7134 return 0;
7136 /* If we got invalid arguments bail out before generating bad rtl. */
7137 if (arg0 == error_mark_node || arg1 == error_mark_node)
7138 return const0_rtx;
7140 if (target == 0
7141 || GET_MODE (target) != tmode
7142 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7143 target = gen_reg_rtx (tmode);
7145 op1 = copy_to_mode_reg (mode1, op1);
7147 if (op0 == const0_rtx)
7149 addr = gen_rtx_MEM (tmode, op1);
7151 else
7153 op0 = copy_to_mode_reg (mode0, op0);
7154 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7157 pat = GEN_FCN (icode) (target, addr);
7159 if (! pat)
7160 return 0;
7161 emit_insn (pat);
7163 return target;
7166 static rtx
7167 spe_expand_stv_builtin (enum insn_code icode, tree arglist)
7169 tree arg0 = TREE_VALUE (arglist);
7170 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7171 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7172 rtx op0 = expand_normal (arg0);
7173 rtx op1 = expand_normal (arg1);
7174 rtx op2 = expand_normal (arg2);
7175 rtx pat;
7176 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
7177 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
7178 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
7180 /* Invalid arguments. Bail before doing anything stoopid! */
7181 if (arg0 == error_mark_node
7182 || arg1 == error_mark_node
7183 || arg2 == error_mark_node)
7184 return const0_rtx;
7186 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
7187 op0 = copy_to_mode_reg (mode2, op0);
7188 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
7189 op1 = copy_to_mode_reg (mode0, op1);
7190 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7191 op2 = copy_to_mode_reg (mode1, op2);
7193 pat = GEN_FCN (icode) (op1, op2, op0);
7194 if (pat)
7195 emit_insn (pat);
7196 return NULL_RTX;
7199 static rtx
7200 altivec_expand_stv_builtin (enum insn_code icode, tree arglist)
7202 tree arg0 = TREE_VALUE (arglist);
7203 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7204 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7205 rtx op0 = expand_normal (arg0);
7206 rtx op1 = expand_normal (arg1);
7207 rtx op2 = expand_normal (arg2);
7208 rtx pat, addr;
7209 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7210 enum machine_mode mode1 = Pmode;
7211 enum machine_mode mode2 = Pmode;
7213 /* Invalid arguments. Bail before doing anything stoopid! */
7214 if (arg0 == error_mark_node
7215 || arg1 == error_mark_node
7216 || arg2 == error_mark_node)
7217 return const0_rtx;
7219 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
7220 op0 = copy_to_mode_reg (tmode, op0);
7222 op2 = copy_to_mode_reg (mode2, op2);
7224 if (op1 == const0_rtx)
7226 addr = gen_rtx_MEM (tmode, op2);
7228 else
7230 op1 = copy_to_mode_reg (mode1, op1);
7231 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
7234 pat = GEN_FCN (icode) (addr, op0);
7235 if (pat)
7236 emit_insn (pat);
7237 return NULL_RTX;
7240 static rtx
7241 rs6000_expand_ternop_builtin (enum insn_code icode, tree arglist, rtx target)
7243 rtx pat;
7244 tree arg0 = TREE_VALUE (arglist);
7245 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7246 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7247 rtx op0 = expand_normal (arg0);
7248 rtx op1 = expand_normal (arg1);
7249 rtx op2 = expand_normal (arg2);
7250 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7251 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7252 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7253 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
7255 if (icode == CODE_FOR_nothing)
7256 /* Builtin not supported on this processor. */
7257 return 0;
7259 /* If we got invalid arguments bail out before generating bad rtl. */
7260 if (arg0 == error_mark_node
7261 || arg1 == error_mark_node
7262 || arg2 == error_mark_node)
7263 return const0_rtx;
7265 if (icode == CODE_FOR_altivec_vsldoi_v4sf
7266 || icode == CODE_FOR_altivec_vsldoi_v4si
7267 || icode == CODE_FOR_altivec_vsldoi_v8hi
7268 || icode == CODE_FOR_altivec_vsldoi_v16qi)
7270 /* Only allow 4-bit unsigned literals. */
7271 STRIP_NOPS (arg2);
7272 if (TREE_CODE (arg2) != INTEGER_CST
7273 || TREE_INT_CST_LOW (arg2) & ~0xf)
7275 error ("argument 3 must be a 4-bit unsigned literal");
7276 return const0_rtx;
7280 if (target == 0
7281 || GET_MODE (target) != tmode
7282 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7283 target = gen_reg_rtx (tmode);
7285 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7286 op0 = copy_to_mode_reg (mode0, op0);
7287 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7288 op1 = copy_to_mode_reg (mode1, op1);
7289 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
7290 op2 = copy_to_mode_reg (mode2, op2);
7292 pat = GEN_FCN (icode) (target, op0, op1, op2);
7293 if (! pat)
7294 return 0;
7295 emit_insn (pat);
7297 return target;
7300 /* Expand the lvx builtins. */
7301 static rtx
7302 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
7304 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7305 tree arglist = TREE_OPERAND (exp, 1);
7306 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7307 tree arg0;
7308 enum machine_mode tmode, mode0;
7309 rtx pat, op0;
7310 enum insn_code icode;
7312 switch (fcode)
7314 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
7315 icode = CODE_FOR_altivec_lvx_v16qi;
7316 break;
7317 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
7318 icode = CODE_FOR_altivec_lvx_v8hi;
7319 break;
7320 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
7321 icode = CODE_FOR_altivec_lvx_v4si;
7322 break;
7323 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
7324 icode = CODE_FOR_altivec_lvx_v4sf;
7325 break;
7326 default:
7327 *expandedp = false;
7328 return NULL_RTX;
7331 *expandedp = true;
7333 arg0 = TREE_VALUE (arglist);
7334 op0 = expand_normal (arg0);
7335 tmode = insn_data[icode].operand[0].mode;
7336 mode0 = insn_data[icode].operand[1].mode;
7338 if (target == 0
7339 || GET_MODE (target) != tmode
7340 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7341 target = gen_reg_rtx (tmode);
7343 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7344 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7346 pat = GEN_FCN (icode) (target, op0);
7347 if (! pat)
7348 return 0;
7349 emit_insn (pat);
7350 return target;
7353 /* Expand the stvx builtins. */
7354 static rtx
7355 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
7356 bool *expandedp)
7358 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7359 tree arglist = TREE_OPERAND (exp, 1);
7360 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7361 tree arg0, arg1;
7362 enum machine_mode mode0, mode1;
7363 rtx pat, op0, op1;
7364 enum insn_code icode;
7366 switch (fcode)
7368 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
7369 icode = CODE_FOR_altivec_stvx_v16qi;
7370 break;
7371 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
7372 icode = CODE_FOR_altivec_stvx_v8hi;
7373 break;
7374 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
7375 icode = CODE_FOR_altivec_stvx_v4si;
7376 break;
7377 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
7378 icode = CODE_FOR_altivec_stvx_v4sf;
7379 break;
7380 default:
7381 *expandedp = false;
7382 return NULL_RTX;
7385 arg0 = TREE_VALUE (arglist);
7386 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7387 op0 = expand_normal (arg0);
7388 op1 = expand_normal (arg1);
7389 mode0 = insn_data[icode].operand[0].mode;
7390 mode1 = insn_data[icode].operand[1].mode;
7392 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7393 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7394 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7395 op1 = copy_to_mode_reg (mode1, op1);
7397 pat = GEN_FCN (icode) (op0, op1);
7398 if (pat)
7399 emit_insn (pat);
7401 *expandedp = true;
7402 return NULL_RTX;
7405 /* Expand the dst builtins. */
7406 static rtx
7407 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
7408 bool *expandedp)
7410 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7411 tree arglist = TREE_OPERAND (exp, 1);
7412 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7413 tree arg0, arg1, arg2;
7414 enum machine_mode mode0, mode1, mode2;
7415 rtx pat, op0, op1, op2;
7416 struct builtin_description *d;
7417 size_t i;
7419 *expandedp = false;
7421 /* Handle DST variants. */
7422 d = (struct builtin_description *) bdesc_dst;
7423 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
7424 if (d->code == fcode)
7426 arg0 = TREE_VALUE (arglist);
7427 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7428 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7429 op0 = expand_normal (arg0);
7430 op1 = expand_normal (arg1);
7431 op2 = expand_normal (arg2);
7432 mode0 = insn_data[d->icode].operand[0].mode;
7433 mode1 = insn_data[d->icode].operand[1].mode;
7434 mode2 = insn_data[d->icode].operand[2].mode;
7436 /* Invalid arguments, bail out before generating bad rtl. */
7437 if (arg0 == error_mark_node
7438 || arg1 == error_mark_node
7439 || arg2 == error_mark_node)
7440 return const0_rtx;
7442 *expandedp = true;
7443 STRIP_NOPS (arg2);
7444 if (TREE_CODE (arg2) != INTEGER_CST
7445 || TREE_INT_CST_LOW (arg2) & ~0x3)
7447 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
7448 return const0_rtx;
7451 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
7452 op0 = copy_to_mode_reg (Pmode, op0);
7453 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
7454 op1 = copy_to_mode_reg (mode1, op1);
7456 pat = GEN_FCN (d->icode) (op0, op1, op2);
7457 if (pat != 0)
7458 emit_insn (pat);
7460 return NULL_RTX;
7463 return NULL_RTX;
7466 /* Expand vec_init builtin. */
7467 static rtx
7468 altivec_expand_vec_init_builtin (tree type, tree arglist, rtx target)
7470 enum machine_mode tmode = TYPE_MODE (type);
7471 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
7472 int i, n_elt = GET_MODE_NUNITS (tmode);
7473 rtvec v = rtvec_alloc (n_elt);
7475 gcc_assert (VECTOR_MODE_P (tmode));
7477 for (i = 0; i < n_elt; ++i, arglist = TREE_CHAIN (arglist))
7479 rtx x = expand_normal (TREE_VALUE (arglist));
7480 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
7483 gcc_assert (arglist == NULL);
7485 if (!target || !register_operand (target, tmode))
7486 target = gen_reg_rtx (tmode);
7488 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
7489 return target;
7492 /* Return the integer constant in ARG. Constrain it to be in the range
7493 of the subparts of VEC_TYPE; issue an error if not. */
7495 static int
7496 get_element_number (tree vec_type, tree arg)
7498 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
7500 if (!host_integerp (arg, 1)
7501 || (elt = tree_low_cst (arg, 1), elt > max))
7503 error ("selector must be an integer constant in the range 0..%wi", max);
7504 return 0;
7507 return elt;
7510 /* Expand vec_set builtin. */
7511 static rtx
7512 altivec_expand_vec_set_builtin (tree arglist)
7514 enum machine_mode tmode, mode1;
7515 tree arg0, arg1, arg2;
7516 int elt;
7517 rtx op0, op1;
7519 arg0 = TREE_VALUE (arglist);
7520 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7521 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7523 tmode = TYPE_MODE (TREE_TYPE (arg0));
7524 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7525 gcc_assert (VECTOR_MODE_P (tmode));
7527 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
7528 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
7529 elt = get_element_number (TREE_TYPE (arg0), arg2);
7531 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
7532 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
7534 op0 = force_reg (tmode, op0);
7535 op1 = force_reg (mode1, op1);
7537 rs6000_expand_vector_set (op0, op1, elt);
7539 return op0;
7542 /* Expand vec_ext builtin. */
7543 static rtx
7544 altivec_expand_vec_ext_builtin (tree arglist, rtx target)
7546 enum machine_mode tmode, mode0;
7547 tree arg0, arg1;
7548 int elt;
7549 rtx op0;
7551 arg0 = TREE_VALUE (arglist);
7552 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7554 op0 = expand_normal (arg0);
7555 elt = get_element_number (TREE_TYPE (arg0), arg1);
7557 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7558 mode0 = TYPE_MODE (TREE_TYPE (arg0));
7559 gcc_assert (VECTOR_MODE_P (mode0));
7561 op0 = force_reg (mode0, op0);
7563 if (optimize || !target || !register_operand (target, tmode))
7564 target = gen_reg_rtx (tmode);
7566 rs6000_expand_vector_extract (target, op0, elt);
7568 return target;
7571 /* Expand the builtin in EXP and store the result in TARGET. Store
7572 true in *EXPANDEDP if we found a builtin to expand. */
7573 static rtx
7574 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
7576 struct builtin_description *d;
7577 struct builtin_description_predicates *dp;
7578 size_t i;
7579 enum insn_code icode;
7580 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7581 tree arglist = TREE_OPERAND (exp, 1);
7582 tree arg0;
7583 rtx op0, pat;
7584 enum machine_mode tmode, mode0;
7585 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7587 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7588 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
7590 *expandedp = true;
7591 error ("unresolved overload for Altivec builtin %qF", fndecl);
7592 return const0_rtx;
7595 target = altivec_expand_ld_builtin (exp, target, expandedp);
7596 if (*expandedp)
7597 return target;
7599 target = altivec_expand_st_builtin (exp, target, expandedp);
7600 if (*expandedp)
7601 return target;
7603 target = altivec_expand_dst_builtin (exp, target, expandedp);
7604 if (*expandedp)
7605 return target;
7607 *expandedp = true;
7609 switch (fcode)
7611 case ALTIVEC_BUILTIN_STVX:
7612 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
7613 case ALTIVEC_BUILTIN_STVEBX:
7614 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
7615 case ALTIVEC_BUILTIN_STVEHX:
7616 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
7617 case ALTIVEC_BUILTIN_STVEWX:
7618 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
7619 case ALTIVEC_BUILTIN_STVXL:
7620 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
7622 case ALTIVEC_BUILTIN_MFVSCR:
7623 icode = CODE_FOR_altivec_mfvscr;
7624 tmode = insn_data[icode].operand[0].mode;
7626 if (target == 0
7627 || GET_MODE (target) != tmode
7628 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7629 target = gen_reg_rtx (tmode);
7631 pat = GEN_FCN (icode) (target);
7632 if (! pat)
7633 return 0;
7634 emit_insn (pat);
7635 return target;
7637 case ALTIVEC_BUILTIN_MTVSCR:
7638 icode = CODE_FOR_altivec_mtvscr;
7639 arg0 = TREE_VALUE (arglist);
7640 op0 = expand_normal (arg0);
7641 mode0 = insn_data[icode].operand[0].mode;
7643 /* If we got invalid arguments bail out before generating bad rtl. */
7644 if (arg0 == error_mark_node)
7645 return const0_rtx;
7647 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7648 op0 = copy_to_mode_reg (mode0, op0);
7650 pat = GEN_FCN (icode) (op0);
7651 if (pat)
7652 emit_insn (pat);
7653 return NULL_RTX;
7655 case ALTIVEC_BUILTIN_DSSALL:
7656 emit_insn (gen_altivec_dssall ());
7657 return NULL_RTX;
7659 case ALTIVEC_BUILTIN_DSS:
7660 icode = CODE_FOR_altivec_dss;
7661 arg0 = TREE_VALUE (arglist);
7662 STRIP_NOPS (arg0);
7663 op0 = expand_normal (arg0);
7664 mode0 = insn_data[icode].operand[0].mode;
7666 /* If we got invalid arguments bail out before generating bad rtl. */
7667 if (arg0 == error_mark_node)
7668 return const0_rtx;
7670 if (TREE_CODE (arg0) != INTEGER_CST
7671 || TREE_INT_CST_LOW (arg0) & ~0x3)
7673 error ("argument to dss must be a 2-bit unsigned literal");
7674 return const0_rtx;
7677 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7678 op0 = copy_to_mode_reg (mode0, op0);
7680 emit_insn (gen_altivec_dss (op0));
7681 return NULL_RTX;
7683 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
7684 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
7685 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
7686 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
7687 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), arglist, target);
7689 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
7690 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
7691 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
7692 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
7693 return altivec_expand_vec_set_builtin (arglist);
7695 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
7696 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
7697 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
7698 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
7699 return altivec_expand_vec_ext_builtin (arglist, target);
7701 default:
7702 break;
7703 /* Fall through. */
7706 /* Expand abs* operations. */
7707 d = (struct builtin_description *) bdesc_abs;
7708 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
7709 if (d->code == fcode)
7710 return altivec_expand_abs_builtin (d->icode, arglist, target);
7712 /* Expand the AltiVec predicates. */
7713 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
7714 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
7715 if (dp->code == fcode)
7716 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
7717 arglist, target);
7719 /* LV* are funky. We initialized them differently. */
7720 switch (fcode)
7722 case ALTIVEC_BUILTIN_LVSL:
7723 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
7724 arglist, target);
7725 case ALTIVEC_BUILTIN_LVSR:
7726 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
7727 arglist, target);
7728 case ALTIVEC_BUILTIN_LVEBX:
7729 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
7730 arglist, target);
7731 case ALTIVEC_BUILTIN_LVEHX:
7732 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
7733 arglist, target);
7734 case ALTIVEC_BUILTIN_LVEWX:
7735 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
7736 arglist, target);
7737 case ALTIVEC_BUILTIN_LVXL:
7738 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
7739 arglist, target);
7740 case ALTIVEC_BUILTIN_LVX:
7741 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
7742 arglist, target);
7743 default:
7744 break;
7745 /* Fall through. */
7748 *expandedp = false;
7749 return NULL_RTX;
7752 /* Binops that need to be initialized manually, but can be expanded
7753 automagically by rs6000_expand_binop_builtin. */
7754 static struct builtin_description bdesc_2arg_spe[] =
7756 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
7757 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
7758 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
7759 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
7760 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
7761 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
7762 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
7763 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
7764 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
7765 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
7766 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
7767 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
7768 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
7769 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
7770 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
7771 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
7772 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
7773 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
7774 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
7775 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
7776 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
7777 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
7780 /* Expand the builtin in EXP and store the result in TARGET. Store
7781 true in *EXPANDEDP if we found a builtin to expand.
7783 This expands the SPE builtins that are not simple unary and binary
7784 operations. */
7785 static rtx
7786 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
7788 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7789 tree arglist = TREE_OPERAND (exp, 1);
7790 tree arg1, arg0;
7791 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7792 enum insn_code icode;
7793 enum machine_mode tmode, mode0;
7794 rtx pat, op0;
7795 struct builtin_description *d;
7796 size_t i;
7798 *expandedp = true;
7800 /* Syntax check for a 5-bit unsigned immediate. */
7801 switch (fcode)
7803 case SPE_BUILTIN_EVSTDD:
7804 case SPE_BUILTIN_EVSTDH:
7805 case SPE_BUILTIN_EVSTDW:
7806 case SPE_BUILTIN_EVSTWHE:
7807 case SPE_BUILTIN_EVSTWHO:
7808 case SPE_BUILTIN_EVSTWWE:
7809 case SPE_BUILTIN_EVSTWWO:
7810 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7811 if (TREE_CODE (arg1) != INTEGER_CST
7812 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7814 error ("argument 2 must be a 5-bit unsigned literal");
7815 return const0_rtx;
7817 break;
7818 default:
7819 break;
7822 /* The evsplat*i instructions are not quite generic. */
7823 switch (fcode)
7825 case SPE_BUILTIN_EVSPLATFI:
7826 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
7827 arglist, target);
7828 case SPE_BUILTIN_EVSPLATI:
7829 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
7830 arglist, target);
7831 default:
7832 break;
7835 d = (struct builtin_description *) bdesc_2arg_spe;
7836 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
7837 if (d->code == fcode)
7838 return rs6000_expand_binop_builtin (d->icode, arglist, target);
7840 d = (struct builtin_description *) bdesc_spe_predicates;
7841 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
7842 if (d->code == fcode)
7843 return spe_expand_predicate_builtin (d->icode, arglist, target);
7845 d = (struct builtin_description *) bdesc_spe_evsel;
7846 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
7847 if (d->code == fcode)
7848 return spe_expand_evsel_builtin (d->icode, arglist, target);
7850 switch (fcode)
7852 case SPE_BUILTIN_EVSTDDX:
7853 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
7854 case SPE_BUILTIN_EVSTDHX:
7855 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
7856 case SPE_BUILTIN_EVSTDWX:
7857 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
7858 case SPE_BUILTIN_EVSTWHEX:
7859 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
7860 case SPE_BUILTIN_EVSTWHOX:
7861 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
7862 case SPE_BUILTIN_EVSTWWEX:
7863 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
7864 case SPE_BUILTIN_EVSTWWOX:
7865 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
7866 case SPE_BUILTIN_EVSTDD:
7867 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
7868 case SPE_BUILTIN_EVSTDH:
7869 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
7870 case SPE_BUILTIN_EVSTDW:
7871 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
7872 case SPE_BUILTIN_EVSTWHE:
7873 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
7874 case SPE_BUILTIN_EVSTWHO:
7875 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
7876 case SPE_BUILTIN_EVSTWWE:
7877 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
7878 case SPE_BUILTIN_EVSTWWO:
7879 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
7880 case SPE_BUILTIN_MFSPEFSCR:
7881 icode = CODE_FOR_spe_mfspefscr;
7882 tmode = insn_data[icode].operand[0].mode;
7884 if (target == 0
7885 || GET_MODE (target) != tmode
7886 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7887 target = gen_reg_rtx (tmode);
7889 pat = GEN_FCN (icode) (target);
7890 if (! pat)
7891 return 0;
7892 emit_insn (pat);
7893 return target;
7894 case SPE_BUILTIN_MTSPEFSCR:
7895 icode = CODE_FOR_spe_mtspefscr;
7896 arg0 = TREE_VALUE (arglist);
7897 op0 = expand_normal (arg0);
7898 mode0 = insn_data[icode].operand[0].mode;
7900 if (arg0 == error_mark_node)
7901 return const0_rtx;
7903 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7904 op0 = copy_to_mode_reg (mode0, op0);
7906 pat = GEN_FCN (icode) (op0);
7907 if (pat)
7908 emit_insn (pat);
7909 return NULL_RTX;
7910 default:
7911 break;
7914 *expandedp = false;
7915 return NULL_RTX;
7918 static rtx
7919 spe_expand_predicate_builtin (enum insn_code icode, tree arglist, rtx target)
7921 rtx pat, scratch, tmp;
7922 tree form = TREE_VALUE (arglist);
7923 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
7924 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7925 rtx op0 = expand_normal (arg0);
7926 rtx op1 = expand_normal (arg1);
7927 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7928 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7929 int form_int;
7930 enum rtx_code code;
7932 if (TREE_CODE (form) != INTEGER_CST)
7934 error ("argument 1 of __builtin_spe_predicate must be a constant");
7935 return const0_rtx;
7937 else
7938 form_int = TREE_INT_CST_LOW (form);
7940 gcc_assert (mode0 == mode1);
7942 if (arg0 == error_mark_node || arg1 == error_mark_node)
7943 return const0_rtx;
7945 if (target == 0
7946 || GET_MODE (target) != SImode
7947 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
7948 target = gen_reg_rtx (SImode);
7950 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7951 op0 = copy_to_mode_reg (mode0, op0);
7952 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7953 op1 = copy_to_mode_reg (mode1, op1);
7955 scratch = gen_reg_rtx (CCmode);
7957 pat = GEN_FCN (icode) (scratch, op0, op1);
7958 if (! pat)
7959 return const0_rtx;
7960 emit_insn (pat);
7962 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
7963 _lower_. We use one compare, but look in different bits of the
7964 CR for each variant.
7966 There are 2 elements in each SPE simd type (upper/lower). The CR
7967 bits are set as follows:
7969 BIT0 | BIT 1 | BIT 2 | BIT 3
7970 U | L | (U | L) | (U & L)
7972 So, for an "all" relationship, BIT 3 would be set.
7973 For an "any" relationship, BIT 2 would be set. Etc.
7975 Following traditional nomenclature, these bits map to:
7977 BIT0 | BIT 1 | BIT 2 | BIT 3
7978 LT | GT | EQ | OV
7980 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
7983 switch (form_int)
7985 /* All variant. OV bit. */
7986 case 0:
7987 /* We need to get to the OV bit, which is the ORDERED bit. We
7988 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
7989 that's ugly and will make validate_condition_mode die.
7990 So let's just use another pattern. */
7991 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
7992 return target;
7993 /* Any variant. EQ bit. */
7994 case 1:
7995 code = EQ;
7996 break;
7997 /* Upper variant. LT bit. */
7998 case 2:
7999 code = LT;
8000 break;
8001 /* Lower variant. GT bit. */
8002 case 3:
8003 code = GT;
8004 break;
8005 default:
8006 error ("argument 1 of __builtin_spe_predicate is out of range");
8007 return const0_rtx;
8010 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8011 emit_move_insn (target, tmp);
8013 return target;
8016 /* The evsel builtins look like this:
8018 e = __builtin_spe_evsel_OP (a, b, c, d);
8020 and work like this:
8022 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8023 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8026 static rtx
8027 spe_expand_evsel_builtin (enum insn_code icode, tree arglist, rtx target)
8029 rtx pat, scratch;
8030 tree arg0 = TREE_VALUE (arglist);
8031 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8032 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8033 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
8034 rtx op0 = expand_normal (arg0);
8035 rtx op1 = expand_normal (arg1);
8036 rtx op2 = expand_normal (arg2);
8037 rtx op3 = expand_normal (arg3);
8038 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8039 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8041 gcc_assert (mode0 == mode1);
8043 if (arg0 == error_mark_node || arg1 == error_mark_node
8044 || arg2 == error_mark_node || arg3 == error_mark_node)
8045 return const0_rtx;
8047 if (target == 0
8048 || GET_MODE (target) != mode0
8049 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
8050 target = gen_reg_rtx (mode0);
8052 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8053 op0 = copy_to_mode_reg (mode0, op0);
8054 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
8055 op1 = copy_to_mode_reg (mode0, op1);
8056 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
8057 op2 = copy_to_mode_reg (mode0, op2);
8058 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
8059 op3 = copy_to_mode_reg (mode0, op3);
8061 /* Generate the compare. */
8062 scratch = gen_reg_rtx (CCmode);
8063 pat = GEN_FCN (icode) (scratch, op0, op1);
8064 if (! pat)
8065 return const0_rtx;
8066 emit_insn (pat);
8068 if (mode0 == V2SImode)
8069 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
8070 else
8071 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
8073 return target;
8076 /* Expand an expression EXP that calls a built-in function,
8077 with result going to TARGET if that's convenient
8078 (and in mode MODE if that's convenient).
8079 SUBTARGET may be used as the target for computing one of EXP's operands.
8080 IGNORE is nonzero if the value is to be ignored. */
8082 static rtx
8083 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8084 enum machine_mode mode ATTRIBUTE_UNUSED,
8085 int ignore ATTRIBUTE_UNUSED)
8087 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8088 tree arglist = TREE_OPERAND (exp, 1);
8089 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8090 struct builtin_description *d;
8091 size_t i;
8092 rtx ret;
8093 bool success;
8095 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
8096 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
8098 int icode = (int) CODE_FOR_altivec_lvsr;
8099 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8100 enum machine_mode mode = insn_data[icode].operand[1].mode;
8101 tree arg;
8102 rtx op, addr, pat;
8104 gcc_assert (TARGET_ALTIVEC);
8106 arg = TREE_VALUE (arglist);
8107 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
8108 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
8109 addr = memory_address (mode, op);
8110 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
8111 op = addr;
8112 else
8114 /* For the load case need to negate the address. */
8115 op = gen_reg_rtx (GET_MODE (addr));
8116 emit_insn (gen_rtx_SET (VOIDmode, op,
8117 gen_rtx_NEG (GET_MODE (addr), addr)));
8119 op = gen_rtx_MEM (mode, op);
8121 if (target == 0
8122 || GET_MODE (target) != tmode
8123 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8124 target = gen_reg_rtx (tmode);
8126 /*pat = gen_altivec_lvsr (target, op);*/
8127 pat = GEN_FCN (icode) (target, op);
8128 if (!pat)
8129 return 0;
8130 emit_insn (pat);
8132 return target;
8135 if (TARGET_ALTIVEC)
8137 ret = altivec_expand_builtin (exp, target, &success);
8139 if (success)
8140 return ret;
8142 if (TARGET_SPE)
8144 ret = spe_expand_builtin (exp, target, &success);
8146 if (success)
8147 return ret;
8150 gcc_assert (TARGET_ALTIVEC || TARGET_SPE);
8152 /* Handle simple unary operations. */
8153 d = (struct builtin_description *) bdesc_1arg;
8154 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
8155 if (d->code == fcode)
8156 return rs6000_expand_unop_builtin (d->icode, arglist, target);
8158 /* Handle simple binary operations. */
8159 d = (struct builtin_description *) bdesc_2arg;
8160 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
8161 if (d->code == fcode)
8162 return rs6000_expand_binop_builtin (d->icode, arglist, target);
8164 /* Handle simple ternary operations. */
8165 d = (struct builtin_description *) bdesc_3arg;
8166 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
8167 if (d->code == fcode)
8168 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
8170 gcc_unreachable ();
8173 static tree
8174 build_opaque_vector_type (tree node, int nunits)
8176 node = copy_node (node);
8177 TYPE_MAIN_VARIANT (node) = node;
8178 return build_vector_type (node, nunits);
8181 static void
8182 rs6000_init_builtins (void)
8184 V2SI_type_node = build_vector_type (intSI_type_node, 2);
8185 V2SF_type_node = build_vector_type (float_type_node, 2);
8186 V4HI_type_node = build_vector_type (intHI_type_node, 4);
8187 V4SI_type_node = build_vector_type (intSI_type_node, 4);
8188 V4SF_type_node = build_vector_type (float_type_node, 4);
8189 V8HI_type_node = build_vector_type (intHI_type_node, 8);
8190 V16QI_type_node = build_vector_type (intQI_type_node, 16);
8192 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
8193 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
8194 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
8196 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
8197 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
8198 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
8199 opaque_V4SI_type_node = copy_node (V4SI_type_node);
8201 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
8202 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
8203 'vector unsigned short'. */
8205 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
8206 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8207 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
8208 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8210 long_integer_type_internal_node = long_integer_type_node;
8211 long_unsigned_type_internal_node = long_unsigned_type_node;
8212 intQI_type_internal_node = intQI_type_node;
8213 uintQI_type_internal_node = unsigned_intQI_type_node;
8214 intHI_type_internal_node = intHI_type_node;
8215 uintHI_type_internal_node = unsigned_intHI_type_node;
8216 intSI_type_internal_node = intSI_type_node;
8217 uintSI_type_internal_node = unsigned_intSI_type_node;
8218 float_type_internal_node = float_type_node;
8219 void_type_internal_node = void_type_node;
8221 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8222 get_identifier ("__bool char"),
8223 bool_char_type_node));
8224 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8225 get_identifier ("__bool short"),
8226 bool_short_type_node));
8227 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8228 get_identifier ("__bool int"),
8229 bool_int_type_node));
8230 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8231 get_identifier ("__pixel"),
8232 pixel_type_node));
8234 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
8235 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
8236 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
8237 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
8239 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8240 get_identifier ("__vector unsigned char"),
8241 unsigned_V16QI_type_node));
8242 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8243 get_identifier ("__vector signed char"),
8244 V16QI_type_node));
8245 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8246 get_identifier ("__vector __bool char"),
8247 bool_V16QI_type_node));
8249 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8250 get_identifier ("__vector unsigned short"),
8251 unsigned_V8HI_type_node));
8252 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8253 get_identifier ("__vector signed short"),
8254 V8HI_type_node));
8255 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8256 get_identifier ("__vector __bool short"),
8257 bool_V8HI_type_node));
8259 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8260 get_identifier ("__vector unsigned int"),
8261 unsigned_V4SI_type_node));
8262 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8263 get_identifier ("__vector signed int"),
8264 V4SI_type_node));
8265 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8266 get_identifier ("__vector __bool int"),
8267 bool_V4SI_type_node));
8269 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8270 get_identifier ("__vector float"),
8271 V4SF_type_node));
8272 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8273 get_identifier ("__vector __pixel"),
8274 pixel_V8HI_type_node));
8276 if (TARGET_SPE)
8277 spe_init_builtins ();
8278 if (TARGET_ALTIVEC)
8279 altivec_init_builtins ();
8280 if (TARGET_ALTIVEC || TARGET_SPE)
8281 rs6000_common_init_builtins ();
8283 #if TARGET_XCOFF
8284 /* AIX libm provides clog as __clog. */
8285 if (built_in_decls [BUILT_IN_CLOG])
8286 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
8287 #endif
8290 /* Search through a set of builtins and enable the mask bits.
8291 DESC is an array of builtins.
8292 SIZE is the total number of builtins.
8293 START is the builtin enum at which to start.
8294 END is the builtin enum at which to end. */
8295 static void
8296 enable_mask_for_builtins (struct builtin_description *desc, int size,
8297 enum rs6000_builtins start,
8298 enum rs6000_builtins end)
8300 int i;
8302 for (i = 0; i < size; ++i)
8303 if (desc[i].code == start)
8304 break;
8306 if (i == size)
8307 return;
8309 for (; i < size; ++i)
8311 /* Flip all the bits on. */
8312 desc[i].mask = target_flags;
8313 if (desc[i].code == end)
8314 break;
8318 static void
8319 spe_init_builtins (void)
8321 tree endlink = void_list_node;
8322 tree puint_type_node = build_pointer_type (unsigned_type_node);
8323 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
8324 struct builtin_description *d;
8325 size_t i;
8327 tree v2si_ftype_4_v2si
8328 = build_function_type
8329 (opaque_V2SI_type_node,
8330 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8331 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8332 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8333 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8334 endlink)))));
8336 tree v2sf_ftype_4_v2sf
8337 = build_function_type
8338 (opaque_V2SF_type_node,
8339 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8340 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8341 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8342 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8343 endlink)))));
8345 tree int_ftype_int_v2si_v2si
8346 = build_function_type
8347 (integer_type_node,
8348 tree_cons (NULL_TREE, integer_type_node,
8349 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8350 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8351 endlink))));
8353 tree int_ftype_int_v2sf_v2sf
8354 = build_function_type
8355 (integer_type_node,
8356 tree_cons (NULL_TREE, integer_type_node,
8357 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8358 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8359 endlink))));
8361 tree void_ftype_v2si_puint_int
8362 = build_function_type (void_type_node,
8363 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8364 tree_cons (NULL_TREE, puint_type_node,
8365 tree_cons (NULL_TREE,
8366 integer_type_node,
8367 endlink))));
8369 tree void_ftype_v2si_puint_char
8370 = build_function_type (void_type_node,
8371 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8372 tree_cons (NULL_TREE, puint_type_node,
8373 tree_cons (NULL_TREE,
8374 char_type_node,
8375 endlink))));
8377 tree void_ftype_v2si_pv2si_int
8378 = build_function_type (void_type_node,
8379 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8380 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8381 tree_cons (NULL_TREE,
8382 integer_type_node,
8383 endlink))));
8385 tree void_ftype_v2si_pv2si_char
8386 = build_function_type (void_type_node,
8387 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8388 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8389 tree_cons (NULL_TREE,
8390 char_type_node,
8391 endlink))));
8393 tree void_ftype_int
8394 = build_function_type (void_type_node,
8395 tree_cons (NULL_TREE, integer_type_node, endlink));
8397 tree int_ftype_void
8398 = build_function_type (integer_type_node, endlink);
8400 tree v2si_ftype_pv2si_int
8401 = build_function_type (opaque_V2SI_type_node,
8402 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8403 tree_cons (NULL_TREE, integer_type_node,
8404 endlink)));
8406 tree v2si_ftype_puint_int
8407 = build_function_type (opaque_V2SI_type_node,
8408 tree_cons (NULL_TREE, puint_type_node,
8409 tree_cons (NULL_TREE, integer_type_node,
8410 endlink)));
8412 tree v2si_ftype_pushort_int
8413 = build_function_type (opaque_V2SI_type_node,
8414 tree_cons (NULL_TREE, pushort_type_node,
8415 tree_cons (NULL_TREE, integer_type_node,
8416 endlink)));
8418 tree v2si_ftype_signed_char
8419 = build_function_type (opaque_V2SI_type_node,
8420 tree_cons (NULL_TREE, signed_char_type_node,
8421 endlink));
8423 /* The initialization of the simple binary and unary builtins is
8424 done in rs6000_common_init_builtins, but we have to enable the
8425 mask bits here manually because we have run out of `target_flags'
8426 bits. We really need to redesign this mask business. */
8428 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
8429 ARRAY_SIZE (bdesc_2arg),
8430 SPE_BUILTIN_EVADDW,
8431 SPE_BUILTIN_EVXOR);
8432 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
8433 ARRAY_SIZE (bdesc_1arg),
8434 SPE_BUILTIN_EVABS,
8435 SPE_BUILTIN_EVSUBFUSIAAW);
8436 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
8437 ARRAY_SIZE (bdesc_spe_predicates),
8438 SPE_BUILTIN_EVCMPEQ,
8439 SPE_BUILTIN_EVFSTSTLT);
8440 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
8441 ARRAY_SIZE (bdesc_spe_evsel),
8442 SPE_BUILTIN_EVSEL_CMPGTS,
8443 SPE_BUILTIN_EVSEL_FSTSTEQ);
8445 (*lang_hooks.decls.pushdecl)
8446 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
8447 opaque_V2SI_type_node));
8449 /* Initialize irregular SPE builtins. */
8451 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
8452 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
8453 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
8454 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
8455 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
8456 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
8457 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
8458 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
8459 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
8460 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
8461 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
8462 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
8463 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
8464 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
8465 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
8466 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
8467 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
8468 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
8470 /* Loads. */
8471 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
8472 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
8473 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
8474 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
8475 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
8476 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
8477 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
8478 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
8479 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
8480 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
8481 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
8482 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
8483 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
8484 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
8485 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
8486 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
8487 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
8488 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
8489 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
8490 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
8491 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
8492 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
8494 /* Predicates. */
8495 d = (struct builtin_description *) bdesc_spe_predicates;
8496 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
8498 tree type;
8500 switch (insn_data[d->icode].operand[1].mode)
8502 case V2SImode:
8503 type = int_ftype_int_v2si_v2si;
8504 break;
8505 case V2SFmode:
8506 type = int_ftype_int_v2sf_v2sf;
8507 break;
8508 default:
8509 gcc_unreachable ();
8512 def_builtin (d->mask, d->name, type, d->code);
8515 /* Evsel predicates. */
8516 d = (struct builtin_description *) bdesc_spe_evsel;
8517 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
8519 tree type;
8521 switch (insn_data[d->icode].operand[1].mode)
8523 case V2SImode:
8524 type = v2si_ftype_4_v2si;
8525 break;
8526 case V2SFmode:
8527 type = v2sf_ftype_4_v2sf;
8528 break;
8529 default:
8530 gcc_unreachable ();
8533 def_builtin (d->mask, d->name, type, d->code);
8537 static void
8538 altivec_init_builtins (void)
8540 struct builtin_description *d;
8541 struct builtin_description_predicates *dp;
8542 size_t i;
8543 tree ftype;
8545 tree pfloat_type_node = build_pointer_type (float_type_node);
8546 tree pint_type_node = build_pointer_type (integer_type_node);
8547 tree pshort_type_node = build_pointer_type (short_integer_type_node);
8548 tree pchar_type_node = build_pointer_type (char_type_node);
8550 tree pvoid_type_node = build_pointer_type (void_type_node);
8552 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
8553 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
8554 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
8555 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
8557 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
8559 tree int_ftype_opaque
8560 = build_function_type_list (integer_type_node,
8561 opaque_V4SI_type_node, NULL_TREE);
8563 tree opaque_ftype_opaque_int
8564 = build_function_type_list (opaque_V4SI_type_node,
8565 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
8566 tree opaque_ftype_opaque_opaque_int
8567 = build_function_type_list (opaque_V4SI_type_node,
8568 opaque_V4SI_type_node, opaque_V4SI_type_node,
8569 integer_type_node, NULL_TREE);
8570 tree int_ftype_int_opaque_opaque
8571 = build_function_type_list (integer_type_node,
8572 integer_type_node, opaque_V4SI_type_node,
8573 opaque_V4SI_type_node, NULL_TREE);
8574 tree int_ftype_int_v4si_v4si
8575 = build_function_type_list (integer_type_node,
8576 integer_type_node, V4SI_type_node,
8577 V4SI_type_node, NULL_TREE);
8578 tree v4sf_ftype_pcfloat
8579 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
8580 tree void_ftype_pfloat_v4sf
8581 = build_function_type_list (void_type_node,
8582 pfloat_type_node, V4SF_type_node, NULL_TREE);
8583 tree v4si_ftype_pcint
8584 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
8585 tree void_ftype_pint_v4si
8586 = build_function_type_list (void_type_node,
8587 pint_type_node, V4SI_type_node, NULL_TREE);
8588 tree v8hi_ftype_pcshort
8589 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
8590 tree void_ftype_pshort_v8hi
8591 = build_function_type_list (void_type_node,
8592 pshort_type_node, V8HI_type_node, NULL_TREE);
8593 tree v16qi_ftype_pcchar
8594 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
8595 tree void_ftype_pchar_v16qi
8596 = build_function_type_list (void_type_node,
8597 pchar_type_node, V16QI_type_node, NULL_TREE);
8598 tree void_ftype_v4si
8599 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
8600 tree v8hi_ftype_void
8601 = build_function_type (V8HI_type_node, void_list_node);
8602 tree void_ftype_void
8603 = build_function_type (void_type_node, void_list_node);
8604 tree void_ftype_int
8605 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
8607 tree opaque_ftype_long_pcvoid
8608 = build_function_type_list (opaque_V4SI_type_node,
8609 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8610 tree v16qi_ftype_long_pcvoid
8611 = build_function_type_list (V16QI_type_node,
8612 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8613 tree v8hi_ftype_long_pcvoid
8614 = build_function_type_list (V8HI_type_node,
8615 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8616 tree v4si_ftype_long_pcvoid
8617 = build_function_type_list (V4SI_type_node,
8618 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8620 tree void_ftype_opaque_long_pvoid
8621 = build_function_type_list (void_type_node,
8622 opaque_V4SI_type_node, long_integer_type_node,
8623 pvoid_type_node, NULL_TREE);
8624 tree void_ftype_v4si_long_pvoid
8625 = build_function_type_list (void_type_node,
8626 V4SI_type_node, long_integer_type_node,
8627 pvoid_type_node, NULL_TREE);
8628 tree void_ftype_v16qi_long_pvoid
8629 = build_function_type_list (void_type_node,
8630 V16QI_type_node, long_integer_type_node,
8631 pvoid_type_node, NULL_TREE);
8632 tree void_ftype_v8hi_long_pvoid
8633 = build_function_type_list (void_type_node,
8634 V8HI_type_node, long_integer_type_node,
8635 pvoid_type_node, NULL_TREE);
8636 tree int_ftype_int_v8hi_v8hi
8637 = build_function_type_list (integer_type_node,
8638 integer_type_node, V8HI_type_node,
8639 V8HI_type_node, NULL_TREE);
8640 tree int_ftype_int_v16qi_v16qi
8641 = build_function_type_list (integer_type_node,
8642 integer_type_node, V16QI_type_node,
8643 V16QI_type_node, NULL_TREE);
8644 tree int_ftype_int_v4sf_v4sf
8645 = build_function_type_list (integer_type_node,
8646 integer_type_node, V4SF_type_node,
8647 V4SF_type_node, NULL_TREE);
8648 tree v4si_ftype_v4si
8649 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
8650 tree v8hi_ftype_v8hi
8651 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
8652 tree v16qi_ftype_v16qi
8653 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
8654 tree v4sf_ftype_v4sf
8655 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8656 tree void_ftype_pcvoid_int_int
8657 = build_function_type_list (void_type_node,
8658 pcvoid_type_node, integer_type_node,
8659 integer_type_node, NULL_TREE);
8661 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
8662 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
8663 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
8664 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
8665 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
8666 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
8667 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
8668 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
8669 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
8670 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
8671 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
8672 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
8673 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
8674 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
8675 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
8676 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
8677 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
8678 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
8679 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
8680 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
8681 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
8682 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
8683 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
8684 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
8685 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
8686 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
8687 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
8688 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
8689 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
8690 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
8691 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
8692 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
8693 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
8694 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
8695 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
8696 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
8697 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
8698 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
8699 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
8700 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
8701 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
8702 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
8703 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
8704 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
8705 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
8706 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
8708 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
8710 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
8711 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
8712 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
8713 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
8714 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
8715 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
8716 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
8717 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
8718 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
8719 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
8721 /* Add the DST variants. */
8722 d = (struct builtin_description *) bdesc_dst;
8723 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8724 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
8726 /* Initialize the predicates. */
8727 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
8728 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
8730 enum machine_mode mode1;
8731 tree type;
8732 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8733 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8735 if (is_overloaded)
8736 mode1 = VOIDmode;
8737 else
8738 mode1 = insn_data[dp->icode].operand[1].mode;
8740 switch (mode1)
8742 case VOIDmode:
8743 type = int_ftype_int_opaque_opaque;
8744 break;
8745 case V4SImode:
8746 type = int_ftype_int_v4si_v4si;
8747 break;
8748 case V8HImode:
8749 type = int_ftype_int_v8hi_v8hi;
8750 break;
8751 case V16QImode:
8752 type = int_ftype_int_v16qi_v16qi;
8753 break;
8754 case V4SFmode:
8755 type = int_ftype_int_v4sf_v4sf;
8756 break;
8757 default:
8758 gcc_unreachable ();
8761 def_builtin (dp->mask, dp->name, type, dp->code);
8764 /* Initialize the abs* operators. */
8765 d = (struct builtin_description *) bdesc_abs;
8766 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
8768 enum machine_mode mode0;
8769 tree type;
8771 mode0 = insn_data[d->icode].operand[0].mode;
8773 switch (mode0)
8775 case V4SImode:
8776 type = v4si_ftype_v4si;
8777 break;
8778 case V8HImode:
8779 type = v8hi_ftype_v8hi;
8780 break;
8781 case V16QImode:
8782 type = v16qi_ftype_v16qi;
8783 break;
8784 case V4SFmode:
8785 type = v4sf_ftype_v4sf;
8786 break;
8787 default:
8788 gcc_unreachable ();
8791 def_builtin (d->mask, d->name, type, d->code);
8794 if (TARGET_ALTIVEC)
8796 tree decl;
8798 /* Initialize target builtin that implements
8799 targetm.vectorize.builtin_mask_for_load. */
8801 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
8802 v16qi_ftype_long_pcvoid,
8803 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
8804 BUILT_IN_MD, NULL, NULL_TREE);
8805 TREE_READONLY (decl) = 1;
8806 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8807 altivec_builtin_mask_for_load = decl;
8810 /* Access to the vec_init patterns. */
8811 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
8812 integer_type_node, integer_type_node,
8813 integer_type_node, NULL_TREE);
8814 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
8815 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
8817 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
8818 short_integer_type_node,
8819 short_integer_type_node,
8820 short_integer_type_node,
8821 short_integer_type_node,
8822 short_integer_type_node,
8823 short_integer_type_node,
8824 short_integer_type_node, NULL_TREE);
8825 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
8826 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
8828 ftype = build_function_type_list (V16QI_type_node, char_type_node,
8829 char_type_node, char_type_node,
8830 char_type_node, char_type_node,
8831 char_type_node, char_type_node,
8832 char_type_node, char_type_node,
8833 char_type_node, char_type_node,
8834 char_type_node, char_type_node,
8835 char_type_node, char_type_node,
8836 char_type_node, NULL_TREE);
8837 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
8838 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
8840 ftype = build_function_type_list (V4SF_type_node, float_type_node,
8841 float_type_node, float_type_node,
8842 float_type_node, NULL_TREE);
8843 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
8844 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
8846 /* Access to the vec_set patterns. */
8847 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
8848 intSI_type_node,
8849 integer_type_node, NULL_TREE);
8850 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
8851 ALTIVEC_BUILTIN_VEC_SET_V4SI);
8853 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
8854 intHI_type_node,
8855 integer_type_node, NULL_TREE);
8856 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
8857 ALTIVEC_BUILTIN_VEC_SET_V8HI);
8859 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
8860 intQI_type_node,
8861 integer_type_node, NULL_TREE);
8862 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
8863 ALTIVEC_BUILTIN_VEC_SET_V16QI);
8865 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
8866 float_type_node,
8867 integer_type_node, NULL_TREE);
8868 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
8869 ALTIVEC_BUILTIN_VEC_SET_V4SF);
8871 /* Access to the vec_extract patterns. */
8872 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
8873 integer_type_node, NULL_TREE);
8874 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
8875 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
8877 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
8878 integer_type_node, NULL_TREE);
8879 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
8880 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
8882 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
8883 integer_type_node, NULL_TREE);
8884 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
8885 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
8887 ftype = build_function_type_list (float_type_node, V4SF_type_node,
8888 integer_type_node, NULL_TREE);
8889 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
8890 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
8893 static void
8894 rs6000_common_init_builtins (void)
8896 struct builtin_description *d;
8897 size_t i;
8899 tree v4sf_ftype_v4sf_v4sf_v16qi
8900 = build_function_type_list (V4SF_type_node,
8901 V4SF_type_node, V4SF_type_node,
8902 V16QI_type_node, NULL_TREE);
8903 tree v4si_ftype_v4si_v4si_v16qi
8904 = build_function_type_list (V4SI_type_node,
8905 V4SI_type_node, V4SI_type_node,
8906 V16QI_type_node, NULL_TREE);
8907 tree v8hi_ftype_v8hi_v8hi_v16qi
8908 = build_function_type_list (V8HI_type_node,
8909 V8HI_type_node, V8HI_type_node,
8910 V16QI_type_node, NULL_TREE);
8911 tree v16qi_ftype_v16qi_v16qi_v16qi
8912 = build_function_type_list (V16QI_type_node,
8913 V16QI_type_node, V16QI_type_node,
8914 V16QI_type_node, NULL_TREE);
8915 tree v4si_ftype_int
8916 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
8917 tree v8hi_ftype_int
8918 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
8919 tree v16qi_ftype_int
8920 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
8921 tree v8hi_ftype_v16qi
8922 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
8923 tree v4sf_ftype_v4sf
8924 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8926 tree v2si_ftype_v2si_v2si
8927 = build_function_type_list (opaque_V2SI_type_node,
8928 opaque_V2SI_type_node,
8929 opaque_V2SI_type_node, NULL_TREE);
8931 tree v2sf_ftype_v2sf_v2sf
8932 = build_function_type_list (opaque_V2SF_type_node,
8933 opaque_V2SF_type_node,
8934 opaque_V2SF_type_node, NULL_TREE);
8936 tree v2si_ftype_int_int
8937 = build_function_type_list (opaque_V2SI_type_node,
8938 integer_type_node, integer_type_node,
8939 NULL_TREE);
8941 tree opaque_ftype_opaque
8942 = build_function_type_list (opaque_V4SI_type_node,
8943 opaque_V4SI_type_node, NULL_TREE);
8945 tree v2si_ftype_v2si
8946 = build_function_type_list (opaque_V2SI_type_node,
8947 opaque_V2SI_type_node, NULL_TREE);
8949 tree v2sf_ftype_v2sf
8950 = build_function_type_list (opaque_V2SF_type_node,
8951 opaque_V2SF_type_node, NULL_TREE);
8953 tree v2sf_ftype_v2si
8954 = build_function_type_list (opaque_V2SF_type_node,
8955 opaque_V2SI_type_node, NULL_TREE);
8957 tree v2si_ftype_v2sf
8958 = build_function_type_list (opaque_V2SI_type_node,
8959 opaque_V2SF_type_node, NULL_TREE);
8961 tree v2si_ftype_v2si_char
8962 = build_function_type_list (opaque_V2SI_type_node,
8963 opaque_V2SI_type_node,
8964 char_type_node, NULL_TREE);
8966 tree v2si_ftype_int_char
8967 = build_function_type_list (opaque_V2SI_type_node,
8968 integer_type_node, char_type_node, NULL_TREE);
8970 tree v2si_ftype_char
8971 = build_function_type_list (opaque_V2SI_type_node,
8972 char_type_node, NULL_TREE);
8974 tree int_ftype_int_int
8975 = build_function_type_list (integer_type_node,
8976 integer_type_node, integer_type_node,
8977 NULL_TREE);
8979 tree opaque_ftype_opaque_opaque
8980 = build_function_type_list (opaque_V4SI_type_node,
8981 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
8982 tree v4si_ftype_v4si_v4si
8983 = build_function_type_list (V4SI_type_node,
8984 V4SI_type_node, V4SI_type_node, NULL_TREE);
8985 tree v4sf_ftype_v4si_int
8986 = build_function_type_list (V4SF_type_node,
8987 V4SI_type_node, integer_type_node, NULL_TREE);
8988 tree v4si_ftype_v4sf_int
8989 = build_function_type_list (V4SI_type_node,
8990 V4SF_type_node, integer_type_node, NULL_TREE);
8991 tree v4si_ftype_v4si_int
8992 = build_function_type_list (V4SI_type_node,
8993 V4SI_type_node, integer_type_node, NULL_TREE);
8994 tree v8hi_ftype_v8hi_int
8995 = build_function_type_list (V8HI_type_node,
8996 V8HI_type_node, integer_type_node, NULL_TREE);
8997 tree v16qi_ftype_v16qi_int
8998 = build_function_type_list (V16QI_type_node,
8999 V16QI_type_node, integer_type_node, NULL_TREE);
9000 tree v16qi_ftype_v16qi_v16qi_int
9001 = build_function_type_list (V16QI_type_node,
9002 V16QI_type_node, V16QI_type_node,
9003 integer_type_node, NULL_TREE);
9004 tree v8hi_ftype_v8hi_v8hi_int
9005 = build_function_type_list (V8HI_type_node,
9006 V8HI_type_node, V8HI_type_node,
9007 integer_type_node, NULL_TREE);
9008 tree v4si_ftype_v4si_v4si_int
9009 = build_function_type_list (V4SI_type_node,
9010 V4SI_type_node, V4SI_type_node,
9011 integer_type_node, NULL_TREE);
9012 tree v4sf_ftype_v4sf_v4sf_int
9013 = build_function_type_list (V4SF_type_node,
9014 V4SF_type_node, V4SF_type_node,
9015 integer_type_node, NULL_TREE);
9016 tree v4sf_ftype_v4sf_v4sf
9017 = build_function_type_list (V4SF_type_node,
9018 V4SF_type_node, V4SF_type_node, NULL_TREE);
9019 tree opaque_ftype_opaque_opaque_opaque
9020 = build_function_type_list (opaque_V4SI_type_node,
9021 opaque_V4SI_type_node, opaque_V4SI_type_node,
9022 opaque_V4SI_type_node, NULL_TREE);
9023 tree v4sf_ftype_v4sf_v4sf_v4si
9024 = build_function_type_list (V4SF_type_node,
9025 V4SF_type_node, V4SF_type_node,
9026 V4SI_type_node, NULL_TREE);
9027 tree v4sf_ftype_v4sf_v4sf_v4sf
9028 = build_function_type_list (V4SF_type_node,
9029 V4SF_type_node, V4SF_type_node,
9030 V4SF_type_node, NULL_TREE);
9031 tree v4si_ftype_v4si_v4si_v4si
9032 = build_function_type_list (V4SI_type_node,
9033 V4SI_type_node, V4SI_type_node,
9034 V4SI_type_node, NULL_TREE);
9035 tree v8hi_ftype_v8hi_v8hi
9036 = build_function_type_list (V8HI_type_node,
9037 V8HI_type_node, V8HI_type_node, NULL_TREE);
9038 tree v8hi_ftype_v8hi_v8hi_v8hi
9039 = build_function_type_list (V8HI_type_node,
9040 V8HI_type_node, V8HI_type_node,
9041 V8HI_type_node, NULL_TREE);
9042 tree v4si_ftype_v8hi_v8hi_v4si
9043 = build_function_type_list (V4SI_type_node,
9044 V8HI_type_node, V8HI_type_node,
9045 V4SI_type_node, NULL_TREE);
9046 tree v4si_ftype_v16qi_v16qi_v4si
9047 = build_function_type_list (V4SI_type_node,
9048 V16QI_type_node, V16QI_type_node,
9049 V4SI_type_node, NULL_TREE);
9050 tree v16qi_ftype_v16qi_v16qi
9051 = build_function_type_list (V16QI_type_node,
9052 V16QI_type_node, V16QI_type_node, NULL_TREE);
9053 tree v4si_ftype_v4sf_v4sf
9054 = build_function_type_list (V4SI_type_node,
9055 V4SF_type_node, V4SF_type_node, NULL_TREE);
9056 tree v8hi_ftype_v16qi_v16qi
9057 = build_function_type_list (V8HI_type_node,
9058 V16QI_type_node, V16QI_type_node, NULL_TREE);
9059 tree v4si_ftype_v8hi_v8hi
9060 = build_function_type_list (V4SI_type_node,
9061 V8HI_type_node, V8HI_type_node, NULL_TREE);
9062 tree v8hi_ftype_v4si_v4si
9063 = build_function_type_list (V8HI_type_node,
9064 V4SI_type_node, V4SI_type_node, NULL_TREE);
9065 tree v16qi_ftype_v8hi_v8hi
9066 = build_function_type_list (V16QI_type_node,
9067 V8HI_type_node, V8HI_type_node, NULL_TREE);
9068 tree v4si_ftype_v16qi_v4si
9069 = build_function_type_list (V4SI_type_node,
9070 V16QI_type_node, V4SI_type_node, NULL_TREE);
9071 tree v4si_ftype_v16qi_v16qi
9072 = build_function_type_list (V4SI_type_node,
9073 V16QI_type_node, V16QI_type_node, NULL_TREE);
9074 tree v4si_ftype_v8hi_v4si
9075 = build_function_type_list (V4SI_type_node,
9076 V8HI_type_node, V4SI_type_node, NULL_TREE);
9077 tree v4si_ftype_v8hi
9078 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
9079 tree int_ftype_v4si_v4si
9080 = build_function_type_list (integer_type_node,
9081 V4SI_type_node, V4SI_type_node, NULL_TREE);
9082 tree int_ftype_v4sf_v4sf
9083 = build_function_type_list (integer_type_node,
9084 V4SF_type_node, V4SF_type_node, NULL_TREE);
9085 tree int_ftype_v16qi_v16qi
9086 = build_function_type_list (integer_type_node,
9087 V16QI_type_node, V16QI_type_node, NULL_TREE);
9088 tree int_ftype_v8hi_v8hi
9089 = build_function_type_list (integer_type_node,
9090 V8HI_type_node, V8HI_type_node, NULL_TREE);
9092 /* Add the simple ternary operators. */
9093 d = (struct builtin_description *) bdesc_3arg;
9094 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
9096 enum machine_mode mode0, mode1, mode2, mode3;
9097 tree type;
9098 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9099 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9101 if (is_overloaded)
9103 mode0 = VOIDmode;
9104 mode1 = VOIDmode;
9105 mode2 = VOIDmode;
9106 mode3 = VOIDmode;
9108 else
9110 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9111 continue;
9113 mode0 = insn_data[d->icode].operand[0].mode;
9114 mode1 = insn_data[d->icode].operand[1].mode;
9115 mode2 = insn_data[d->icode].operand[2].mode;
9116 mode3 = insn_data[d->icode].operand[3].mode;
9119 /* When all four are of the same mode. */
9120 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
9122 switch (mode0)
9124 case VOIDmode:
9125 type = opaque_ftype_opaque_opaque_opaque;
9126 break;
9127 case V4SImode:
9128 type = v4si_ftype_v4si_v4si_v4si;
9129 break;
9130 case V4SFmode:
9131 type = v4sf_ftype_v4sf_v4sf_v4sf;
9132 break;
9133 case V8HImode:
9134 type = v8hi_ftype_v8hi_v8hi_v8hi;
9135 break;
9136 case V16QImode:
9137 type = v16qi_ftype_v16qi_v16qi_v16qi;
9138 break;
9139 default:
9140 gcc_unreachable ();
9143 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
9145 switch (mode0)
9147 case V4SImode:
9148 type = v4si_ftype_v4si_v4si_v16qi;
9149 break;
9150 case V4SFmode:
9151 type = v4sf_ftype_v4sf_v4sf_v16qi;
9152 break;
9153 case V8HImode:
9154 type = v8hi_ftype_v8hi_v8hi_v16qi;
9155 break;
9156 case V16QImode:
9157 type = v16qi_ftype_v16qi_v16qi_v16qi;
9158 break;
9159 default:
9160 gcc_unreachable ();
9163 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
9164 && mode3 == V4SImode)
9165 type = v4si_ftype_v16qi_v16qi_v4si;
9166 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
9167 && mode3 == V4SImode)
9168 type = v4si_ftype_v8hi_v8hi_v4si;
9169 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
9170 && mode3 == V4SImode)
9171 type = v4sf_ftype_v4sf_v4sf_v4si;
9173 /* vchar, vchar, vchar, 4 bit literal. */
9174 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
9175 && mode3 == QImode)
9176 type = v16qi_ftype_v16qi_v16qi_int;
9178 /* vshort, vshort, vshort, 4 bit literal. */
9179 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
9180 && mode3 == QImode)
9181 type = v8hi_ftype_v8hi_v8hi_int;
9183 /* vint, vint, vint, 4 bit literal. */
9184 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
9185 && mode3 == QImode)
9186 type = v4si_ftype_v4si_v4si_int;
9188 /* vfloat, vfloat, vfloat, 4 bit literal. */
9189 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
9190 && mode3 == QImode)
9191 type = v4sf_ftype_v4sf_v4sf_int;
9193 else
9194 gcc_unreachable ();
9196 def_builtin (d->mask, d->name, type, d->code);
9199 /* Add the simple binary operators. */
9200 d = (struct builtin_description *) bdesc_2arg;
9201 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
9203 enum machine_mode mode0, mode1, mode2;
9204 tree type;
9205 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9206 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9208 if (is_overloaded)
9210 mode0 = VOIDmode;
9211 mode1 = VOIDmode;
9212 mode2 = VOIDmode;
9214 else
9216 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9217 continue;
9219 mode0 = insn_data[d->icode].operand[0].mode;
9220 mode1 = insn_data[d->icode].operand[1].mode;
9221 mode2 = insn_data[d->icode].operand[2].mode;
9224 /* When all three operands are of the same mode. */
9225 if (mode0 == mode1 && mode1 == mode2)
9227 switch (mode0)
9229 case VOIDmode:
9230 type = opaque_ftype_opaque_opaque;
9231 break;
9232 case V4SFmode:
9233 type = v4sf_ftype_v4sf_v4sf;
9234 break;
9235 case V4SImode:
9236 type = v4si_ftype_v4si_v4si;
9237 break;
9238 case V16QImode:
9239 type = v16qi_ftype_v16qi_v16qi;
9240 break;
9241 case V8HImode:
9242 type = v8hi_ftype_v8hi_v8hi;
9243 break;
9244 case V2SImode:
9245 type = v2si_ftype_v2si_v2si;
9246 break;
9247 case V2SFmode:
9248 type = v2sf_ftype_v2sf_v2sf;
9249 break;
9250 case SImode:
9251 type = int_ftype_int_int;
9252 break;
9253 default:
9254 gcc_unreachable ();
9258 /* A few other combos we really don't want to do manually. */
9260 /* vint, vfloat, vfloat. */
9261 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
9262 type = v4si_ftype_v4sf_v4sf;
9264 /* vshort, vchar, vchar. */
9265 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
9266 type = v8hi_ftype_v16qi_v16qi;
9268 /* vint, vshort, vshort. */
9269 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
9270 type = v4si_ftype_v8hi_v8hi;
9272 /* vshort, vint, vint. */
9273 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
9274 type = v8hi_ftype_v4si_v4si;
9276 /* vchar, vshort, vshort. */
9277 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
9278 type = v16qi_ftype_v8hi_v8hi;
9280 /* vint, vchar, vint. */
9281 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
9282 type = v4si_ftype_v16qi_v4si;
9284 /* vint, vchar, vchar. */
9285 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
9286 type = v4si_ftype_v16qi_v16qi;
9288 /* vint, vshort, vint. */
9289 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
9290 type = v4si_ftype_v8hi_v4si;
9292 /* vint, vint, 5 bit literal. */
9293 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
9294 type = v4si_ftype_v4si_int;
9296 /* vshort, vshort, 5 bit literal. */
9297 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
9298 type = v8hi_ftype_v8hi_int;
9300 /* vchar, vchar, 5 bit literal. */
9301 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
9302 type = v16qi_ftype_v16qi_int;
9304 /* vfloat, vint, 5 bit literal. */
9305 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
9306 type = v4sf_ftype_v4si_int;
9308 /* vint, vfloat, 5 bit literal. */
9309 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
9310 type = v4si_ftype_v4sf_int;
9312 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
9313 type = v2si_ftype_int_int;
9315 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
9316 type = v2si_ftype_v2si_char;
9318 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
9319 type = v2si_ftype_int_char;
9321 else
9323 /* int, x, x. */
9324 gcc_assert (mode0 == SImode);
9325 switch (mode1)
9327 case V4SImode:
9328 type = int_ftype_v4si_v4si;
9329 break;
9330 case V4SFmode:
9331 type = int_ftype_v4sf_v4sf;
9332 break;
9333 case V16QImode:
9334 type = int_ftype_v16qi_v16qi;
9335 break;
9336 case V8HImode:
9337 type = int_ftype_v8hi_v8hi;
9338 break;
9339 default:
9340 gcc_unreachable ();
9344 def_builtin (d->mask, d->name, type, d->code);
9347 /* Add the simple unary operators. */
9348 d = (struct builtin_description *) bdesc_1arg;
9349 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
9351 enum machine_mode mode0, mode1;
9352 tree type;
9353 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9354 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9356 if (is_overloaded)
9358 mode0 = VOIDmode;
9359 mode1 = VOIDmode;
9361 else
9363 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9364 continue;
9366 mode0 = insn_data[d->icode].operand[0].mode;
9367 mode1 = insn_data[d->icode].operand[1].mode;
9370 if (mode0 == V4SImode && mode1 == QImode)
9371 type = v4si_ftype_int;
9372 else if (mode0 == V8HImode && mode1 == QImode)
9373 type = v8hi_ftype_int;
9374 else if (mode0 == V16QImode && mode1 == QImode)
9375 type = v16qi_ftype_int;
9376 else if (mode0 == VOIDmode && mode1 == VOIDmode)
9377 type = opaque_ftype_opaque;
9378 else if (mode0 == V4SFmode && mode1 == V4SFmode)
9379 type = v4sf_ftype_v4sf;
9380 else if (mode0 == V8HImode && mode1 == V16QImode)
9381 type = v8hi_ftype_v16qi;
9382 else if (mode0 == V4SImode && mode1 == V8HImode)
9383 type = v4si_ftype_v8hi;
9384 else if (mode0 == V2SImode && mode1 == V2SImode)
9385 type = v2si_ftype_v2si;
9386 else if (mode0 == V2SFmode && mode1 == V2SFmode)
9387 type = v2sf_ftype_v2sf;
9388 else if (mode0 == V2SFmode && mode1 == V2SImode)
9389 type = v2sf_ftype_v2si;
9390 else if (mode0 == V2SImode && mode1 == V2SFmode)
9391 type = v2si_ftype_v2sf;
9392 else if (mode0 == V2SImode && mode1 == QImode)
9393 type = v2si_ftype_char;
9394 else
9395 gcc_unreachable ();
9397 def_builtin (d->mask, d->name, type, d->code);
9401 static void
9402 rs6000_init_libfuncs (void)
9404 if (!TARGET_HARD_FLOAT)
9405 return;
9407 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
9408 && !TARGET_POWER2 && !TARGET_POWERPC)
9410 /* AIX library routines for float->int conversion. */
9411 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
9412 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
9413 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
9414 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
9417 if (!TARGET_IEEEQUAD)
9418 /* AIX/Darwin/64-bit Linux quad floating point routines. */
9419 if (!TARGET_XL_COMPAT)
9421 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
9422 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
9423 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
9424 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
9426 else
9428 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
9429 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
9430 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
9431 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
9433 else
9435 /* 32-bit SVR4 quad floating point routines. */
9437 set_optab_libfunc (add_optab, TFmode, "_q_add");
9438 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
9439 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
9440 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
9441 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
9442 if (TARGET_PPC_GPOPT || TARGET_POWER2)
9443 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
9445 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
9446 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
9447 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
9448 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
9449 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
9450 set_optab_libfunc (le_optab, TFmode, "_q_fle");
9452 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
9453 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
9454 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
9455 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
9456 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
9457 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
9458 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
9459 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
9464 /* Expand a block clear operation, and return 1 if successful. Return 0
9465 if we should let the compiler generate normal code.
9467 operands[0] is the destination
9468 operands[1] is the length
9469 operands[3] is the alignment */
9472 expand_block_clear (rtx operands[])
9474 rtx orig_dest = operands[0];
9475 rtx bytes_rtx = operands[1];
9476 rtx align_rtx = operands[3];
9477 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
9478 HOST_WIDE_INT align;
9479 HOST_WIDE_INT bytes;
9480 int offset;
9481 int clear_bytes;
9482 int clear_step;
9484 /* If this is not a fixed size move, just call memcpy */
9485 if (! constp)
9486 return 0;
9488 /* This must be a fixed size alignment */
9489 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9490 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9492 /* Anything to clear? */
9493 bytes = INTVAL (bytes_rtx);
9494 if (bytes <= 0)
9495 return 1;
9497 /* Use the builtin memset after a point, to avoid huge code bloat.
9498 When optimize_size, avoid any significant code bloat; calling
9499 memset is about 4 instructions, so allow for one instruction to
9500 load zero and three to do clearing. */
9501 if (TARGET_ALTIVEC && align >= 128)
9502 clear_step = 16;
9503 else if (TARGET_POWERPC64 && align >= 32)
9504 clear_step = 8;
9505 else
9506 clear_step = 4;
9508 if (optimize_size && bytes > 3 * clear_step)
9509 return 0;
9510 if (! optimize_size && bytes > 8 * clear_step)
9511 return 0;
9513 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
9515 enum machine_mode mode = BLKmode;
9516 rtx dest;
9518 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
9520 clear_bytes = 16;
9521 mode = V4SImode;
9523 else if (bytes >= 8 && TARGET_POWERPC64
9524 /* 64-bit loads and stores require word-aligned
9525 displacements. */
9526 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9528 clear_bytes = 8;
9529 mode = DImode;
9531 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9532 { /* move 4 bytes */
9533 clear_bytes = 4;
9534 mode = SImode;
9536 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9537 { /* move 2 bytes */
9538 clear_bytes = 2;
9539 mode = HImode;
9541 else /* move 1 byte at a time */
9543 clear_bytes = 1;
9544 mode = QImode;
9547 dest = adjust_address (orig_dest, mode, offset);
9549 emit_move_insn (dest, CONST0_RTX (mode));
9552 return 1;
9556 /* Expand a block move operation, and return 1 if successful. Return 0
9557 if we should let the compiler generate normal code.
9559 operands[0] is the destination
9560 operands[1] is the source
9561 operands[2] is the length
9562 operands[3] is the alignment */
9564 #define MAX_MOVE_REG 4
9567 expand_block_move (rtx operands[])
9569 rtx orig_dest = operands[0];
9570 rtx orig_src = operands[1];
9571 rtx bytes_rtx = operands[2];
9572 rtx align_rtx = operands[3];
9573 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
9574 int align;
9575 int bytes;
9576 int offset;
9577 int move_bytes;
9578 rtx stores[MAX_MOVE_REG];
9579 int num_reg = 0;
9581 /* If this is not a fixed size move, just call memcpy */
9582 if (! constp)
9583 return 0;
9585 /* This must be a fixed size alignment */
9586 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9587 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9589 /* Anything to move? */
9590 bytes = INTVAL (bytes_rtx);
9591 if (bytes <= 0)
9592 return 1;
9594 /* store_one_arg depends on expand_block_move to handle at least the size of
9595 reg_parm_stack_space. */
9596 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
9597 return 0;
9599 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
9601 union {
9602 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
9603 rtx (*mov) (rtx, rtx);
9604 } gen_func;
9605 enum machine_mode mode = BLKmode;
9606 rtx src, dest;
9608 /* Altivec first, since it will be faster than a string move
9609 when it applies, and usually not significantly larger. */
9610 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
9612 move_bytes = 16;
9613 mode = V4SImode;
9614 gen_func.mov = gen_movv4si;
9616 else if (TARGET_STRING
9617 && bytes > 24 /* move up to 32 bytes at a time */
9618 && ! fixed_regs[5]
9619 && ! fixed_regs[6]
9620 && ! fixed_regs[7]
9621 && ! fixed_regs[8]
9622 && ! fixed_regs[9]
9623 && ! fixed_regs[10]
9624 && ! fixed_regs[11]
9625 && ! fixed_regs[12])
9627 move_bytes = (bytes > 32) ? 32 : bytes;
9628 gen_func.movmemsi = gen_movmemsi_8reg;
9630 else if (TARGET_STRING
9631 && bytes > 16 /* move up to 24 bytes at a time */
9632 && ! fixed_regs[5]
9633 && ! fixed_regs[6]
9634 && ! fixed_regs[7]
9635 && ! fixed_regs[8]
9636 && ! fixed_regs[9]
9637 && ! fixed_regs[10])
9639 move_bytes = (bytes > 24) ? 24 : bytes;
9640 gen_func.movmemsi = gen_movmemsi_6reg;
9642 else if (TARGET_STRING
9643 && bytes > 8 /* move up to 16 bytes at a time */
9644 && ! fixed_regs[5]
9645 && ! fixed_regs[6]
9646 && ! fixed_regs[7]
9647 && ! fixed_regs[8])
9649 move_bytes = (bytes > 16) ? 16 : bytes;
9650 gen_func.movmemsi = gen_movmemsi_4reg;
9652 else if (bytes >= 8 && TARGET_POWERPC64
9653 /* 64-bit loads and stores require word-aligned
9654 displacements. */
9655 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9657 move_bytes = 8;
9658 mode = DImode;
9659 gen_func.mov = gen_movdi;
9661 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
9662 { /* move up to 8 bytes at a time */
9663 move_bytes = (bytes > 8) ? 8 : bytes;
9664 gen_func.movmemsi = gen_movmemsi_2reg;
9666 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9667 { /* move 4 bytes */
9668 move_bytes = 4;
9669 mode = SImode;
9670 gen_func.mov = gen_movsi;
9672 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9673 { /* move 2 bytes */
9674 move_bytes = 2;
9675 mode = HImode;
9676 gen_func.mov = gen_movhi;
9678 else if (TARGET_STRING && bytes > 1)
9679 { /* move up to 4 bytes at a time */
9680 move_bytes = (bytes > 4) ? 4 : bytes;
9681 gen_func.movmemsi = gen_movmemsi_1reg;
9683 else /* move 1 byte at a time */
9685 move_bytes = 1;
9686 mode = QImode;
9687 gen_func.mov = gen_movqi;
9690 src = adjust_address (orig_src, mode, offset);
9691 dest = adjust_address (orig_dest, mode, offset);
9693 if (mode != BLKmode)
9695 rtx tmp_reg = gen_reg_rtx (mode);
9697 emit_insn ((*gen_func.mov) (tmp_reg, src));
9698 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
9701 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
9703 int i;
9704 for (i = 0; i < num_reg; i++)
9705 emit_insn (stores[i]);
9706 num_reg = 0;
9709 if (mode == BLKmode)
9711 /* Move the address into scratch registers. The movmemsi
9712 patterns require zero offset. */
9713 if (!REG_P (XEXP (src, 0)))
9715 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
9716 src = replace_equiv_address (src, src_reg);
9718 set_mem_size (src, GEN_INT (move_bytes));
9720 if (!REG_P (XEXP (dest, 0)))
9722 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
9723 dest = replace_equiv_address (dest, dest_reg);
9725 set_mem_size (dest, GEN_INT (move_bytes));
9727 emit_insn ((*gen_func.movmemsi) (dest, src,
9728 GEN_INT (move_bytes & 31),
9729 align_rtx));
9733 return 1;
9737 /* Return a string to perform a load_multiple operation.
9738 operands[0] is the vector.
9739 operands[1] is the source address.
9740 operands[2] is the first destination register. */
9742 const char *
9743 rs6000_output_load_multiple (rtx operands[3])
9745 /* We have to handle the case where the pseudo used to contain the address
9746 is assigned to one of the output registers. */
9747 int i, j;
9748 int words = XVECLEN (operands[0], 0);
9749 rtx xop[10];
9751 if (XVECLEN (operands[0], 0) == 1)
9752 return "{l|lwz} %2,0(%1)";
9754 for (i = 0; i < words; i++)
9755 if (refers_to_regno_p (REGNO (operands[2]) + i,
9756 REGNO (operands[2]) + i + 1, operands[1], 0))
9758 if (i == words-1)
9760 xop[0] = GEN_INT (4 * (words-1));
9761 xop[1] = operands[1];
9762 xop[2] = operands[2];
9763 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
9764 return "";
9766 else if (i == 0)
9768 xop[0] = GEN_INT (4 * (words-1));
9769 xop[1] = operands[1];
9770 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
9771 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);
9772 return "";
9774 else
9776 for (j = 0; j < words; j++)
9777 if (j != i)
9779 xop[0] = GEN_INT (j * 4);
9780 xop[1] = operands[1];
9781 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
9782 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
9784 xop[0] = GEN_INT (i * 4);
9785 xop[1] = operands[1];
9786 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
9787 return "";
9791 return "{lsi|lswi} %2,%1,%N0";
9795 /* A validation routine: say whether CODE, a condition code, and MODE
9796 match. The other alternatives either don't make sense or should
9797 never be generated. */
9799 void
9800 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
9802 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
9803 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
9804 && GET_MODE_CLASS (mode) == MODE_CC);
9806 /* These don't make sense. */
9807 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
9808 || mode != CCUNSmode);
9810 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
9811 || mode == CCUNSmode);
9813 gcc_assert (mode == CCFPmode
9814 || (code != ORDERED && code != UNORDERED
9815 && code != UNEQ && code != LTGT
9816 && code != UNGT && code != UNLT
9817 && code != UNGE && code != UNLE));
9819 /* These should never be generated except for
9820 flag_finite_math_only. */
9821 gcc_assert (mode != CCFPmode
9822 || flag_finite_math_only
9823 || (code != LE && code != GE
9824 && code != UNEQ && code != LTGT
9825 && code != UNGT && code != UNLT));
9827 /* These are invalid; the information is not there. */
9828 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
9832 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9833 mask required to convert the result of a rotate insn into a shift
9834 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9837 includes_lshift_p (rtx shiftop, rtx andop)
9839 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9841 shift_mask <<= INTVAL (shiftop);
9843 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9846 /* Similar, but for right shift. */
9849 includes_rshift_p (rtx shiftop, rtx andop)
9851 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9853 shift_mask >>= INTVAL (shiftop);
9855 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9858 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9859 to perform a left shift. It must have exactly SHIFTOP least
9860 significant 0's, then one or more 1's, then zero or more 0's. */
9863 includes_rldic_lshift_p (rtx shiftop, rtx andop)
9865 if (GET_CODE (andop) == CONST_INT)
9867 HOST_WIDE_INT c, lsb, shift_mask;
9869 c = INTVAL (andop);
9870 if (c == 0 || c == ~0)
9871 return 0;
9873 shift_mask = ~0;
9874 shift_mask <<= INTVAL (shiftop);
9876 /* Find the least significant one bit. */
9877 lsb = c & -c;
9879 /* It must coincide with the LSB of the shift mask. */
9880 if (-lsb != shift_mask)
9881 return 0;
9883 /* Invert to look for the next transition (if any). */
9884 c = ~c;
9886 /* Remove the low group of ones (originally low group of zeros). */
9887 c &= -lsb;
9889 /* Again find the lsb, and check we have all 1's above. */
9890 lsb = c & -c;
9891 return c == -lsb;
9893 else if (GET_CODE (andop) == CONST_DOUBLE
9894 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9896 HOST_WIDE_INT low, high, lsb;
9897 HOST_WIDE_INT shift_mask_low, shift_mask_high;
9899 low = CONST_DOUBLE_LOW (andop);
9900 if (HOST_BITS_PER_WIDE_INT < 64)
9901 high = CONST_DOUBLE_HIGH (andop);
9903 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
9904 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
9905 return 0;
9907 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9909 shift_mask_high = ~0;
9910 if (INTVAL (shiftop) > 32)
9911 shift_mask_high <<= INTVAL (shiftop) - 32;
9913 lsb = high & -high;
9915 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
9916 return 0;
9918 high = ~high;
9919 high &= -lsb;
9921 lsb = high & -high;
9922 return high == -lsb;
9925 shift_mask_low = ~0;
9926 shift_mask_low <<= INTVAL (shiftop);
9928 lsb = low & -low;
9930 if (-lsb != shift_mask_low)
9931 return 0;
9933 if (HOST_BITS_PER_WIDE_INT < 64)
9934 high = ~high;
9935 low = ~low;
9936 low &= -lsb;
9938 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9940 lsb = high & -high;
9941 return high == -lsb;
9944 lsb = low & -low;
9945 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
9947 else
9948 return 0;
9951 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
9952 to perform a left shift. It must have SHIFTOP or more least
9953 significant 0's, with the remainder of the word 1's. */
9956 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
9958 if (GET_CODE (andop) == CONST_INT)
9960 HOST_WIDE_INT c, lsb, shift_mask;
9962 shift_mask = ~0;
9963 shift_mask <<= INTVAL (shiftop);
9964 c = INTVAL (andop);
9966 /* Find the least significant one bit. */
9967 lsb = c & -c;
9969 /* It must be covered by the shift mask.
9970 This test also rejects c == 0. */
9971 if ((lsb & shift_mask) == 0)
9972 return 0;
9974 /* Check we have all 1's above the transition, and reject all 1's. */
9975 return c == -lsb && lsb != 1;
9977 else if (GET_CODE (andop) == CONST_DOUBLE
9978 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9980 HOST_WIDE_INT low, lsb, shift_mask_low;
9982 low = CONST_DOUBLE_LOW (andop);
9984 if (HOST_BITS_PER_WIDE_INT < 64)
9986 HOST_WIDE_INT high, shift_mask_high;
9988 high = CONST_DOUBLE_HIGH (andop);
9990 if (low == 0)
9992 shift_mask_high = ~0;
9993 if (INTVAL (shiftop) > 32)
9994 shift_mask_high <<= INTVAL (shiftop) - 32;
9996 lsb = high & -high;
9998 if ((lsb & shift_mask_high) == 0)
9999 return 0;
10001 return high == -lsb;
10003 if (high != ~0)
10004 return 0;
10007 shift_mask_low = ~0;
10008 shift_mask_low <<= INTVAL (shiftop);
10010 lsb = low & -low;
10012 if ((lsb & shift_mask_low) == 0)
10013 return 0;
10015 return low == -lsb && lsb != 1;
10017 else
10018 return 0;
10021 /* Return 1 if operands will generate a valid arguments to rlwimi
10022 instruction for insert with right shift in 64-bit mode. The mask may
10023 not start on the first bit or stop on the last bit because wrap-around
10024 effects of instruction do not correspond to semantics of RTL insn. */
10027 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
10029 if (INTVAL (startop) > 32
10030 && INTVAL (startop) < 64
10031 && INTVAL (sizeop) > 1
10032 && INTVAL (sizeop) + INTVAL (startop) < 64
10033 && INTVAL (shiftop) > 0
10034 && INTVAL (sizeop) + INTVAL (shiftop) < 32
10035 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
10036 return 1;
10038 return 0;
10041 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
10042 for lfq and stfq insns iff the registers are hard registers. */
10045 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
10047 /* We might have been passed a SUBREG. */
10048 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
10049 return 0;
10051 /* We might have been passed non floating point registers. */
10052 if (!FP_REGNO_P (REGNO (reg1))
10053 || !FP_REGNO_P (REGNO (reg2)))
10054 return 0;
10056 return (REGNO (reg1) == REGNO (reg2) - 1);
10059 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
10060 addr1 and addr2 must be in consecutive memory locations
10061 (addr2 == addr1 + 8). */
10064 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
10066 rtx addr1, addr2;
10067 unsigned int reg1, reg2;
10068 int offset1, offset2;
10070 /* The mems cannot be volatile. */
10071 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
10072 return 0;
10074 addr1 = XEXP (mem1, 0);
10075 addr2 = XEXP (mem2, 0);
10077 /* Extract an offset (if used) from the first addr. */
10078 if (GET_CODE (addr1) == PLUS)
10080 /* If not a REG, return zero. */
10081 if (GET_CODE (XEXP (addr1, 0)) != REG)
10082 return 0;
10083 else
10085 reg1 = REGNO (XEXP (addr1, 0));
10086 /* The offset must be constant! */
10087 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
10088 return 0;
10089 offset1 = INTVAL (XEXP (addr1, 1));
10092 else if (GET_CODE (addr1) != REG)
10093 return 0;
10094 else
10096 reg1 = REGNO (addr1);
10097 /* This was a simple (mem (reg)) expression. Offset is 0. */
10098 offset1 = 0;
10101 /* And now for the second addr. */
10102 if (GET_CODE (addr2) == PLUS)
10104 /* If not a REG, return zero. */
10105 if (GET_CODE (XEXP (addr2, 0)) != REG)
10106 return 0;
10107 else
10109 reg2 = REGNO (XEXP (addr2, 0));
10110 /* The offset must be constant. */
10111 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
10112 return 0;
10113 offset2 = INTVAL (XEXP (addr2, 1));
10116 else if (GET_CODE (addr2) != REG)
10117 return 0;
10118 else
10120 reg2 = REGNO (addr2);
10121 /* This was a simple (mem (reg)) expression. Offset is 0. */
10122 offset2 = 0;
10125 /* Both of these must have the same base register. */
10126 if (reg1 != reg2)
10127 return 0;
10129 /* The offset for the second addr must be 8 more than the first addr. */
10130 if (offset2 != offset1 + 8)
10131 return 0;
10133 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
10134 instructions. */
10135 return 1;
10138 /* Return the register class of a scratch register needed to copy IN into
10139 or out of a register in CLASS in MODE. If it can be done directly,
10140 NO_REGS is returned. */
10142 enum reg_class
10143 rs6000_secondary_reload_class (enum reg_class class,
10144 enum machine_mode mode ATTRIBUTE_UNUSED,
10145 rtx in)
10147 int regno;
10149 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
10150 #if TARGET_MACHO
10151 && MACHOPIC_INDIRECT
10152 #endif
10155 /* We cannot copy a symbolic operand directly into anything
10156 other than BASE_REGS for TARGET_ELF. So indicate that a
10157 register from BASE_REGS is needed as an intermediate
10158 register.
10160 On Darwin, pic addresses require a load from memory, which
10161 needs a base register. */
10162 if (class != BASE_REGS
10163 && (GET_CODE (in) == SYMBOL_REF
10164 || GET_CODE (in) == HIGH
10165 || GET_CODE (in) == LABEL_REF
10166 || GET_CODE (in) == CONST))
10167 return BASE_REGS;
10170 if (GET_CODE (in) == REG)
10172 regno = REGNO (in);
10173 if (regno >= FIRST_PSEUDO_REGISTER)
10175 regno = true_regnum (in);
10176 if (regno >= FIRST_PSEUDO_REGISTER)
10177 regno = -1;
10180 else if (GET_CODE (in) == SUBREG)
10182 regno = true_regnum (in);
10183 if (regno >= FIRST_PSEUDO_REGISTER)
10184 regno = -1;
10186 else
10187 regno = -1;
10189 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
10190 into anything. */
10191 if (class == GENERAL_REGS || class == BASE_REGS
10192 || (regno >= 0 && INT_REGNO_P (regno)))
10193 return NO_REGS;
10195 /* Constants, memory, and FP registers can go into FP registers. */
10196 if ((regno == -1 || FP_REGNO_P (regno))
10197 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
10198 return NO_REGS;
10200 /* Memory, and AltiVec registers can go into AltiVec registers. */
10201 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
10202 && class == ALTIVEC_REGS)
10203 return NO_REGS;
10205 /* We can copy among the CR registers. */
10206 if ((class == CR_REGS || class == CR0_REGS)
10207 && regno >= 0 && CR_REGNO_P (regno))
10208 return NO_REGS;
10210 /* Otherwise, we need GENERAL_REGS. */
10211 return GENERAL_REGS;
10214 /* Given a comparison operation, return the bit number in CCR to test. We
10215 know this is a valid comparison.
10217 SCC_P is 1 if this is for an scc. That means that %D will have been
10218 used instead of %C, so the bits will be in different places.
10220 Return -1 if OP isn't a valid comparison for some reason. */
10223 ccr_bit (rtx op, int scc_p)
10225 enum rtx_code code = GET_CODE (op);
10226 enum machine_mode cc_mode;
10227 int cc_regnum;
10228 int base_bit;
10229 rtx reg;
10231 if (!COMPARISON_P (op))
10232 return -1;
10234 reg = XEXP (op, 0);
10236 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
10238 cc_mode = GET_MODE (reg);
10239 cc_regnum = REGNO (reg);
10240 base_bit = 4 * (cc_regnum - CR0_REGNO);
10242 validate_condition_mode (code, cc_mode);
10244 /* When generating a sCOND operation, only positive conditions are
10245 allowed. */
10246 gcc_assert (!scc_p
10247 || code == EQ || code == GT || code == LT || code == UNORDERED
10248 || code == GTU || code == LTU);
10250 switch (code)
10252 case NE:
10253 return scc_p ? base_bit + 3 : base_bit + 2;
10254 case EQ:
10255 return base_bit + 2;
10256 case GT: case GTU: case UNLE:
10257 return base_bit + 1;
10258 case LT: case LTU: case UNGE:
10259 return base_bit;
10260 case ORDERED: case UNORDERED:
10261 return base_bit + 3;
10263 case GE: case GEU:
10264 /* If scc, we will have done a cror to put the bit in the
10265 unordered position. So test that bit. For integer, this is ! LT
10266 unless this is an scc insn. */
10267 return scc_p ? base_bit + 3 : base_bit;
10269 case LE: case LEU:
10270 return scc_p ? base_bit + 3 : base_bit + 1;
10272 default:
10273 gcc_unreachable ();
10277 /* Return the GOT register. */
10280 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
10282 /* The second flow pass currently (June 1999) can't update
10283 regs_ever_live without disturbing other parts of the compiler, so
10284 update it here to make the prolog/epilogue code happy. */
10285 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
10286 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
10288 current_function_uses_pic_offset_table = 1;
10290 return pic_offset_table_rtx;
10293 /* Function to init struct machine_function.
10294 This will be called, via a pointer variable,
10295 from push_function_context. */
10297 static struct machine_function *
10298 rs6000_init_machine_status (void)
10300 return ggc_alloc_cleared (sizeof (machine_function));
10303 /* These macros test for integers and extract the low-order bits. */
10304 #define INT_P(X) \
10305 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
10306 && GET_MODE (X) == VOIDmode)
10308 #define INT_LOWPART(X) \
10309 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
10312 extract_MB (rtx op)
10314 int i;
10315 unsigned long val = INT_LOWPART (op);
10317 /* If the high bit is zero, the value is the first 1 bit we find
10318 from the left. */
10319 if ((val & 0x80000000) == 0)
10321 gcc_assert (val & 0xffffffff);
10323 i = 1;
10324 while (((val <<= 1) & 0x80000000) == 0)
10325 ++i;
10326 return i;
10329 /* If the high bit is set and the low bit is not, or the mask is all
10330 1's, the value is zero. */
10331 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
10332 return 0;
10334 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10335 from the right. */
10336 i = 31;
10337 while (((val >>= 1) & 1) != 0)
10338 --i;
10340 return i;
10344 extract_ME (rtx op)
10346 int i;
10347 unsigned long val = INT_LOWPART (op);
10349 /* If the low bit is zero, the value is the first 1 bit we find from
10350 the right. */
10351 if ((val & 1) == 0)
10353 gcc_assert (val & 0xffffffff);
10355 i = 30;
10356 while (((val >>= 1) & 1) == 0)
10357 --i;
10359 return i;
10362 /* If the low bit is set and the high bit is not, or the mask is all
10363 1's, the value is 31. */
10364 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
10365 return 31;
10367 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10368 from the left. */
10369 i = 0;
10370 while (((val <<= 1) & 0x80000000) != 0)
10371 ++i;
10373 return i;
10376 /* Locate some local-dynamic symbol still in use by this function
10377 so that we can print its name in some tls_ld pattern. */
10379 static const char *
10380 rs6000_get_some_local_dynamic_name (void)
10382 rtx insn;
10384 if (cfun->machine->some_ld_name)
10385 return cfun->machine->some_ld_name;
10387 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
10388 if (INSN_P (insn)
10389 && for_each_rtx (&PATTERN (insn),
10390 rs6000_get_some_local_dynamic_name_1, 0))
10391 return cfun->machine->some_ld_name;
10393 gcc_unreachable ();
10396 /* Helper function for rs6000_get_some_local_dynamic_name. */
10398 static int
10399 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
10401 rtx x = *px;
10403 if (GET_CODE (x) == SYMBOL_REF)
10405 const char *str = XSTR (x, 0);
10406 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
10408 cfun->machine->some_ld_name = str;
10409 return 1;
10413 return 0;
10416 /* Write out a function code label. */
10418 void
10419 rs6000_output_function_entry (FILE *file, const char *fname)
10421 if (fname[0] != '.')
10423 switch (DEFAULT_ABI)
10425 default:
10426 gcc_unreachable ();
10428 case ABI_AIX:
10429 if (DOT_SYMBOLS)
10430 putc ('.', file);
10431 else
10432 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
10433 break;
10435 case ABI_V4:
10436 case ABI_DARWIN:
10437 break;
10440 if (TARGET_AIX)
10441 RS6000_OUTPUT_BASENAME (file, fname);
10442 else
10443 assemble_name (file, fname);
10446 /* Print an operand. Recognize special options, documented below. */
10448 #if TARGET_ELF
10449 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
10450 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
10451 #else
10452 #define SMALL_DATA_RELOC "sda21"
10453 #define SMALL_DATA_REG 0
10454 #endif
10456 void
10457 print_operand (FILE *file, rtx x, int code)
10459 int i;
10460 HOST_WIDE_INT val;
10461 unsigned HOST_WIDE_INT uval;
10463 switch (code)
10465 case '.':
10466 /* Write out an instruction after the call which may be replaced
10467 with glue code by the loader. This depends on the AIX version. */
10468 asm_fprintf (file, RS6000_CALL_GLUE);
10469 return;
10471 /* %a is output_address. */
10473 case 'A':
10474 /* If X is a constant integer whose low-order 5 bits are zero,
10475 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10476 in the AIX assembler where "sri" with a zero shift count
10477 writes a trash instruction. */
10478 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
10479 putc ('l', file);
10480 else
10481 putc ('r', file);
10482 return;
10484 case 'b':
10485 /* If constant, low-order 16 bits of constant, unsigned.
10486 Otherwise, write normally. */
10487 if (INT_P (x))
10488 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
10489 else
10490 print_operand (file, x, 0);
10491 return;
10493 case 'B':
10494 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10495 for 64-bit mask direction. */
10496 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
10497 return;
10499 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10500 output_operand. */
10502 case 'c':
10503 /* X is a CR register. Print the number of the GT bit of the CR. */
10504 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10505 output_operand_lossage ("invalid %%E value");
10506 else
10507 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
10508 return;
10510 case 'D':
10511 /* Like 'J' but get to the GT bit only. */
10512 gcc_assert (GET_CODE (x) == REG);
10514 /* Bit 1 is GT bit. */
10515 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
10517 /* Add one for shift count in rlinm for scc. */
10518 fprintf (file, "%d", i + 1);
10519 return;
10521 case 'E':
10522 /* X is a CR register. Print the number of the EQ bit of the CR */
10523 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10524 output_operand_lossage ("invalid %%E value");
10525 else
10526 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
10527 return;
10529 case 'f':
10530 /* X is a CR register. Print the shift count needed to move it
10531 to the high-order four bits. */
10532 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10533 output_operand_lossage ("invalid %%f value");
10534 else
10535 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
10536 return;
10538 case 'F':
10539 /* Similar, but print the count for the rotate in the opposite
10540 direction. */
10541 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10542 output_operand_lossage ("invalid %%F value");
10543 else
10544 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
10545 return;
10547 case 'G':
10548 /* X is a constant integer. If it is negative, print "m",
10549 otherwise print "z". This is to make an aze or ame insn. */
10550 if (GET_CODE (x) != CONST_INT)
10551 output_operand_lossage ("invalid %%G value");
10552 else if (INTVAL (x) >= 0)
10553 putc ('z', file);
10554 else
10555 putc ('m', file);
10556 return;
10558 case 'h':
10559 /* If constant, output low-order five bits. Otherwise, write
10560 normally. */
10561 if (INT_P (x))
10562 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
10563 else
10564 print_operand (file, x, 0);
10565 return;
10567 case 'H':
10568 /* If constant, output low-order six bits. Otherwise, write
10569 normally. */
10570 if (INT_P (x))
10571 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
10572 else
10573 print_operand (file, x, 0);
10574 return;
10576 case 'I':
10577 /* Print `i' if this is a constant, else nothing. */
10578 if (INT_P (x))
10579 putc ('i', file);
10580 return;
10582 case 'j':
10583 /* Write the bit number in CCR for jump. */
10584 i = ccr_bit (x, 0);
10585 if (i == -1)
10586 output_operand_lossage ("invalid %%j code");
10587 else
10588 fprintf (file, "%d", i);
10589 return;
10591 case 'J':
10592 /* Similar, but add one for shift count in rlinm for scc and pass
10593 scc flag to `ccr_bit'. */
10594 i = ccr_bit (x, 1);
10595 if (i == -1)
10596 output_operand_lossage ("invalid %%J code");
10597 else
10598 /* If we want bit 31, write a shift count of zero, not 32. */
10599 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10600 return;
10602 case 'k':
10603 /* X must be a constant. Write the 1's complement of the
10604 constant. */
10605 if (! INT_P (x))
10606 output_operand_lossage ("invalid %%k value");
10607 else
10608 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
10609 return;
10611 case 'K':
10612 /* X must be a symbolic constant on ELF. Write an
10613 expression suitable for an 'addi' that adds in the low 16
10614 bits of the MEM. */
10615 if (GET_CODE (x) != CONST)
10617 print_operand_address (file, x);
10618 fputs ("@l", file);
10620 else
10622 if (GET_CODE (XEXP (x, 0)) != PLUS
10623 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
10624 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
10625 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
10626 output_operand_lossage ("invalid %%K value");
10627 print_operand_address (file, XEXP (XEXP (x, 0), 0));
10628 fputs ("@l", file);
10629 /* For GNU as, there must be a non-alphanumeric character
10630 between 'l' and the number. The '-' is added by
10631 print_operand() already. */
10632 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
10633 fputs ("+", file);
10634 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
10636 return;
10638 /* %l is output_asm_label. */
10640 case 'L':
10641 /* Write second word of DImode or DFmode reference. Works on register
10642 or non-indexed memory only. */
10643 if (GET_CODE (x) == REG)
10644 fputs (reg_names[REGNO (x) + 1], file);
10645 else if (GET_CODE (x) == MEM)
10647 /* Handle possible auto-increment. Since it is pre-increment and
10648 we have already done it, we can just use an offset of word. */
10649 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10650 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10651 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
10652 UNITS_PER_WORD));
10653 else
10654 output_address (XEXP (adjust_address_nv (x, SImode,
10655 UNITS_PER_WORD),
10656 0));
10658 if (small_data_operand (x, GET_MODE (x)))
10659 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10660 reg_names[SMALL_DATA_REG]);
10662 return;
10664 case 'm':
10665 /* MB value for a mask operand. */
10666 if (! mask_operand (x, SImode))
10667 output_operand_lossage ("invalid %%m value");
10669 fprintf (file, "%d", extract_MB (x));
10670 return;
10672 case 'M':
10673 /* ME value for a mask operand. */
10674 if (! mask_operand (x, SImode))
10675 output_operand_lossage ("invalid %%M value");
10677 fprintf (file, "%d", extract_ME (x));
10678 return;
10680 /* %n outputs the negative of its operand. */
10682 case 'N':
10683 /* Write the number of elements in the vector times 4. */
10684 if (GET_CODE (x) != PARALLEL)
10685 output_operand_lossage ("invalid %%N value");
10686 else
10687 fprintf (file, "%d", XVECLEN (x, 0) * 4);
10688 return;
10690 case 'O':
10691 /* Similar, but subtract 1 first. */
10692 if (GET_CODE (x) != PARALLEL)
10693 output_operand_lossage ("invalid %%O value");
10694 else
10695 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
10696 return;
10698 case 'p':
10699 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10700 if (! INT_P (x)
10701 || INT_LOWPART (x) < 0
10702 || (i = exact_log2 (INT_LOWPART (x))) < 0)
10703 output_operand_lossage ("invalid %%p value");
10704 else
10705 fprintf (file, "%d", i);
10706 return;
10708 case 'P':
10709 /* The operand must be an indirect memory reference. The result
10710 is the register name. */
10711 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
10712 || REGNO (XEXP (x, 0)) >= 32)
10713 output_operand_lossage ("invalid %%P value");
10714 else
10715 fputs (reg_names[REGNO (XEXP (x, 0))], file);
10716 return;
10718 case 'q':
10719 /* This outputs the logical code corresponding to a boolean
10720 expression. The expression may have one or both operands
10721 negated (if one, only the first one). For condition register
10722 logical operations, it will also treat the negated
10723 CR codes as NOTs, but not handle NOTs of them. */
10725 const char *const *t = 0;
10726 const char *s;
10727 enum rtx_code code = GET_CODE (x);
10728 static const char * const tbl[3][3] = {
10729 { "and", "andc", "nor" },
10730 { "or", "orc", "nand" },
10731 { "xor", "eqv", "xor" } };
10733 if (code == AND)
10734 t = tbl[0];
10735 else if (code == IOR)
10736 t = tbl[1];
10737 else if (code == XOR)
10738 t = tbl[2];
10739 else
10740 output_operand_lossage ("invalid %%q value");
10742 if (GET_CODE (XEXP (x, 0)) != NOT)
10743 s = t[0];
10744 else
10746 if (GET_CODE (XEXP (x, 1)) == NOT)
10747 s = t[2];
10748 else
10749 s = t[1];
10752 fputs (s, file);
10754 return;
10756 case 'Q':
10757 if (TARGET_MFCRF)
10758 fputc (',', file);
10759 /* FALLTHRU */
10760 else
10761 return;
10763 case 'R':
10764 /* X is a CR register. Print the mask for `mtcrf'. */
10765 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10766 output_operand_lossage ("invalid %%R value");
10767 else
10768 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
10769 return;
10771 case 's':
10772 /* Low 5 bits of 32 - value */
10773 if (! INT_P (x))
10774 output_operand_lossage ("invalid %%s value");
10775 else
10776 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
10777 return;
10779 case 'S':
10780 /* PowerPC64 mask position. All 0's is excluded.
10781 CONST_INT 32-bit mask is considered sign-extended so any
10782 transition must occur within the CONST_INT, not on the boundary. */
10783 if (! mask64_operand (x, DImode))
10784 output_operand_lossage ("invalid %%S value");
10786 uval = INT_LOWPART (x);
10788 if (uval & 1) /* Clear Left */
10790 #if HOST_BITS_PER_WIDE_INT > 64
10791 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10792 #endif
10793 i = 64;
10795 else /* Clear Right */
10797 uval = ~uval;
10798 #if HOST_BITS_PER_WIDE_INT > 64
10799 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10800 #endif
10801 i = 63;
10803 while (uval != 0)
10804 --i, uval >>= 1;
10805 gcc_assert (i >= 0);
10806 fprintf (file, "%d", i);
10807 return;
10809 case 't':
10810 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10811 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
10813 /* Bit 3 is OV bit. */
10814 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
10816 /* If we want bit 31, write a shift count of zero, not 32. */
10817 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10818 return;
10820 case 'T':
10821 /* Print the symbolic name of a branch target register. */
10822 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
10823 && REGNO (x) != COUNT_REGISTER_REGNUM))
10824 output_operand_lossage ("invalid %%T value");
10825 else if (REGNO (x) == LINK_REGISTER_REGNUM)
10826 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
10827 else
10828 fputs ("ctr", file);
10829 return;
10831 case 'u':
10832 /* High-order 16 bits of constant for use in unsigned operand. */
10833 if (! INT_P (x))
10834 output_operand_lossage ("invalid %%u value");
10835 else
10836 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10837 (INT_LOWPART (x) >> 16) & 0xffff);
10838 return;
10840 case 'v':
10841 /* High-order 16 bits of constant for use in signed operand. */
10842 if (! INT_P (x))
10843 output_operand_lossage ("invalid %%v value");
10844 else
10845 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10846 (INT_LOWPART (x) >> 16) & 0xffff);
10847 return;
10849 case 'U':
10850 /* Print `u' if this has an auto-increment or auto-decrement. */
10851 if (GET_CODE (x) == MEM
10852 && (GET_CODE (XEXP (x, 0)) == PRE_INC
10853 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
10854 putc ('u', file);
10855 return;
10857 case 'V':
10858 /* Print the trap code for this operand. */
10859 switch (GET_CODE (x))
10861 case EQ:
10862 fputs ("eq", file); /* 4 */
10863 break;
10864 case NE:
10865 fputs ("ne", file); /* 24 */
10866 break;
10867 case LT:
10868 fputs ("lt", file); /* 16 */
10869 break;
10870 case LE:
10871 fputs ("le", file); /* 20 */
10872 break;
10873 case GT:
10874 fputs ("gt", file); /* 8 */
10875 break;
10876 case GE:
10877 fputs ("ge", file); /* 12 */
10878 break;
10879 case LTU:
10880 fputs ("llt", file); /* 2 */
10881 break;
10882 case LEU:
10883 fputs ("lle", file); /* 6 */
10884 break;
10885 case GTU:
10886 fputs ("lgt", file); /* 1 */
10887 break;
10888 case GEU:
10889 fputs ("lge", file); /* 5 */
10890 break;
10891 default:
10892 gcc_unreachable ();
10894 break;
10896 case 'w':
10897 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10898 normally. */
10899 if (INT_P (x))
10900 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
10901 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
10902 else
10903 print_operand (file, x, 0);
10904 return;
10906 case 'W':
10907 /* MB value for a PowerPC64 rldic operand. */
10908 val = (GET_CODE (x) == CONST_INT
10909 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
10911 if (val < 0)
10912 i = -1;
10913 else
10914 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
10915 if ((val <<= 1) < 0)
10916 break;
10918 #if HOST_BITS_PER_WIDE_INT == 32
10919 if (GET_CODE (x) == CONST_INT && i >= 0)
10920 i += 32; /* zero-extend high-part was all 0's */
10921 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
10923 val = CONST_DOUBLE_LOW (x);
10925 gcc_assert (val);
10926 if (val < 0)
10927 --i;
10928 else
10929 for ( ; i < 64; i++)
10930 if ((val <<= 1) < 0)
10931 break;
10933 #endif
10935 fprintf (file, "%d", i + 1);
10936 return;
10938 case 'X':
10939 if (GET_CODE (x) == MEM
10940 && legitimate_indexed_address_p (XEXP (x, 0), 0))
10941 putc ('x', file);
10942 return;
10944 case 'Y':
10945 /* Like 'L', for third word of TImode */
10946 if (GET_CODE (x) == REG)
10947 fputs (reg_names[REGNO (x) + 2], file);
10948 else if (GET_CODE (x) == MEM)
10950 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10951 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10952 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
10953 else
10954 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
10955 if (small_data_operand (x, GET_MODE (x)))
10956 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10957 reg_names[SMALL_DATA_REG]);
10959 return;
10961 case 'z':
10962 /* X is a SYMBOL_REF. Write out the name preceded by a
10963 period and without any trailing data in brackets. Used for function
10964 names. If we are configured for System V (or the embedded ABI) on
10965 the PowerPC, do not emit the period, since those systems do not use
10966 TOCs and the like. */
10967 gcc_assert (GET_CODE (x) == SYMBOL_REF);
10969 /* Mark the decl as referenced so that cgraph will output the
10970 function. */
10971 if (SYMBOL_REF_DECL (x))
10972 mark_decl_referenced (SYMBOL_REF_DECL (x));
10974 /* For macho, check to see if we need a stub. */
10975 if (TARGET_MACHO)
10977 const char *name = XSTR (x, 0);
10978 #if TARGET_MACHO
10979 if (MACHOPIC_INDIRECT
10980 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
10981 name = machopic_indirection_name (x, /*stub_p=*/true);
10982 #endif
10983 assemble_name (file, name);
10985 else if (!DOT_SYMBOLS)
10986 assemble_name (file, XSTR (x, 0));
10987 else
10988 rs6000_output_function_entry (file, XSTR (x, 0));
10989 return;
10991 case 'Z':
10992 /* Like 'L', for last word of TImode. */
10993 if (GET_CODE (x) == REG)
10994 fputs (reg_names[REGNO (x) + 3], file);
10995 else if (GET_CODE (x) == MEM)
10997 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10998 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10999 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
11000 else
11001 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
11002 if (small_data_operand (x, GET_MODE (x)))
11003 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11004 reg_names[SMALL_DATA_REG]);
11006 return;
11008 /* Print AltiVec or SPE memory operand. */
11009 case 'y':
11011 rtx tmp;
11013 gcc_assert (GET_CODE (x) == MEM);
11015 tmp = XEXP (x, 0);
11017 /* Ugly hack because %y is overloaded. */
11018 if ((TARGET_SPE || TARGET_E500_DOUBLE)
11019 && GET_MODE_SIZE (GET_MODE (x)) == 8)
11021 /* Handle [reg]. */
11022 if (GET_CODE (tmp) == REG)
11024 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
11025 break;
11027 /* Handle [reg+UIMM]. */
11028 else if (GET_CODE (tmp) == PLUS &&
11029 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
11031 int x;
11033 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
11035 x = INTVAL (XEXP (tmp, 1));
11036 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
11037 break;
11040 /* Fall through. Must be [reg+reg]. */
11042 if (TARGET_ALTIVEC
11043 && GET_CODE (tmp) == AND
11044 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
11045 && INTVAL (XEXP (tmp, 1)) == -16)
11046 tmp = XEXP (tmp, 0);
11047 if (GET_CODE (tmp) == REG)
11048 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
11049 else
11051 gcc_assert (GET_CODE (tmp) == PLUS
11052 && REG_P (XEXP (tmp, 0))
11053 && REG_P (XEXP (tmp, 1)));
11055 if (REGNO (XEXP (tmp, 0)) == 0)
11056 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
11057 reg_names[ REGNO (XEXP (tmp, 0)) ]);
11058 else
11059 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
11060 reg_names[ REGNO (XEXP (tmp, 1)) ]);
11062 break;
11065 case 0:
11066 if (GET_CODE (x) == REG)
11067 fprintf (file, "%s", reg_names[REGNO (x)]);
11068 else if (GET_CODE (x) == MEM)
11070 /* We need to handle PRE_INC and PRE_DEC here, since we need to
11071 know the width from the mode. */
11072 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
11073 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
11074 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
11075 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
11076 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
11077 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
11078 else
11079 output_address (XEXP (x, 0));
11081 else
11082 output_addr_const (file, x);
11083 return;
11085 case '&':
11086 assemble_name (file, rs6000_get_some_local_dynamic_name ());
11087 return;
11089 default:
11090 output_operand_lossage ("invalid %%xn code");
11094 /* Print the address of an operand. */
11096 void
11097 print_operand_address (FILE *file, rtx x)
11099 if (GET_CODE (x) == REG)
11100 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
11101 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
11102 || GET_CODE (x) == LABEL_REF)
11104 output_addr_const (file, x);
11105 if (small_data_operand (x, GET_MODE (x)))
11106 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11107 reg_names[SMALL_DATA_REG]);
11108 else
11109 gcc_assert (!TARGET_TOC);
11111 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
11113 gcc_assert (REG_P (XEXP (x, 0)));
11114 if (REGNO (XEXP (x, 0)) == 0)
11115 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
11116 reg_names[ REGNO (XEXP (x, 0)) ]);
11117 else
11118 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
11119 reg_names[ REGNO (XEXP (x, 1)) ]);
11121 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
11122 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
11123 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
11124 #if TARGET_ELF
11125 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
11126 && CONSTANT_P (XEXP (x, 1)))
11128 output_addr_const (file, XEXP (x, 1));
11129 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
11131 #endif
11132 #if TARGET_MACHO
11133 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
11134 && CONSTANT_P (XEXP (x, 1)))
11136 fprintf (file, "lo16(");
11137 output_addr_const (file, XEXP (x, 1));
11138 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
11140 #endif
11141 else if (legitimate_constant_pool_address_p (x))
11143 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
11145 rtx contains_minus = XEXP (x, 1);
11146 rtx minus, symref;
11147 const char *name;
11149 /* Find the (minus (sym) (toc)) buried in X, and temporarily
11150 turn it into (sym) for output_addr_const. */
11151 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
11152 contains_minus = XEXP (contains_minus, 0);
11154 minus = XEXP (contains_minus, 0);
11155 symref = XEXP (minus, 0);
11156 XEXP (contains_minus, 0) = symref;
11157 if (TARGET_ELF)
11159 char *newname;
11161 name = XSTR (symref, 0);
11162 newname = alloca (strlen (name) + sizeof ("@toc"));
11163 strcpy (newname, name);
11164 strcat (newname, "@toc");
11165 XSTR (symref, 0) = newname;
11167 output_addr_const (file, XEXP (x, 1));
11168 if (TARGET_ELF)
11169 XSTR (symref, 0) = name;
11170 XEXP (contains_minus, 0) = minus;
11172 else
11173 output_addr_const (file, XEXP (x, 1));
11175 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
11177 else
11178 gcc_unreachable ();
11181 /* Target hook for assembling integer objects. The PowerPC version has
11182 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
11183 is defined. It also needs to handle DI-mode objects on 64-bit
11184 targets. */
11186 static bool
11187 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
11189 #ifdef RELOCATABLE_NEEDS_FIXUP
11190 /* Special handling for SI values. */
11191 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
11193 static int recurse = 0;
11195 /* For -mrelocatable, we mark all addresses that need to be fixed up
11196 in the .fixup section. */
11197 if (TARGET_RELOCATABLE
11198 && in_section != toc_section
11199 && in_section != text_section
11200 && !unlikely_text_section_p (in_section)
11201 && !recurse
11202 && GET_CODE (x) != CONST_INT
11203 && GET_CODE (x) != CONST_DOUBLE
11204 && CONSTANT_P (x))
11206 char buf[256];
11208 recurse = 1;
11209 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
11210 fixuplabelno++;
11211 ASM_OUTPUT_LABEL (asm_out_file, buf);
11212 fprintf (asm_out_file, "\t.long\t(");
11213 output_addr_const (asm_out_file, x);
11214 fprintf (asm_out_file, ")@fixup\n");
11215 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
11216 ASM_OUTPUT_ALIGN (asm_out_file, 2);
11217 fprintf (asm_out_file, "\t.long\t");
11218 assemble_name (asm_out_file, buf);
11219 fprintf (asm_out_file, "\n\t.previous\n");
11220 recurse = 0;
11221 return true;
11223 /* Remove initial .'s to turn a -mcall-aixdesc function
11224 address into the address of the descriptor, not the function
11225 itself. */
11226 else if (GET_CODE (x) == SYMBOL_REF
11227 && XSTR (x, 0)[0] == '.'
11228 && DEFAULT_ABI == ABI_AIX)
11230 const char *name = XSTR (x, 0);
11231 while (*name == '.')
11232 name++;
11234 fprintf (asm_out_file, "\t.long\t%s\n", name);
11235 return true;
11238 #endif /* RELOCATABLE_NEEDS_FIXUP */
11239 return default_assemble_integer (x, size, aligned_p);
11242 #ifdef HAVE_GAS_HIDDEN
11243 /* Emit an assembler directive to set symbol visibility for DECL to
11244 VISIBILITY_TYPE. */
11246 static void
11247 rs6000_assemble_visibility (tree decl, int vis)
11249 /* Functions need to have their entry point symbol visibility set as
11250 well as their descriptor symbol visibility. */
11251 if (DEFAULT_ABI == ABI_AIX
11252 && DOT_SYMBOLS
11253 && TREE_CODE (decl) == FUNCTION_DECL)
11255 static const char * const visibility_types[] = {
11256 NULL, "internal", "hidden", "protected"
11259 const char *name, *type;
11261 name = ((* targetm.strip_name_encoding)
11262 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
11263 type = visibility_types[vis];
11265 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
11266 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
11268 else
11269 default_assemble_visibility (decl, vis);
11271 #endif
11273 enum rtx_code
11274 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
11276 /* Reversal of FP compares takes care -- an ordered compare
11277 becomes an unordered compare and vice versa. */
11278 if (mode == CCFPmode
11279 && (!flag_finite_math_only
11280 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
11281 || code == UNEQ || code == LTGT))
11282 return reverse_condition_maybe_unordered (code);
11283 else
11284 return reverse_condition (code);
11287 /* Generate a compare for CODE. Return a brand-new rtx that
11288 represents the result of the compare. */
11290 static rtx
11291 rs6000_generate_compare (enum rtx_code code)
11293 enum machine_mode comp_mode;
11294 rtx compare_result;
11296 if (rs6000_compare_fp_p)
11297 comp_mode = CCFPmode;
11298 else if (code == GTU || code == LTU
11299 || code == GEU || code == LEU)
11300 comp_mode = CCUNSmode;
11301 else if ((code == EQ || code == NE)
11302 && GET_CODE (rs6000_compare_op0) == SUBREG
11303 && GET_CODE (rs6000_compare_op1) == SUBREG
11304 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
11305 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
11306 /* These are unsigned values, perhaps there will be a later
11307 ordering compare that can be shared with this one.
11308 Unfortunately we cannot detect the signedness of the operands
11309 for non-subregs. */
11310 comp_mode = CCUNSmode;
11311 else
11312 comp_mode = CCmode;
11314 /* First, the compare. */
11315 compare_result = gen_reg_rtx (comp_mode);
11317 /* E500 FP compare instructions on the GPRs. Yuck! */
11318 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
11319 && rs6000_compare_fp_p)
11321 rtx cmp, or_result, compare_result2;
11322 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
11324 if (op_mode == VOIDmode)
11325 op_mode = GET_MODE (rs6000_compare_op1);
11327 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
11328 This explains the following mess. */
11330 switch (code)
11332 case EQ: case UNEQ: case NE: case LTGT:
11333 switch (op_mode)
11335 case SFmode:
11336 cmp = flag_unsafe_math_optimizations
11337 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
11338 rs6000_compare_op1)
11339 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
11340 rs6000_compare_op1);
11341 break;
11343 case DFmode:
11344 cmp = flag_unsafe_math_optimizations
11345 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
11346 rs6000_compare_op1)
11347 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
11348 rs6000_compare_op1);
11349 break;
11351 default:
11352 gcc_unreachable ();
11354 break;
11356 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
11357 switch (op_mode)
11359 case SFmode:
11360 cmp = flag_unsafe_math_optimizations
11361 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
11362 rs6000_compare_op1)
11363 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
11364 rs6000_compare_op1);
11365 break;
11367 case DFmode:
11368 cmp = flag_unsafe_math_optimizations
11369 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
11370 rs6000_compare_op1)
11371 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
11372 rs6000_compare_op1);
11373 break;
11375 default:
11376 gcc_unreachable ();
11378 break;
11380 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
11381 switch (op_mode)
11383 case SFmode:
11384 cmp = flag_unsafe_math_optimizations
11385 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
11386 rs6000_compare_op1)
11387 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
11388 rs6000_compare_op1);
11389 break;
11391 case DFmode:
11392 cmp = flag_unsafe_math_optimizations
11393 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
11394 rs6000_compare_op1)
11395 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
11396 rs6000_compare_op1);
11397 break;
11399 default:
11400 gcc_unreachable ();
11402 break;
11403 default:
11404 gcc_unreachable ();
11407 /* Synthesize LE and GE from LT/GT || EQ. */
11408 if (code == LE || code == GE || code == LEU || code == GEU)
11410 emit_insn (cmp);
11412 switch (code)
11414 case LE: code = LT; break;
11415 case GE: code = GT; break;
11416 case LEU: code = LT; break;
11417 case GEU: code = GT; break;
11418 default: gcc_unreachable ();
11421 compare_result2 = gen_reg_rtx (CCFPmode);
11423 /* Do the EQ. */
11424 switch (op_mode)
11426 case SFmode:
11427 cmp = flag_unsafe_math_optimizations
11428 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
11429 rs6000_compare_op1)
11430 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
11431 rs6000_compare_op1);
11432 break;
11434 case DFmode:
11435 cmp = flag_unsafe_math_optimizations
11436 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
11437 rs6000_compare_op1)
11438 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
11439 rs6000_compare_op1);
11440 break;
11442 default:
11443 gcc_unreachable ();
11445 emit_insn (cmp);
11447 /* OR them together. */
11448 or_result = gen_reg_rtx (CCFPmode);
11449 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
11450 compare_result2);
11451 compare_result = or_result;
11452 code = EQ;
11454 else
11456 if (code == NE || code == LTGT)
11457 code = NE;
11458 else
11459 code = EQ;
11462 emit_insn (cmp);
11464 else
11466 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11467 CLOBBERs to match cmptf_internal2 pattern. */
11468 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
11469 && GET_MODE (rs6000_compare_op0) == TFmode
11470 && !TARGET_IEEEQUAD
11471 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
11472 emit_insn (gen_rtx_PARALLEL (VOIDmode,
11473 gen_rtvec (9,
11474 gen_rtx_SET (VOIDmode,
11475 compare_result,
11476 gen_rtx_COMPARE (comp_mode,
11477 rs6000_compare_op0,
11478 rs6000_compare_op1)),
11479 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11480 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11481 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11482 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11483 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11484 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11485 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11486 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
11487 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
11488 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
11490 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
11491 comp_mode = CCEQmode;
11492 compare_result = gen_reg_rtx (CCEQmode);
11493 if (TARGET_64BIT)
11494 emit_insn (gen_stack_protect_testdi (compare_result,
11495 rs6000_compare_op0, op1));
11496 else
11497 emit_insn (gen_stack_protect_testsi (compare_result,
11498 rs6000_compare_op0, op1));
11500 else
11501 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
11502 gen_rtx_COMPARE (comp_mode,
11503 rs6000_compare_op0,
11504 rs6000_compare_op1)));
11507 /* Some kinds of FP comparisons need an OR operation;
11508 under flag_finite_math_only we don't bother. */
11509 if (rs6000_compare_fp_p
11510 && !flag_finite_math_only
11511 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
11512 && (code == LE || code == GE
11513 || code == UNEQ || code == LTGT
11514 || code == UNGT || code == UNLT))
11516 enum rtx_code or1, or2;
11517 rtx or1_rtx, or2_rtx, compare2_rtx;
11518 rtx or_result = gen_reg_rtx (CCEQmode);
11520 switch (code)
11522 case LE: or1 = LT; or2 = EQ; break;
11523 case GE: or1 = GT; or2 = EQ; break;
11524 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
11525 case LTGT: or1 = LT; or2 = GT; break;
11526 case UNGT: or1 = UNORDERED; or2 = GT; break;
11527 case UNLT: or1 = UNORDERED; or2 = LT; break;
11528 default: gcc_unreachable ();
11530 validate_condition_mode (or1, comp_mode);
11531 validate_condition_mode (or2, comp_mode);
11532 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
11533 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
11534 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
11535 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
11536 const_true_rtx);
11537 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
11539 compare_result = or_result;
11540 code = EQ;
11543 validate_condition_mode (code, GET_MODE (compare_result));
11545 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
11549 /* Emit the RTL for an sCOND pattern. */
11551 void
11552 rs6000_emit_sCOND (enum rtx_code code, rtx result)
11554 rtx condition_rtx;
11555 enum machine_mode op_mode;
11556 enum rtx_code cond_code;
11558 condition_rtx = rs6000_generate_compare (code);
11559 cond_code = GET_CODE (condition_rtx);
11561 if (rs6000_compare_fp_p
11562 && !TARGET_FPRS && TARGET_HARD_FLOAT)
11564 rtx t;
11566 PUT_MODE (condition_rtx, SImode);
11567 t = XEXP (condition_rtx, 0);
11569 gcc_assert (cond_code == NE || cond_code == EQ);
11571 if (cond_code == NE)
11572 emit_insn (gen_e500_flip_gt_bit (t, t));
11574 emit_insn (gen_move_from_CR_gt_bit (result, t));
11575 return;
11578 if (cond_code == NE
11579 || cond_code == GE || cond_code == LE
11580 || cond_code == GEU || cond_code == LEU
11581 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
11583 rtx not_result = gen_reg_rtx (CCEQmode);
11584 rtx not_op, rev_cond_rtx;
11585 enum machine_mode cc_mode;
11587 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
11589 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
11590 SImode, XEXP (condition_rtx, 0), const0_rtx);
11591 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
11592 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
11593 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
11596 op_mode = GET_MODE (rs6000_compare_op0);
11597 if (op_mode == VOIDmode)
11598 op_mode = GET_MODE (rs6000_compare_op1);
11600 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
11602 PUT_MODE (condition_rtx, DImode);
11603 convert_move (result, condition_rtx, 0);
11605 else
11607 PUT_MODE (condition_rtx, SImode);
11608 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
11612 /* Emit a branch of kind CODE to location LOC. */
11614 void
11615 rs6000_emit_cbranch (enum rtx_code code, rtx loc)
11617 rtx condition_rtx, loc_ref;
11619 condition_rtx = rs6000_generate_compare (code);
11620 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
11621 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
11622 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
11623 loc_ref, pc_rtx)));
11626 /* Return the string to output a conditional branch to LABEL, which is
11627 the operand number of the label, or -1 if the branch is really a
11628 conditional return.
11630 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11631 condition code register and its mode specifies what kind of
11632 comparison we made.
11634 REVERSED is nonzero if we should reverse the sense of the comparison.
11636 INSN is the insn. */
11638 char *
11639 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
11641 static char string[64];
11642 enum rtx_code code = GET_CODE (op);
11643 rtx cc_reg = XEXP (op, 0);
11644 enum machine_mode mode = GET_MODE (cc_reg);
11645 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
11646 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
11647 int really_reversed = reversed ^ need_longbranch;
11648 char *s = string;
11649 const char *ccode;
11650 const char *pred;
11651 rtx note;
11653 validate_condition_mode (code, mode);
11655 /* Work out which way this really branches. We could use
11656 reverse_condition_maybe_unordered here always but this
11657 makes the resulting assembler clearer. */
11658 if (really_reversed)
11660 /* Reversal of FP compares takes care -- an ordered compare
11661 becomes an unordered compare and vice versa. */
11662 if (mode == CCFPmode)
11663 code = reverse_condition_maybe_unordered (code);
11664 else
11665 code = reverse_condition (code);
11668 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
11670 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11671 to the GT bit. */
11672 switch (code)
11674 case EQ:
11675 /* Opposite of GT. */
11676 code = GT;
11677 break;
11679 case NE:
11680 code = UNLE;
11681 break;
11683 default:
11684 gcc_unreachable ();
11688 switch (code)
11690 /* Not all of these are actually distinct opcodes, but
11691 we distinguish them for clarity of the resulting assembler. */
11692 case NE: case LTGT:
11693 ccode = "ne"; break;
11694 case EQ: case UNEQ:
11695 ccode = "eq"; break;
11696 case GE: case GEU:
11697 ccode = "ge"; break;
11698 case GT: case GTU: case UNGT:
11699 ccode = "gt"; break;
11700 case LE: case LEU:
11701 ccode = "le"; break;
11702 case LT: case LTU: case UNLT:
11703 ccode = "lt"; break;
11704 case UNORDERED: ccode = "un"; break;
11705 case ORDERED: ccode = "nu"; break;
11706 case UNGE: ccode = "nl"; break;
11707 case UNLE: ccode = "ng"; break;
11708 default:
11709 gcc_unreachable ();
11712 /* Maybe we have a guess as to how likely the branch is.
11713 The old mnemonics don't have a way to specify this information. */
11714 pred = "";
11715 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
11716 if (note != NULL_RTX)
11718 /* PROB is the difference from 50%. */
11719 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
11721 /* Only hint for highly probable/improbable branches on newer
11722 cpus as static prediction overrides processor dynamic
11723 prediction. For older cpus we may as well always hint, but
11724 assume not taken for branches that are very close to 50% as a
11725 mispredicted taken branch is more expensive than a
11726 mispredicted not-taken branch. */
11727 if (rs6000_always_hint
11728 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
11729 && br_prob_note_reliable_p (note)))
11731 if (abs (prob) > REG_BR_PROB_BASE / 20
11732 && ((prob > 0) ^ need_longbranch))
11733 pred = "+";
11734 else
11735 pred = "-";
11739 if (label == NULL)
11740 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
11741 else
11742 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
11744 /* We need to escape any '%' characters in the reg_names string.
11745 Assume they'd only be the first character.... */
11746 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
11747 *s++ = '%';
11748 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
11750 if (label != NULL)
11752 /* If the branch distance was too far, we may have to use an
11753 unconditional branch to go the distance. */
11754 if (need_longbranch)
11755 s += sprintf (s, ",$+8\n\tb %s", label);
11756 else
11757 s += sprintf (s, ",%s", label);
11760 return string;
11763 /* Return the string to flip the GT bit on a CR. */
11764 char *
11765 output_e500_flip_gt_bit (rtx dst, rtx src)
11767 static char string[64];
11768 int a, b;
11770 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
11771 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
11773 /* GT bit. */
11774 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
11775 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
11777 sprintf (string, "crnot %d,%d", a, b);
11778 return string;
11781 /* Return insn index for the vector compare instruction for given CODE,
11782 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11783 not available. */
11785 static int
11786 get_vec_cmp_insn (enum rtx_code code,
11787 enum machine_mode dest_mode,
11788 enum machine_mode op_mode)
11790 if (!TARGET_ALTIVEC)
11791 return INSN_NOT_AVAILABLE;
11793 switch (code)
11795 case EQ:
11796 if (dest_mode == V16QImode && op_mode == V16QImode)
11797 return UNSPEC_VCMPEQUB;
11798 if (dest_mode == V8HImode && op_mode == V8HImode)
11799 return UNSPEC_VCMPEQUH;
11800 if (dest_mode == V4SImode && op_mode == V4SImode)
11801 return UNSPEC_VCMPEQUW;
11802 if (dest_mode == V4SImode && op_mode == V4SFmode)
11803 return UNSPEC_VCMPEQFP;
11804 break;
11805 case GE:
11806 if (dest_mode == V4SImode && op_mode == V4SFmode)
11807 return UNSPEC_VCMPGEFP;
11808 case GT:
11809 if (dest_mode == V16QImode && op_mode == V16QImode)
11810 return UNSPEC_VCMPGTSB;
11811 if (dest_mode == V8HImode && op_mode == V8HImode)
11812 return UNSPEC_VCMPGTSH;
11813 if (dest_mode == V4SImode && op_mode == V4SImode)
11814 return UNSPEC_VCMPGTSW;
11815 if (dest_mode == V4SImode && op_mode == V4SFmode)
11816 return UNSPEC_VCMPGTFP;
11817 break;
11818 case GTU:
11819 if (dest_mode == V16QImode && op_mode == V16QImode)
11820 return UNSPEC_VCMPGTUB;
11821 if (dest_mode == V8HImode && op_mode == V8HImode)
11822 return UNSPEC_VCMPGTUH;
11823 if (dest_mode == V4SImode && op_mode == V4SImode)
11824 return UNSPEC_VCMPGTUW;
11825 break;
11826 default:
11827 break;
11829 return INSN_NOT_AVAILABLE;
11832 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
11833 DMODE is expected destination mode. This is a recursive function. */
11835 static rtx
11836 rs6000_emit_vector_compare (enum rtx_code rcode,
11837 rtx op0, rtx op1,
11838 enum machine_mode dmode)
11840 int vec_cmp_insn;
11841 rtx mask;
11842 enum machine_mode dest_mode;
11843 enum machine_mode op_mode = GET_MODE (op1);
11845 gcc_assert (TARGET_ALTIVEC);
11846 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
11848 /* Floating point vector compare instructions uses destination V4SImode.
11849 Move destination to appropriate mode later. */
11850 if (dmode == V4SFmode)
11851 dest_mode = V4SImode;
11852 else
11853 dest_mode = dmode;
11855 mask = gen_reg_rtx (dest_mode);
11856 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11858 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
11860 bool swap_operands = false;
11861 bool try_again = false;
11862 switch (rcode)
11864 case LT:
11865 rcode = GT;
11866 swap_operands = true;
11867 try_again = true;
11868 break;
11869 case LTU:
11870 rcode = GTU;
11871 swap_operands = true;
11872 try_again = true;
11873 break;
11874 case NE:
11875 /* Treat A != B as ~(A==B). */
11877 enum insn_code nor_code;
11878 rtx eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
11879 dest_mode);
11881 nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
11882 gcc_assert (nor_code != CODE_FOR_nothing);
11883 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
11885 if (dmode != dest_mode)
11887 rtx temp = gen_reg_rtx (dest_mode);
11888 convert_move (temp, mask, 0);
11889 return temp;
11891 return mask;
11893 break;
11894 case GE:
11895 case GEU:
11896 case LE:
11897 case LEU:
11898 /* Try GT/GTU/LT/LTU OR EQ */
11900 rtx c_rtx, eq_rtx;
11901 enum insn_code ior_code;
11902 enum rtx_code new_code;
11904 switch (rcode)
11906 case GE:
11907 new_code = GT;
11908 break;
11910 case GEU:
11911 new_code = GTU;
11912 break;
11914 case LE:
11915 new_code = LT;
11916 break;
11918 case LEU:
11919 new_code = LTU;
11920 break;
11922 default:
11923 gcc_unreachable ();
11926 c_rtx = rs6000_emit_vector_compare (new_code,
11927 op0, op1, dest_mode);
11928 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
11929 dest_mode);
11931 ior_code = ior_optab->handlers[(int)dest_mode].insn_code;
11932 gcc_assert (ior_code != CODE_FOR_nothing);
11933 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
11934 if (dmode != dest_mode)
11936 rtx temp = gen_reg_rtx (dest_mode);
11937 convert_move (temp, mask, 0);
11938 return temp;
11940 return mask;
11942 break;
11943 default:
11944 gcc_unreachable ();
11947 if (try_again)
11949 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11950 /* You only get two chances. */
11951 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
11954 if (swap_operands)
11956 rtx tmp;
11957 tmp = op0;
11958 op0 = op1;
11959 op1 = tmp;
11963 emit_insn (gen_rtx_SET (VOIDmode, mask,
11964 gen_rtx_UNSPEC (dest_mode,
11965 gen_rtvec (2, op0, op1),
11966 vec_cmp_insn)));
11967 if (dmode != dest_mode)
11969 rtx temp = gen_reg_rtx (dest_mode);
11970 convert_move (temp, mask, 0);
11971 return temp;
11973 return mask;
11976 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
11977 valid insn doesn exist for given mode. */
11979 static int
11980 get_vsel_insn (enum machine_mode mode)
11982 switch (mode)
11984 case V4SImode:
11985 return UNSPEC_VSEL4SI;
11986 break;
11987 case V4SFmode:
11988 return UNSPEC_VSEL4SF;
11989 break;
11990 case V8HImode:
11991 return UNSPEC_VSEL8HI;
11992 break;
11993 case V16QImode:
11994 return UNSPEC_VSEL16QI;
11995 break;
11996 default:
11997 return INSN_NOT_AVAILABLE;
11998 break;
12000 return INSN_NOT_AVAILABLE;
12003 /* Emit vector select insn where DEST is destination using
12004 operands OP1, OP2 and MASK. */
12006 static void
12007 rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
12009 rtx t, temp;
12010 enum machine_mode dest_mode = GET_MODE (dest);
12011 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
12013 temp = gen_reg_rtx (dest_mode);
12015 /* For each vector element, select op1 when mask is 1 otherwise
12016 select op2. */
12017 t = gen_rtx_SET (VOIDmode, temp,
12018 gen_rtx_UNSPEC (dest_mode,
12019 gen_rtvec (3, op2, op1, mask),
12020 vsel_insn_index));
12021 emit_insn (t);
12022 emit_move_insn (dest, temp);
12023 return;
12026 /* Emit vector conditional expression.
12027 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
12028 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
12031 rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
12032 rtx cond, rtx cc_op0, rtx cc_op1)
12034 enum machine_mode dest_mode = GET_MODE (dest);
12035 enum rtx_code rcode = GET_CODE (cond);
12036 rtx mask;
12038 if (!TARGET_ALTIVEC)
12039 return 0;
12041 /* Get the vector mask for the given relational operations. */
12042 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
12044 rs6000_emit_vector_select (dest, op1, op2, mask);
12046 return 1;
12049 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
12050 operands of the last comparison is nonzero/true, FALSE_COND if it
12051 is zero/false. Return 0 if the hardware has no such operation. */
12054 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
12056 enum rtx_code code = GET_CODE (op);
12057 rtx op0 = rs6000_compare_op0;
12058 rtx op1 = rs6000_compare_op1;
12059 REAL_VALUE_TYPE c1;
12060 enum machine_mode compare_mode = GET_MODE (op0);
12061 enum machine_mode result_mode = GET_MODE (dest);
12062 rtx temp;
12063 bool is_against_zero;
12065 /* These modes should always match. */
12066 if (GET_MODE (op1) != compare_mode
12067 /* In the isel case however, we can use a compare immediate, so
12068 op1 may be a small constant. */
12069 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
12070 return 0;
12071 if (GET_MODE (true_cond) != result_mode)
12072 return 0;
12073 if (GET_MODE (false_cond) != result_mode)
12074 return 0;
12076 /* First, work out if the hardware can do this at all, or
12077 if it's too slow.... */
12078 if (! rs6000_compare_fp_p)
12080 if (TARGET_ISEL)
12081 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
12082 return 0;
12084 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
12085 && SCALAR_FLOAT_MODE_P (compare_mode))
12086 return 0;
12088 is_against_zero = op1 == CONST0_RTX (compare_mode);
12090 /* A floating-point subtract might overflow, underflow, or produce
12091 an inexact result, thus changing the floating-point flags, so it
12092 can't be generated if we care about that. It's safe if one side
12093 of the construct is zero, since then no subtract will be
12094 generated. */
12095 if (SCALAR_FLOAT_MODE_P (compare_mode)
12096 && flag_trapping_math && ! is_against_zero)
12097 return 0;
12099 /* Eliminate half of the comparisons by switching operands, this
12100 makes the remaining code simpler. */
12101 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
12102 || code == LTGT || code == LT || code == UNLE)
12104 code = reverse_condition_maybe_unordered (code);
12105 temp = true_cond;
12106 true_cond = false_cond;
12107 false_cond = temp;
12110 /* UNEQ and LTGT take four instructions for a comparison with zero,
12111 it'll probably be faster to use a branch here too. */
12112 if (code == UNEQ && HONOR_NANS (compare_mode))
12113 return 0;
12115 if (GET_CODE (op1) == CONST_DOUBLE)
12116 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
12118 /* We're going to try to implement comparisons by performing
12119 a subtract, then comparing against zero. Unfortunately,
12120 Inf - Inf is NaN which is not zero, and so if we don't
12121 know that the operand is finite and the comparison
12122 would treat EQ different to UNORDERED, we can't do it. */
12123 if (HONOR_INFINITIES (compare_mode)
12124 && code != GT && code != UNGE
12125 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
12126 /* Constructs of the form (a OP b ? a : b) are safe. */
12127 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
12128 || (! rtx_equal_p (op0, true_cond)
12129 && ! rtx_equal_p (op1, true_cond))))
12130 return 0;
12132 /* At this point we know we can use fsel. */
12134 /* Reduce the comparison to a comparison against zero. */
12135 if (! is_against_zero)
12137 temp = gen_reg_rtx (compare_mode);
12138 emit_insn (gen_rtx_SET (VOIDmode, temp,
12139 gen_rtx_MINUS (compare_mode, op0, op1)));
12140 op0 = temp;
12141 op1 = CONST0_RTX (compare_mode);
12144 /* If we don't care about NaNs we can reduce some of the comparisons
12145 down to faster ones. */
12146 if (! HONOR_NANS (compare_mode))
12147 switch (code)
12149 case GT:
12150 code = LE;
12151 temp = true_cond;
12152 true_cond = false_cond;
12153 false_cond = temp;
12154 break;
12155 case UNGE:
12156 code = GE;
12157 break;
12158 case UNEQ:
12159 code = EQ;
12160 break;
12161 default:
12162 break;
12165 /* Now, reduce everything down to a GE. */
12166 switch (code)
12168 case GE:
12169 break;
12171 case LE:
12172 temp = gen_reg_rtx (compare_mode);
12173 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12174 op0 = temp;
12175 break;
12177 case ORDERED:
12178 temp = gen_reg_rtx (compare_mode);
12179 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
12180 op0 = temp;
12181 break;
12183 case EQ:
12184 temp = gen_reg_rtx (compare_mode);
12185 emit_insn (gen_rtx_SET (VOIDmode, temp,
12186 gen_rtx_NEG (compare_mode,
12187 gen_rtx_ABS (compare_mode, op0))));
12188 op0 = temp;
12189 break;
12191 case UNGE:
12192 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
12193 temp = gen_reg_rtx (result_mode);
12194 emit_insn (gen_rtx_SET (VOIDmode, temp,
12195 gen_rtx_IF_THEN_ELSE (result_mode,
12196 gen_rtx_GE (VOIDmode,
12197 op0, op1),
12198 true_cond, false_cond)));
12199 false_cond = true_cond;
12200 true_cond = temp;
12202 temp = gen_reg_rtx (compare_mode);
12203 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12204 op0 = temp;
12205 break;
12207 case GT:
12208 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
12209 temp = gen_reg_rtx (result_mode);
12210 emit_insn (gen_rtx_SET (VOIDmode, temp,
12211 gen_rtx_IF_THEN_ELSE (result_mode,
12212 gen_rtx_GE (VOIDmode,
12213 op0, op1),
12214 true_cond, false_cond)));
12215 true_cond = false_cond;
12216 false_cond = temp;
12218 temp = gen_reg_rtx (compare_mode);
12219 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12220 op0 = temp;
12221 break;
12223 default:
12224 gcc_unreachable ();
12227 emit_insn (gen_rtx_SET (VOIDmode, dest,
12228 gen_rtx_IF_THEN_ELSE (result_mode,
12229 gen_rtx_GE (VOIDmode,
12230 op0, op1),
12231 true_cond, false_cond)));
12232 return 1;
12235 /* Same as above, but for ints (isel). */
12237 static int
12238 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
12240 rtx condition_rtx, cr;
12242 /* All isel implementations thus far are 32-bits. */
12243 if (GET_MODE (rs6000_compare_op0) != SImode)
12244 return 0;
12246 /* We still have to do the compare, because isel doesn't do a
12247 compare, it just looks at the CRx bits set by a previous compare
12248 instruction. */
12249 condition_rtx = rs6000_generate_compare (GET_CODE (op));
12250 cr = XEXP (condition_rtx, 0);
12252 if (GET_MODE (cr) == CCmode)
12253 emit_insn (gen_isel_signed (dest, condition_rtx,
12254 true_cond, false_cond, cr));
12255 else
12256 emit_insn (gen_isel_unsigned (dest, condition_rtx,
12257 true_cond, false_cond, cr));
12259 return 1;
12262 const char *
12263 output_isel (rtx *operands)
12265 enum rtx_code code;
12267 code = GET_CODE (operands[1]);
12268 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
12270 PUT_CODE (operands[1], reverse_condition (code));
12271 return "isel %0,%3,%2,%j1";
12273 else
12274 return "isel %0,%2,%3,%j1";
12277 void
12278 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
12280 enum machine_mode mode = GET_MODE (op0);
12281 enum rtx_code c;
12282 rtx target;
12284 if (code == SMAX || code == SMIN)
12285 c = GE;
12286 else
12287 c = GEU;
12289 if (code == SMAX || code == UMAX)
12290 target = emit_conditional_move (dest, c, op0, op1, mode,
12291 op0, op1, mode, 0);
12292 else
12293 target = emit_conditional_move (dest, c, op0, op1, mode,
12294 op1, op0, mode, 0);
12295 gcc_assert (target);
12296 if (target != dest)
12297 emit_move_insn (dest, target);
12300 /* Emit instructions to perform a load-reserved/store-conditional operation.
12301 The operation performed is an atomic
12302 (set M (CODE:MODE M OP))
12303 If not NULL, BEFORE is atomically set to M before the operation, and
12304 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
12305 If SYNC_P then a memory barrier is emitted before the operation.
12306 Either OP or M may be wrapped in a NOT operation. */
12308 void
12309 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
12310 rtx m, rtx op, rtx before_param, rtx after_param,
12311 bool sync_p)
12313 enum machine_mode used_mode;
12314 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
12315 rtx used_m;
12316 rtvec vec;
12317 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12318 rtx shift = NULL_RTX;
12320 if (sync_p)
12321 emit_insn (gen_memory_barrier ());
12323 if (GET_CODE (m) == NOT)
12324 used_m = XEXP (m, 0);
12325 else
12326 used_m = m;
12328 /* If this is smaller than SImode, we'll have to use SImode with
12329 adjustments. */
12330 if (mode == QImode || mode == HImode)
12332 rtx newop, oldop;
12334 if (MEM_ALIGN (used_m) >= 32)
12336 int ishift = 0;
12337 if (BYTES_BIG_ENDIAN)
12338 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
12340 shift = GEN_INT (ishift);
12342 else
12344 rtx addrSI, aligned_addr;
12345 int shift_mask = mode == QImode ? 0x18 : 0x10;
12347 addrSI = force_reg (SImode, gen_lowpart_common (SImode,
12348 XEXP (used_m, 0)));
12349 shift = gen_reg_rtx (SImode);
12351 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
12352 GEN_INT (shift_mask)));
12353 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
12355 aligned_addr = expand_binop (Pmode, and_optab,
12356 XEXP (used_m, 0),
12357 GEN_INT (-4), NULL_RTX,
12358 1, OPTAB_LIB_WIDEN);
12359 used_m = change_address (used_m, SImode, aligned_addr);
12360 set_mem_align (used_m, 32);
12361 /* It's safe to keep the old alias set of USED_M, because
12362 the operation is atomic and only affects the original
12363 USED_M. */
12364 if (GET_CODE (m) == NOT)
12365 m = gen_rtx_NOT (SImode, used_m);
12366 else
12367 m = used_m;
12370 if (GET_CODE (op) == NOT)
12372 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
12373 oldop = gen_rtx_NOT (SImode, oldop);
12375 else
12376 oldop = lowpart_subreg (SImode, op, mode);
12378 switch (code)
12380 case IOR:
12381 case XOR:
12382 newop = expand_binop (SImode, and_optab,
12383 oldop, GEN_INT (imask), NULL_RTX,
12384 1, OPTAB_LIB_WIDEN);
12385 emit_insn (gen_ashlsi3 (newop, newop, shift));
12386 break;
12388 case AND:
12389 newop = expand_binop (SImode, ior_optab,
12390 oldop, GEN_INT (~imask), NULL_RTX,
12391 1, OPTAB_LIB_WIDEN);
12392 emit_insn (gen_rotlsi3 (newop, newop, shift));
12393 break;
12395 case PLUS:
12396 case MINUS:
12398 rtx mask;
12400 newop = expand_binop (SImode, and_optab,
12401 oldop, GEN_INT (imask), NULL_RTX,
12402 1, OPTAB_LIB_WIDEN);
12403 emit_insn (gen_ashlsi3 (newop, newop, shift));
12405 mask = gen_reg_rtx (SImode);
12406 emit_move_insn (mask, GEN_INT (imask));
12407 emit_insn (gen_ashlsi3 (mask, mask, shift));
12409 if (code == PLUS)
12410 newop = gen_rtx_PLUS (SImode, m, newop);
12411 else
12412 newop = gen_rtx_MINUS (SImode, m, newop);
12413 newop = gen_rtx_AND (SImode, newop, mask);
12414 newop = gen_rtx_IOR (SImode, newop,
12415 gen_rtx_AND (SImode,
12416 gen_rtx_NOT (SImode, mask),
12417 m));
12418 break;
12421 default:
12422 gcc_unreachable ();
12425 if (GET_CODE (m) == NOT)
12427 rtx mask, xorm;
12429 mask = gen_reg_rtx (SImode);
12430 emit_move_insn (mask, GEN_INT (imask));
12431 emit_insn (gen_ashlsi3 (mask, mask, shift));
12433 xorm = gen_rtx_XOR (SImode, used_m, mask);
12434 /* Depending on the value of 'op', the XOR or the operation might
12435 be able to be simplified away. */
12436 newop = simplify_gen_binary (code, SImode, xorm, newop);
12438 op = newop;
12439 used_mode = SImode;
12440 before = gen_reg_rtx (used_mode);
12441 after = gen_reg_rtx (used_mode);
12443 else
12445 used_mode = mode;
12446 before = before_param;
12447 after = after_param;
12449 if (before == NULL_RTX)
12450 before = gen_reg_rtx (used_mode);
12451 if (after == NULL_RTX)
12452 after = gen_reg_rtx (used_mode);
12455 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
12456 && used_mode != mode)
12457 the_op = op; /* Computed above. */
12458 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
12459 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
12460 else
12461 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
12463 set_after = gen_rtx_SET (VOIDmode, after, the_op);
12464 set_before = gen_rtx_SET (VOIDmode, before, used_m);
12465 set_atomic = gen_rtx_SET (VOIDmode, used_m,
12466 gen_rtx_UNSPEC (used_mode,
12467 gen_rtvec (1, the_op),
12468 UNSPEC_SYNC_OP));
12469 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
12471 if ((code == PLUS || code == MINUS) && used_mode != mode)
12472 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
12473 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
12474 else
12475 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
12476 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
12478 /* Shift and mask the return values properly. */
12479 if (used_mode != mode && before_param)
12481 emit_insn (gen_lshrsi3 (before, before, shift));
12482 convert_move (before_param, before, 1);
12485 if (used_mode != mode && after_param)
12487 emit_insn (gen_lshrsi3 (after, after, shift));
12488 convert_move (after_param, after, 1);
12491 /* The previous sequence will end with a branch that's dependent on
12492 the conditional store, so placing an isync will ensure that no
12493 other instructions (especially, no load or store instructions)
12494 can start before the atomic operation completes. */
12495 if (sync_p)
12496 emit_insn (gen_isync ());
12499 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12500 COND is true. Mark the jump as unlikely to be taken. */
12502 static void
12503 emit_unlikely_jump (rtx cond, rtx label)
12505 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
12506 rtx x;
12508 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
12509 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
12510 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
12513 /* A subroutine of the atomic operation splitters. Emit a load-locked
12514 instruction in MODE. */
12516 static void
12517 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
12519 rtx (*fn) (rtx, rtx) = NULL;
12520 if (mode == SImode)
12521 fn = gen_load_locked_si;
12522 else if (mode == DImode)
12523 fn = gen_load_locked_di;
12524 emit_insn (fn (reg, mem));
12527 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12528 instruction in MODE. */
12530 static void
12531 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
12533 rtx (*fn) (rtx, rtx, rtx) = NULL;
12534 if (mode == SImode)
12535 fn = gen_store_conditional_si;
12536 else if (mode == DImode)
12537 fn = gen_store_conditional_di;
12539 /* Emit sync before stwcx. to address PPC405 Erratum. */
12540 if (PPC405_ERRATUM77)
12541 emit_insn (gen_memory_barrier ());
12543 emit_insn (fn (res, mem, val));
12546 /* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
12547 to perform. MEM is the memory on which to operate. VAL is the second
12548 operand of the binary operator. BEFORE and AFTER are optional locations to
12549 return the value of MEM either before of after the operation. SCRATCH is
12550 a scratch register. */
12552 void
12553 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
12554 rtx before, rtx after, rtx scratch)
12556 enum machine_mode mode = GET_MODE (mem);
12557 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12559 emit_insn (gen_memory_barrier ());
12561 label = gen_label_rtx ();
12562 emit_label (label);
12563 label = gen_rtx_LABEL_REF (VOIDmode, label);
12565 if (before == NULL_RTX)
12566 before = scratch;
12567 emit_load_locked (mode, before, mem);
12569 if (code == NOT)
12570 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
12571 else if (code == AND)
12572 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
12573 else
12574 x = gen_rtx_fmt_ee (code, mode, before, val);
12576 if (after != NULL_RTX)
12577 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
12578 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
12580 emit_store_conditional (mode, cond, mem, scratch);
12582 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12583 emit_unlikely_jump (x, label);
12585 emit_insn (gen_isync ());
12588 /* Expand an atomic compare and swap operation. MEM is the memory on which
12589 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12590 value to be stored. SCRATCH is a scratch GPR. */
12592 void
12593 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
12594 rtx scratch)
12596 enum machine_mode mode = GET_MODE (mem);
12597 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12599 emit_insn (gen_memory_barrier ());
12601 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12602 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12603 emit_label (XEXP (label1, 0));
12605 emit_load_locked (mode, retval, mem);
12607 x = gen_rtx_COMPARE (CCmode, retval, oldval);
12608 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12610 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12611 emit_unlikely_jump (x, label2);
12613 emit_move_insn (scratch, newval);
12614 emit_store_conditional (mode, cond, mem, scratch);
12616 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12617 emit_unlikely_jump (x, label1);
12619 emit_insn (gen_isync ());
12620 emit_label (XEXP (label2, 0));
12623 /* Expand an atomic test and set operation. MEM is the memory on which
12624 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12626 void
12627 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
12629 enum machine_mode mode = GET_MODE (mem);
12630 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12632 emit_insn (gen_memory_barrier ());
12634 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12635 emit_label (XEXP (label, 0));
12637 emit_load_locked (mode, retval, mem);
12638 emit_move_insn (scratch, val);
12639 emit_store_conditional (mode, cond, mem, scratch);
12641 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12642 emit_unlikely_jump (x, label);
12644 emit_insn (gen_isync ());
12647 void
12648 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
12650 enum machine_mode mode = GET_MODE (mem);
12651 rtx addrSI, align, wdst, shift, mask;
12652 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
12653 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12655 /* Shift amount for subword relative to aligned word. */
12656 addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0)));
12657 shift = gen_reg_rtx (SImode);
12658 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
12659 GEN_INT (shift_mask)));
12660 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
12662 /* Shift and mask old value into position within word. */
12663 oldval = convert_modes (SImode, mode, oldval, 1);
12664 oldval = expand_binop (SImode, and_optab,
12665 oldval, GEN_INT (imask), NULL_RTX,
12666 1, OPTAB_LIB_WIDEN);
12667 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
12669 /* Shift and mask new value into position within word. */
12670 newval = convert_modes (SImode, mode, newval, 1);
12671 newval = expand_binop (SImode, and_optab,
12672 newval, GEN_INT (imask), NULL_RTX,
12673 1, OPTAB_LIB_WIDEN);
12674 emit_insn (gen_ashlsi3 (newval, newval, shift));
12676 /* Mask for insertion. */
12677 mask = gen_reg_rtx (SImode);
12678 emit_move_insn (mask, GEN_INT (imask));
12679 emit_insn (gen_ashlsi3 (mask, mask, shift));
12681 /* Address of aligned word containing subword. */
12682 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
12683 NULL_RTX, 1, OPTAB_LIB_WIDEN);
12684 mem = change_address (mem, SImode, align);
12685 set_mem_align (mem, 32);
12686 MEM_VOLATILE_P (mem) = 1;
12688 wdst = gen_reg_rtx (SImode);
12689 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
12690 oldval, newval, mem));
12692 emit_move_insn (dst, gen_lowpart (mode, wdst));
12695 void
12696 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
12697 rtx oldval, rtx newval, rtx mem,
12698 rtx scratch)
12700 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12702 emit_insn (gen_memory_barrier ());
12703 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12704 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12705 emit_label (XEXP (label1, 0));
12707 emit_load_locked (SImode, scratch, mem);
12709 /* Mask subword within loaded value for comparison with oldval.
12710 Use UNSPEC_AND to avoid clobber.*/
12711 emit_insn (gen_rtx_SET (SImode, dest,
12712 gen_rtx_UNSPEC (SImode,
12713 gen_rtvec (2, scratch, mask),
12714 UNSPEC_AND)));
12716 x = gen_rtx_COMPARE (CCmode, dest, oldval);
12717 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12719 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12720 emit_unlikely_jump (x, label2);
12722 /* Clear subword within loaded value for insertion of new value. */
12723 emit_insn (gen_rtx_SET (SImode, scratch,
12724 gen_rtx_AND (SImode,
12725 gen_rtx_NOT (SImode, mask), scratch)));
12726 emit_insn (gen_iorsi3 (scratch, scratch, newval));
12727 emit_store_conditional (SImode, cond, mem, scratch);
12729 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12730 emit_unlikely_jump (x, label1);
12732 emit_insn (gen_isync ());
12733 emit_label (XEXP (label2, 0));
12737 /* Emit instructions to move SRC to DST. Called by splitters for
12738 multi-register moves. It will emit at most one instruction for
12739 each register that is accessed; that is, it won't emit li/lis pairs
12740 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12741 register. */
12743 void
12744 rs6000_split_multireg_move (rtx dst, rtx src)
12746 /* The register number of the first register being moved. */
12747 int reg;
12748 /* The mode that is to be moved. */
12749 enum machine_mode mode;
12750 /* The mode that the move is being done in, and its size. */
12751 enum machine_mode reg_mode;
12752 int reg_mode_size;
12753 /* The number of registers that will be moved. */
12754 int nregs;
12756 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
12757 mode = GET_MODE (dst);
12758 nregs = hard_regno_nregs[reg][mode];
12759 if (FP_REGNO_P (reg))
12760 reg_mode = DFmode;
12761 else if (ALTIVEC_REGNO_P (reg))
12762 reg_mode = V16QImode;
12763 else if (TARGET_E500_DOUBLE && mode == TFmode)
12764 reg_mode = DFmode;
12765 else
12766 reg_mode = word_mode;
12767 reg_mode_size = GET_MODE_SIZE (reg_mode);
12769 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
12771 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
12773 /* Move register range backwards, if we might have destructive
12774 overlap. */
12775 int i;
12776 for (i = nregs - 1; i >= 0; i--)
12777 emit_insn (gen_rtx_SET (VOIDmode,
12778 simplify_gen_subreg (reg_mode, dst, mode,
12779 i * reg_mode_size),
12780 simplify_gen_subreg (reg_mode, src, mode,
12781 i * reg_mode_size)));
12783 else
12785 int i;
12786 int j = -1;
12787 bool used_update = false;
12789 if (MEM_P (src) && INT_REGNO_P (reg))
12791 rtx breg;
12793 if (GET_CODE (XEXP (src, 0)) == PRE_INC
12794 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
12796 rtx delta_rtx;
12797 breg = XEXP (XEXP (src, 0), 0);
12798 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
12799 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
12800 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
12801 emit_insn (TARGET_32BIT
12802 ? gen_addsi3 (breg, breg, delta_rtx)
12803 : gen_adddi3 (breg, breg, delta_rtx));
12804 src = replace_equiv_address (src, breg);
12806 else if (! rs6000_offsettable_memref_p (src))
12808 rtx basereg;
12809 basereg = gen_rtx_REG (Pmode, reg);
12810 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
12811 src = replace_equiv_address (src, basereg);
12814 breg = XEXP (src, 0);
12815 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
12816 breg = XEXP (breg, 0);
12818 /* If the base register we are using to address memory is
12819 also a destination reg, then change that register last. */
12820 if (REG_P (breg)
12821 && REGNO (breg) >= REGNO (dst)
12822 && REGNO (breg) < REGNO (dst) + nregs)
12823 j = REGNO (breg) - REGNO (dst);
12826 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
12828 rtx breg;
12830 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
12831 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
12833 rtx delta_rtx;
12834 breg = XEXP (XEXP (dst, 0), 0);
12835 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
12836 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
12837 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
12839 /* We have to update the breg before doing the store.
12840 Use store with update, if available. */
12842 if (TARGET_UPDATE)
12844 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
12845 emit_insn (TARGET_32BIT
12846 ? (TARGET_POWERPC64
12847 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
12848 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
12849 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
12850 used_update = true;
12852 else
12853 emit_insn (TARGET_32BIT
12854 ? gen_addsi3 (breg, breg, delta_rtx)
12855 : gen_adddi3 (breg, breg, delta_rtx));
12856 dst = replace_equiv_address (dst, breg);
12858 else
12859 gcc_assert (rs6000_offsettable_memref_p (dst));
12862 for (i = 0; i < nregs; i++)
12864 /* Calculate index to next subword. */
12865 ++j;
12866 if (j == nregs)
12867 j = 0;
12869 /* If compiler already emitted move of first word by
12870 store with update, no need to do anything. */
12871 if (j == 0 && used_update)
12872 continue;
12874 emit_insn (gen_rtx_SET (VOIDmode,
12875 simplify_gen_subreg (reg_mode, dst, mode,
12876 j * reg_mode_size),
12877 simplify_gen_subreg (reg_mode, src, mode,
12878 j * reg_mode_size)));
12884 /* This page contains routines that are used to determine what the
12885 function prologue and epilogue code will do and write them out. */
12887 /* Return the first fixed-point register that is required to be
12888 saved. 32 if none. */
12891 first_reg_to_save (void)
12893 int first_reg;
12895 /* Find lowest numbered live register. */
12896 for (first_reg = 13; first_reg <= 31; first_reg++)
12897 if (regs_ever_live[first_reg]
12898 && (! call_used_regs[first_reg]
12899 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
12900 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
12901 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
12902 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
12903 break;
12905 #if TARGET_MACHO
12906 if (flag_pic
12907 && current_function_uses_pic_offset_table
12908 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
12909 return RS6000_PIC_OFFSET_TABLE_REGNUM;
12910 #endif
12912 return first_reg;
12915 /* Similar, for FP regs. */
12918 first_fp_reg_to_save (void)
12920 int first_reg;
12922 /* Find lowest numbered live register. */
12923 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
12924 if (regs_ever_live[first_reg])
12925 break;
12927 return first_reg;
12930 /* Similar, for AltiVec regs. */
12932 static int
12933 first_altivec_reg_to_save (void)
12935 int i;
12937 /* Stack frame remains as is unless we are in AltiVec ABI. */
12938 if (! TARGET_ALTIVEC_ABI)
12939 return LAST_ALTIVEC_REGNO + 1;
12941 /* Find lowest numbered live register. */
12942 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
12943 if (regs_ever_live[i])
12944 break;
12946 return i;
12949 /* Return a 32-bit mask of the AltiVec registers we need to set in
12950 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
12951 the 32-bit word is 0. */
12953 static unsigned int
12954 compute_vrsave_mask (void)
12956 unsigned int i, mask = 0;
12958 /* First, find out if we use _any_ altivec registers. */
12959 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
12960 if (regs_ever_live[i])
12961 mask |= ALTIVEC_REG_BIT (i);
12963 if (mask == 0)
12964 return mask;
12966 /* Next, remove the argument registers from the set. These must
12967 be in the VRSAVE mask set by the caller, so we don't need to add
12968 them in again. More importantly, the mask we compute here is
12969 used to generate CLOBBERs in the set_vrsave insn, and we do not
12970 wish the argument registers to die. */
12971 for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
12972 mask &= ~ALTIVEC_REG_BIT (i);
12974 /* Similarly, remove the return value from the set. */
12976 bool yes = false;
12977 diddle_return_value (is_altivec_return_reg, &yes);
12978 if (yes)
12979 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
12982 return mask;
12985 /* For a very restricted set of circumstances, we can cut down the
12986 size of prologues/epilogues by calling our own save/restore-the-world
12987 routines. */
12989 static void
12990 compute_save_world_info (rs6000_stack_t *info_ptr)
12992 info_ptr->world_save_p = 1;
12993 info_ptr->world_save_p
12994 = (WORLD_SAVE_P (info_ptr)
12995 && DEFAULT_ABI == ABI_DARWIN
12996 && ! (current_function_calls_setjmp && flag_exceptions)
12997 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
12998 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
12999 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
13000 && info_ptr->cr_save_p);
13002 /* This will not work in conjunction with sibcalls. Make sure there
13003 are none. (This check is expensive, but seldom executed.) */
13004 if (WORLD_SAVE_P (info_ptr))
13006 rtx insn;
13007 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
13008 if ( GET_CODE (insn) == CALL_INSN
13009 && SIBLING_CALL_P (insn))
13011 info_ptr->world_save_p = 0;
13012 break;
13016 if (WORLD_SAVE_P (info_ptr))
13018 /* Even if we're not touching VRsave, make sure there's room on the
13019 stack for it, if it looks like we're calling SAVE_WORLD, which
13020 will attempt to save it. */
13021 info_ptr->vrsave_size = 4;
13023 /* "Save" the VRsave register too if we're saving the world. */
13024 if (info_ptr->vrsave_mask == 0)
13025 info_ptr->vrsave_mask = compute_vrsave_mask ();
13027 /* Because the Darwin register save/restore routines only handle
13028 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
13029 check. */
13030 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
13031 && (info_ptr->first_altivec_reg_save
13032 >= FIRST_SAVED_ALTIVEC_REGNO));
13034 return;
13038 static void
13039 is_altivec_return_reg (rtx reg, void *xyes)
13041 bool *yes = (bool *) xyes;
13042 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
13043 *yes = true;
13047 /* Calculate the stack information for the current function. This is
13048 complicated by having two separate calling sequences, the AIX calling
13049 sequence and the V.4 calling sequence.
13051 AIX (and Darwin/Mac OS X) stack frames look like:
13052 32-bit 64-bit
13053 SP----> +---------------------------------------+
13054 | back chain to caller | 0 0
13055 +---------------------------------------+
13056 | saved CR | 4 8 (8-11)
13057 +---------------------------------------+
13058 | saved LR | 8 16
13059 +---------------------------------------+
13060 | reserved for compilers | 12 24
13061 +---------------------------------------+
13062 | reserved for binders | 16 32
13063 +---------------------------------------+
13064 | saved TOC pointer | 20 40
13065 +---------------------------------------+
13066 | Parameter save area (P) | 24 48
13067 +---------------------------------------+
13068 | Alloca space (A) | 24+P etc.
13069 +---------------------------------------+
13070 | Local variable space (L) | 24+P+A
13071 +---------------------------------------+
13072 | Float/int conversion temporary (X) | 24+P+A+L
13073 +---------------------------------------+
13074 | Save area for AltiVec registers (W) | 24+P+A+L+X
13075 +---------------------------------------+
13076 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
13077 +---------------------------------------+
13078 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
13079 +---------------------------------------+
13080 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
13081 +---------------------------------------+
13082 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
13083 +---------------------------------------+
13084 old SP->| back chain to caller's caller |
13085 +---------------------------------------+
13087 The required alignment for AIX configurations is two words (i.e., 8
13088 or 16 bytes).
13091 V.4 stack frames look like:
13093 SP----> +---------------------------------------+
13094 | back chain to caller | 0
13095 +---------------------------------------+
13096 | caller's saved LR | 4
13097 +---------------------------------------+
13098 | Parameter save area (P) | 8
13099 +---------------------------------------+
13100 | Alloca space (A) | 8+P
13101 +---------------------------------------+
13102 | Varargs save area (V) | 8+P+A
13103 +---------------------------------------+
13104 | Local variable space (L) | 8+P+A+V
13105 +---------------------------------------+
13106 | Float/int conversion temporary (X) | 8+P+A+V+L
13107 +---------------------------------------+
13108 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
13109 +---------------------------------------+
13110 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
13111 +---------------------------------------+
13112 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
13113 +---------------------------------------+
13114 | SPE: area for 64-bit GP registers |
13115 +---------------------------------------+
13116 | SPE alignment padding |
13117 +---------------------------------------+
13118 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
13119 +---------------------------------------+
13120 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
13121 +---------------------------------------+
13122 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
13123 +---------------------------------------+
13124 old SP->| back chain to caller's caller |
13125 +---------------------------------------+
13127 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
13128 given. (But note below and in sysv4.h that we require only 8 and
13129 may round up the size of our stack frame anyways. The historical
13130 reason is early versions of powerpc-linux which didn't properly
13131 align the stack at program startup. A happy side-effect is that
13132 -mno-eabi libraries can be used with -meabi programs.)
13134 The EABI configuration defaults to the V.4 layout. However,
13135 the stack alignment requirements may differ. If -mno-eabi is not
13136 given, the required stack alignment is 8 bytes; if -mno-eabi is
13137 given, the required alignment is 16 bytes. (But see V.4 comment
13138 above.) */
13140 #ifndef ABI_STACK_BOUNDARY
13141 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
13142 #endif
13144 static rs6000_stack_t *
13145 rs6000_stack_info (void)
13147 static rs6000_stack_t info;
13148 rs6000_stack_t *info_ptr = &info;
13149 int reg_size = TARGET_32BIT ? 4 : 8;
13150 int ehrd_size;
13151 int save_align;
13152 HOST_WIDE_INT non_fixed_size;
13154 memset (&info, 0, sizeof (info));
13156 if (TARGET_SPE)
13158 /* Cache value so we don't rescan instruction chain over and over. */
13159 if (cfun->machine->insn_chain_scanned_p == 0)
13160 cfun->machine->insn_chain_scanned_p
13161 = spe_func_has_64bit_regs_p () + 1;
13162 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
13165 /* Select which calling sequence. */
13166 info_ptr->abi = DEFAULT_ABI;
13168 /* Calculate which registers need to be saved & save area size. */
13169 info_ptr->first_gp_reg_save = first_reg_to_save ();
13170 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
13171 even if it currently looks like we won't. */
13172 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
13173 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
13174 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
13175 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
13176 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
13177 else
13178 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
13180 /* For the SPE, we have an additional upper 32-bits on each GPR.
13181 Ideally we should save the entire 64-bits only when the upper
13182 half is used in SIMD instructions. Since we only record
13183 registers live (not the size they are used in), this proves
13184 difficult because we'd have to traverse the instruction chain at
13185 the right time, taking reload into account. This is a real pain,
13186 so we opt to save the GPRs in 64-bits always if but one register
13187 gets used in 64-bits. Otherwise, all the registers in the frame
13188 get saved in 32-bits.
13190 So... since when we save all GPRs (except the SP) in 64-bits, the
13191 traditional GP save area will be empty. */
13192 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13193 info_ptr->gp_size = 0;
13195 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
13196 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
13198 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
13199 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
13200 - info_ptr->first_altivec_reg_save);
13202 /* Does this function call anything? */
13203 info_ptr->calls_p = (! current_function_is_leaf
13204 || cfun->machine->ra_needs_full_frame);
13206 /* Determine if we need to save the link register. */
13207 if ((DEFAULT_ABI == ABI_AIX
13208 && current_function_profile
13209 && !TARGET_PROFILE_KERNEL)
13210 #ifdef TARGET_RELOCATABLE
13211 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
13212 #endif
13213 || (info_ptr->first_fp_reg_save != 64
13214 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
13215 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
13216 || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
13217 || info_ptr->calls_p
13218 || rs6000_ra_ever_killed ())
13220 info_ptr->lr_save_p = 1;
13221 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
13224 /* Determine if we need to save the condition code registers. */
13225 if (regs_ever_live[CR2_REGNO]
13226 || regs_ever_live[CR3_REGNO]
13227 || regs_ever_live[CR4_REGNO])
13229 info_ptr->cr_save_p = 1;
13230 if (DEFAULT_ABI == ABI_V4)
13231 info_ptr->cr_size = reg_size;
13234 /* If the current function calls __builtin_eh_return, then we need
13235 to allocate stack space for registers that will hold data for
13236 the exception handler. */
13237 if (current_function_calls_eh_return)
13239 unsigned int i;
13240 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
13241 continue;
13243 /* SPE saves EH registers in 64-bits. */
13244 ehrd_size = i * (TARGET_SPE_ABI
13245 && info_ptr->spe_64bit_regs_used != 0
13246 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
13248 else
13249 ehrd_size = 0;
13251 /* Determine various sizes. */
13252 info_ptr->reg_size = reg_size;
13253 info_ptr->fixed_size = RS6000_SAVE_AREA;
13254 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
13255 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
13256 TARGET_ALTIVEC ? 16 : 8);
13257 if (FRAME_GROWS_DOWNWARD)
13258 info_ptr->vars_size
13259 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
13260 + info_ptr->parm_size,
13261 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
13262 - (info_ptr->fixed_size + info_ptr->vars_size
13263 + info_ptr->parm_size);
13265 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13266 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
13267 else
13268 info_ptr->spe_gp_size = 0;
13270 if (TARGET_ALTIVEC_ABI)
13271 info_ptr->vrsave_mask = compute_vrsave_mask ();
13272 else
13273 info_ptr->vrsave_mask = 0;
13275 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
13276 info_ptr->vrsave_size = 4;
13277 else
13278 info_ptr->vrsave_size = 0;
13280 compute_save_world_info (info_ptr);
13282 /* Calculate the offsets. */
13283 switch (DEFAULT_ABI)
13285 case ABI_NONE:
13286 default:
13287 gcc_unreachable ();
13289 case ABI_AIX:
13290 case ABI_DARWIN:
13291 info_ptr->fp_save_offset = - info_ptr->fp_size;
13292 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
13294 if (TARGET_ALTIVEC_ABI)
13296 info_ptr->vrsave_save_offset
13297 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
13299 /* Align stack so vector save area is on a quadword boundary. */
13300 if (info_ptr->altivec_size != 0)
13301 info_ptr->altivec_padding_size
13302 = 16 - (-info_ptr->vrsave_save_offset % 16);
13303 else
13304 info_ptr->altivec_padding_size = 0;
13306 info_ptr->altivec_save_offset
13307 = info_ptr->vrsave_save_offset
13308 - info_ptr->altivec_padding_size
13309 - info_ptr->altivec_size;
13311 /* Adjust for AltiVec case. */
13312 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
13314 else
13315 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
13316 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
13317 info_ptr->lr_save_offset = 2*reg_size;
13318 break;
13320 case ABI_V4:
13321 info_ptr->fp_save_offset = - info_ptr->fp_size;
13322 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
13323 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
13325 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13327 /* Align stack so SPE GPR save area is aligned on a
13328 double-word boundary. */
13329 if (info_ptr->spe_gp_size != 0)
13330 info_ptr->spe_padding_size
13331 = 8 - (-info_ptr->cr_save_offset % 8);
13332 else
13333 info_ptr->spe_padding_size = 0;
13335 info_ptr->spe_gp_save_offset
13336 = info_ptr->cr_save_offset
13337 - info_ptr->spe_padding_size
13338 - info_ptr->spe_gp_size;
13340 /* Adjust for SPE case. */
13341 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
13343 else if (TARGET_ALTIVEC_ABI)
13345 info_ptr->vrsave_save_offset
13346 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
13348 /* Align stack so vector save area is on a quadword boundary. */
13349 if (info_ptr->altivec_size != 0)
13350 info_ptr->altivec_padding_size
13351 = 16 - (-info_ptr->vrsave_save_offset % 16);
13352 else
13353 info_ptr->altivec_padding_size = 0;
13355 info_ptr->altivec_save_offset
13356 = info_ptr->vrsave_save_offset
13357 - info_ptr->altivec_padding_size
13358 - info_ptr->altivec_size;
13360 /* Adjust for AltiVec case. */
13361 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
13363 else
13364 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
13365 info_ptr->ehrd_offset -= ehrd_size;
13366 info_ptr->lr_save_offset = reg_size;
13367 break;
13370 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
13371 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
13372 + info_ptr->gp_size
13373 + info_ptr->altivec_size
13374 + info_ptr->altivec_padding_size
13375 + info_ptr->spe_gp_size
13376 + info_ptr->spe_padding_size
13377 + ehrd_size
13378 + info_ptr->cr_size
13379 + info_ptr->vrsave_size,
13380 save_align);
13382 non_fixed_size = (info_ptr->vars_size
13383 + info_ptr->parm_size
13384 + info_ptr->save_size);
13386 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
13387 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
13389 /* Determine if we need to allocate any stack frame:
13391 For AIX we need to push the stack if a frame pointer is needed
13392 (because the stack might be dynamically adjusted), if we are
13393 debugging, if we make calls, or if the sum of fp_save, gp_save,
13394 and local variables are more than the space needed to save all
13395 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
13396 + 18*8 = 288 (GPR13 reserved).
13398 For V.4 we don't have the stack cushion that AIX uses, but assume
13399 that the debugger can handle stackless frames. */
13401 if (info_ptr->calls_p)
13402 info_ptr->push_p = 1;
13404 else if (DEFAULT_ABI == ABI_V4)
13405 info_ptr->push_p = non_fixed_size != 0;
13407 else if (frame_pointer_needed)
13408 info_ptr->push_p = 1;
13410 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
13411 info_ptr->push_p = 1;
13413 else
13414 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
13416 /* Zero offsets if we're not saving those registers. */
13417 if (info_ptr->fp_size == 0)
13418 info_ptr->fp_save_offset = 0;
13420 if (info_ptr->gp_size == 0)
13421 info_ptr->gp_save_offset = 0;
13423 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
13424 info_ptr->altivec_save_offset = 0;
13426 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
13427 info_ptr->vrsave_save_offset = 0;
13429 if (! TARGET_SPE_ABI
13430 || info_ptr->spe_64bit_regs_used == 0
13431 || info_ptr->spe_gp_size == 0)
13432 info_ptr->spe_gp_save_offset = 0;
13434 if (! info_ptr->lr_save_p)
13435 info_ptr->lr_save_offset = 0;
13437 if (! info_ptr->cr_save_p)
13438 info_ptr->cr_save_offset = 0;
13440 return info_ptr;
13443 /* Return true if the current function uses any GPRs in 64-bit SIMD
13444 mode. */
13446 static bool
13447 spe_func_has_64bit_regs_p (void)
13449 rtx insns, insn;
13451 /* Functions that save and restore all the call-saved registers will
13452 need to save/restore the registers in 64-bits. */
13453 if (current_function_calls_eh_return
13454 || current_function_calls_setjmp
13455 || current_function_has_nonlocal_goto)
13456 return true;
13458 insns = get_insns ();
13460 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
13462 if (INSN_P (insn))
13464 rtx i;
13466 /* FIXME: This should be implemented with attributes...
13468 (set_attr "spe64" "true")....then,
13469 if (get_spe64(insn)) return true;
13471 It's the only reliable way to do the stuff below. */
13473 i = PATTERN (insn);
13474 if (GET_CODE (i) == SET)
13476 enum machine_mode mode = GET_MODE (SET_SRC (i));
13478 if (SPE_VECTOR_MODE (mode))
13479 return true;
13480 if (TARGET_E500_DOUBLE && mode == DFmode)
13481 return true;
13486 return false;
13489 static void
13490 debug_stack_info (rs6000_stack_t *info)
13492 const char *abi_string;
13494 if (! info)
13495 info = rs6000_stack_info ();
13497 fprintf (stderr, "\nStack information for function %s:\n",
13498 ((current_function_decl && DECL_NAME (current_function_decl))
13499 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
13500 : "<unknown>"));
13502 switch (info->abi)
13504 default: abi_string = "Unknown"; break;
13505 case ABI_NONE: abi_string = "NONE"; break;
13506 case ABI_AIX: abi_string = "AIX"; break;
13507 case ABI_DARWIN: abi_string = "Darwin"; break;
13508 case ABI_V4: abi_string = "V.4"; break;
13511 fprintf (stderr, "\tABI = %5s\n", abi_string);
13513 if (TARGET_ALTIVEC_ABI)
13514 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
13516 if (TARGET_SPE_ABI)
13517 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
13519 if (info->first_gp_reg_save != 32)
13520 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
13522 if (info->first_fp_reg_save != 64)
13523 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
13525 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
13526 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
13527 info->first_altivec_reg_save);
13529 if (info->lr_save_p)
13530 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
13532 if (info->cr_save_p)
13533 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
13535 if (info->vrsave_mask)
13536 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
13538 if (info->push_p)
13539 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
13541 if (info->calls_p)
13542 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
13544 if (info->gp_save_offset)
13545 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
13547 if (info->fp_save_offset)
13548 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
13550 if (info->altivec_save_offset)
13551 fprintf (stderr, "\taltivec_save_offset = %5d\n",
13552 info->altivec_save_offset);
13554 if (info->spe_gp_save_offset)
13555 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
13556 info->spe_gp_save_offset);
13558 if (info->vrsave_save_offset)
13559 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
13560 info->vrsave_save_offset);
13562 if (info->lr_save_offset)
13563 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
13565 if (info->cr_save_offset)
13566 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
13568 if (info->varargs_save_offset)
13569 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
13571 if (info->total_size)
13572 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13573 info->total_size);
13575 if (info->vars_size)
13576 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13577 info->vars_size);
13579 if (info->parm_size)
13580 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
13582 if (info->fixed_size)
13583 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
13585 if (info->gp_size)
13586 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
13588 if (info->spe_gp_size)
13589 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
13591 if (info->fp_size)
13592 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
13594 if (info->altivec_size)
13595 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
13597 if (info->vrsave_size)
13598 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
13600 if (info->altivec_padding_size)
13601 fprintf (stderr, "\taltivec_padding_size= %5d\n",
13602 info->altivec_padding_size);
13604 if (info->spe_padding_size)
13605 fprintf (stderr, "\tspe_padding_size = %5d\n",
13606 info->spe_padding_size);
13608 if (info->cr_size)
13609 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
13611 if (info->save_size)
13612 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
13614 if (info->reg_size != 4)
13615 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
13617 fprintf (stderr, "\n");
13621 rs6000_return_addr (int count, rtx frame)
13623 /* Currently we don't optimize very well between prolog and body
13624 code and for PIC code the code can be actually quite bad, so
13625 don't try to be too clever here. */
13626 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
13628 cfun->machine->ra_needs_full_frame = 1;
13630 return
13631 gen_rtx_MEM
13632 (Pmode,
13633 memory_address
13634 (Pmode,
13635 plus_constant (copy_to_reg
13636 (gen_rtx_MEM (Pmode,
13637 memory_address (Pmode, frame))),
13638 RETURN_ADDRESS_OFFSET)));
13641 cfun->machine->ra_need_lr = 1;
13642 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
13645 /* Say whether a function is a candidate for sibcall handling or not.
13646 We do not allow indirect calls to be optimized into sibling calls.
13647 Also, we can't do it if there are any vector parameters; there's
13648 nowhere to put the VRsave code so it works; note that functions with
13649 vector parameters are required to have a prototype, so the argument
13650 type info must be available here. (The tail recursion case can work
13651 with vector parameters, but there's no way to distinguish here.) */
13652 static bool
13653 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
13655 tree type;
13656 if (decl)
13658 if (TARGET_ALTIVEC_VRSAVE)
13660 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
13661 type; type = TREE_CHAIN (type))
13663 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
13664 return false;
13667 if (DEFAULT_ABI == ABI_DARWIN
13668 || (*targetm.binds_local_p) (decl))
13670 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
13672 if (!lookup_attribute ("longcall", attr_list)
13673 || lookup_attribute ("shortcall", attr_list))
13674 return true;
13677 return false;
13680 /* NULL if INSN insn is valid within a low-overhead loop.
13681 Otherwise return why doloop cannot be applied.
13682 PowerPC uses the COUNT register for branch on table instructions. */
13684 static const char *
13685 rs6000_invalid_within_doloop (rtx insn)
13687 if (CALL_P (insn))
13688 return "Function call in the loop.";
13690 if (JUMP_P (insn)
13691 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
13692 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
13693 return "Computed branch in the loop.";
13695 return NULL;
13698 static int
13699 rs6000_ra_ever_killed (void)
13701 rtx top;
13702 rtx reg;
13703 rtx insn;
13705 if (current_function_is_thunk)
13706 return 0;
13708 /* regs_ever_live has LR marked as used if any sibcalls are present,
13709 but this should not force saving and restoring in the
13710 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13711 clobbers LR, so that is inappropriate. */
13713 /* Also, the prologue can generate a store into LR that
13714 doesn't really count, like this:
13716 move LR->R0
13717 bcl to set PIC register
13718 move LR->R31
13719 move R0->LR
13721 When we're called from the epilogue, we need to avoid counting
13722 this as a store. */
13724 push_topmost_sequence ();
13725 top = get_insns ();
13726 pop_topmost_sequence ();
13727 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
13729 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
13731 if (INSN_P (insn))
13733 if (CALL_P (insn))
13735 if (!SIBLING_CALL_P (insn))
13736 return 1;
13738 else if (find_regno_note (insn, REG_INC, LINK_REGISTER_REGNUM))
13739 return 1;
13740 else if (set_of (reg, insn) != NULL_RTX
13741 && !prologue_epilogue_contains (insn))
13742 return 1;
13745 return 0;
13748 /* Add a REG_MAYBE_DEAD note to the insn. */
13749 static void
13750 rs6000_maybe_dead (rtx insn)
13752 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
13753 const0_rtx,
13754 REG_NOTES (insn));
13757 /* Emit instructions needed to load the TOC register.
13758 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13759 a constant pool; or for SVR4 -fpic. */
13761 void
13762 rs6000_emit_load_toc_table (int fromprolog)
13764 rtx dest, insn;
13765 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
13767 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
13769 char buf[30];
13770 rtx lab, tmp1, tmp2, got, tempLR;
13772 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13773 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13774 if (flag_pic == 2)
13775 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13776 else
13777 got = rs6000_got_sym ();
13778 tmp1 = tmp2 = dest;
13779 if (!fromprolog)
13781 tmp1 = gen_reg_rtx (Pmode);
13782 tmp2 = gen_reg_rtx (Pmode);
13784 tempLR = (fromprolog
13785 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13786 : gen_reg_rtx (Pmode));
13787 insn = emit_insn (gen_load_toc_v4_PIC_1 (tempLR, lab));
13788 if (fromprolog)
13789 rs6000_maybe_dead (insn);
13790 insn = emit_move_insn (tmp1, tempLR);
13791 if (fromprolog)
13792 rs6000_maybe_dead (insn);
13793 insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
13794 if (fromprolog)
13795 rs6000_maybe_dead (insn);
13796 insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
13797 if (fromprolog)
13798 rs6000_maybe_dead (insn);
13800 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
13802 rtx tempLR = (fromprolog
13803 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13804 : gen_reg_rtx (Pmode));
13806 insn = emit_insn (gen_load_toc_v4_pic_si (tempLR));
13807 if (fromprolog)
13808 rs6000_maybe_dead (insn);
13809 insn = emit_move_insn (dest, tempLR);
13810 if (fromprolog)
13811 rs6000_maybe_dead (insn);
13813 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
13815 char buf[30];
13816 rtx tempLR = (fromprolog
13817 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13818 : gen_reg_rtx (Pmode));
13819 rtx temp0 = (fromprolog
13820 ? gen_rtx_REG (Pmode, 0)
13821 : gen_reg_rtx (Pmode));
13823 if (fromprolog)
13825 rtx symF, symL;
13827 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13828 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13830 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
13831 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13833 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
13834 symF)));
13835 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
13836 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
13837 symL,
13838 symF)));
13840 else
13842 rtx tocsym;
13844 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13845 emit_insn (gen_load_toc_v4_PIC_1b (tempLR, tocsym));
13846 emit_move_insn (dest, tempLR);
13847 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
13849 insn = emit_insn (gen_addsi3 (dest, temp0, dest));
13850 if (fromprolog)
13851 rs6000_maybe_dead (insn);
13853 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
13855 /* This is for AIX code running in non-PIC ELF32. */
13856 char buf[30];
13857 rtx realsym;
13858 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
13859 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13861 insn = emit_insn (gen_elf_high (dest, realsym));
13862 if (fromprolog)
13863 rs6000_maybe_dead (insn);
13864 insn = emit_insn (gen_elf_low (dest, dest, realsym));
13865 if (fromprolog)
13866 rs6000_maybe_dead (insn);
13868 else
13870 gcc_assert (DEFAULT_ABI == ABI_AIX);
13872 if (TARGET_32BIT)
13873 insn = emit_insn (gen_load_toc_aix_si (dest));
13874 else
13875 insn = emit_insn (gen_load_toc_aix_di (dest));
13876 if (fromprolog)
13877 rs6000_maybe_dead (insn);
13881 /* Emit instructions to restore the link register after determining where
13882 its value has been stored. */
13884 void
13885 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
13887 rs6000_stack_t *info = rs6000_stack_info ();
13888 rtx operands[2];
13890 operands[0] = source;
13891 operands[1] = scratch;
13893 if (info->lr_save_p)
13895 rtx frame_rtx = stack_pointer_rtx;
13896 HOST_WIDE_INT sp_offset = 0;
13897 rtx tmp;
13899 if (frame_pointer_needed
13900 || current_function_calls_alloca
13901 || info->total_size > 32767)
13903 tmp = gen_frame_mem (Pmode, frame_rtx);
13904 emit_move_insn (operands[1], tmp);
13905 frame_rtx = operands[1];
13907 else if (info->push_p)
13908 sp_offset = info->total_size;
13910 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
13911 tmp = gen_frame_mem (Pmode, tmp);
13912 emit_move_insn (tmp, operands[0]);
13914 else
13915 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
13918 static GTY(()) int set = -1;
13921 get_TOC_alias_set (void)
13923 if (set == -1)
13924 set = new_alias_set ();
13925 return set;
13928 /* This returns nonzero if the current function uses the TOC. This is
13929 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
13930 is generated by the ABI_V4 load_toc_* patterns. */
13931 #if TARGET_ELF
13932 static int
13933 uses_TOC (void)
13935 rtx insn;
13937 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
13938 if (INSN_P (insn))
13940 rtx pat = PATTERN (insn);
13941 int i;
13943 if (GET_CODE (pat) == PARALLEL)
13944 for (i = 0; i < XVECLEN (pat, 0); i++)
13946 rtx sub = XVECEXP (pat, 0, i);
13947 if (GET_CODE (sub) == USE)
13949 sub = XEXP (sub, 0);
13950 if (GET_CODE (sub) == UNSPEC
13951 && XINT (sub, 1) == UNSPEC_TOC)
13952 return 1;
13956 return 0;
13958 #endif
13961 create_TOC_reference (rtx symbol)
13963 if (no_new_pseudos)
13964 regs_ever_live[TOC_REGISTER] = 1;
13965 return gen_rtx_PLUS (Pmode,
13966 gen_rtx_REG (Pmode, TOC_REGISTER),
13967 gen_rtx_CONST (Pmode,
13968 gen_rtx_MINUS (Pmode, symbol,
13969 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
13972 /* If _Unwind_* has been called from within the same module,
13973 toc register is not guaranteed to be saved to 40(1) on function
13974 entry. Save it there in that case. */
13976 void
13977 rs6000_aix_emit_builtin_unwind_init (void)
13979 rtx mem;
13980 rtx stack_top = gen_reg_rtx (Pmode);
13981 rtx opcode_addr = gen_reg_rtx (Pmode);
13982 rtx opcode = gen_reg_rtx (SImode);
13983 rtx tocompare = gen_reg_rtx (SImode);
13984 rtx no_toc_save_needed = gen_label_rtx ();
13986 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
13987 emit_move_insn (stack_top, mem);
13989 mem = gen_frame_mem (Pmode,
13990 gen_rtx_PLUS (Pmode, stack_top,
13991 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
13992 emit_move_insn (opcode_addr, mem);
13993 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
13994 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
13995 : 0xE8410028, SImode));
13997 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
13998 SImode, NULL_RTX, NULL_RTX,
13999 no_toc_save_needed);
14001 mem = gen_frame_mem (Pmode,
14002 gen_rtx_PLUS (Pmode, stack_top,
14003 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
14004 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
14005 emit_label (no_toc_save_needed);
14008 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
14009 and the change to the stack pointer. */
14011 static void
14012 rs6000_emit_stack_tie (void)
14014 rtx mem = gen_frame_mem (BLKmode,
14015 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
14017 emit_insn (gen_stack_tie (mem));
14020 /* Emit the correct code for allocating stack space, as insns.
14021 If COPY_R12, make sure a copy of the old frame is left in r12.
14022 The generated code may use hard register 0 as a temporary. */
14024 static void
14025 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
14027 rtx insn;
14028 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14029 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
14030 rtx todec = gen_int_mode (-size, Pmode);
14032 if (INTVAL (todec) != -size)
14034 warning (0, "stack frame too large");
14035 emit_insn (gen_trap ());
14036 return;
14039 if (current_function_limit_stack)
14041 if (REG_P (stack_limit_rtx)
14042 && REGNO (stack_limit_rtx) > 1
14043 && REGNO (stack_limit_rtx) <= 31)
14045 emit_insn (TARGET_32BIT
14046 ? gen_addsi3 (tmp_reg,
14047 stack_limit_rtx,
14048 GEN_INT (size))
14049 : gen_adddi3 (tmp_reg,
14050 stack_limit_rtx,
14051 GEN_INT (size)));
14053 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
14054 const0_rtx));
14056 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
14057 && TARGET_32BIT
14058 && DEFAULT_ABI == ABI_V4)
14060 rtx toload = gen_rtx_CONST (VOIDmode,
14061 gen_rtx_PLUS (Pmode,
14062 stack_limit_rtx,
14063 GEN_INT (size)));
14065 emit_insn (gen_elf_high (tmp_reg, toload));
14066 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
14067 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
14068 const0_rtx));
14070 else
14071 warning (0, "stack limit expression is not supported");
14074 if (copy_r12 || ! TARGET_UPDATE)
14075 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
14077 if (TARGET_UPDATE)
14079 if (size > 32767)
14081 /* Need a note here so that try_split doesn't get confused. */
14082 if (get_last_insn () == NULL_RTX)
14083 emit_note (NOTE_INSN_DELETED);
14084 insn = emit_move_insn (tmp_reg, todec);
14085 try_split (PATTERN (insn), insn, 0);
14086 todec = tmp_reg;
14089 insn = emit_insn (TARGET_32BIT
14090 ? gen_movsi_update (stack_reg, stack_reg,
14091 todec, stack_reg)
14092 : gen_movdi_di_update (stack_reg, stack_reg,
14093 todec, stack_reg));
14095 else
14097 insn = emit_insn (TARGET_32BIT
14098 ? gen_addsi3 (stack_reg, stack_reg, todec)
14099 : gen_adddi3 (stack_reg, stack_reg, todec));
14100 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
14101 gen_rtx_REG (Pmode, 12));
14104 RTX_FRAME_RELATED_P (insn) = 1;
14105 REG_NOTES (insn) =
14106 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14107 gen_rtx_SET (VOIDmode, stack_reg,
14108 gen_rtx_PLUS (Pmode, stack_reg,
14109 GEN_INT (-size))),
14110 REG_NOTES (insn));
14113 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
14114 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
14115 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
14116 deduce these equivalences by itself so it wasn't necessary to hold
14117 its hand so much. */
14119 static void
14120 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
14121 rtx reg2, rtx rreg)
14123 rtx real, temp;
14125 /* copy_rtx will not make unique copies of registers, so we need to
14126 ensure we don't have unwanted sharing here. */
14127 if (reg == reg2)
14128 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
14130 if (reg == rreg)
14131 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
14133 real = copy_rtx (PATTERN (insn));
14135 if (reg2 != NULL_RTX)
14136 real = replace_rtx (real, reg2, rreg);
14138 real = replace_rtx (real, reg,
14139 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
14140 STACK_POINTER_REGNUM),
14141 GEN_INT (val)));
14143 /* We expect that 'real' is either a SET or a PARALLEL containing
14144 SETs (and possibly other stuff). In a PARALLEL, all the SETs
14145 are important so they all have to be marked RTX_FRAME_RELATED_P. */
14147 if (GET_CODE (real) == SET)
14149 rtx set = real;
14151 temp = simplify_rtx (SET_SRC (set));
14152 if (temp)
14153 SET_SRC (set) = temp;
14154 temp = simplify_rtx (SET_DEST (set));
14155 if (temp)
14156 SET_DEST (set) = temp;
14157 if (GET_CODE (SET_DEST (set)) == MEM)
14159 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
14160 if (temp)
14161 XEXP (SET_DEST (set), 0) = temp;
14164 else
14166 int i;
14168 gcc_assert (GET_CODE (real) == PARALLEL);
14169 for (i = 0; i < XVECLEN (real, 0); i++)
14170 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
14172 rtx set = XVECEXP (real, 0, i);
14174 temp = simplify_rtx (SET_SRC (set));
14175 if (temp)
14176 SET_SRC (set) = temp;
14177 temp = simplify_rtx (SET_DEST (set));
14178 if (temp)
14179 SET_DEST (set) = temp;
14180 if (GET_CODE (SET_DEST (set)) == MEM)
14182 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
14183 if (temp)
14184 XEXP (SET_DEST (set), 0) = temp;
14186 RTX_FRAME_RELATED_P (set) = 1;
14190 if (TARGET_SPE)
14191 real = spe_synthesize_frame_save (real);
14193 RTX_FRAME_RELATED_P (insn) = 1;
14194 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14195 real,
14196 REG_NOTES (insn));
14199 /* Given an SPE frame note, return a PARALLEL of SETs with the
14200 original note, plus a synthetic register save. */
14202 static rtx
14203 spe_synthesize_frame_save (rtx real)
14205 rtx synth, offset, reg, real2;
14207 if (GET_CODE (real) != SET
14208 || GET_MODE (SET_SRC (real)) != V2SImode)
14209 return real;
14211 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
14212 frame related note. The parallel contains a set of the register
14213 being saved, and another set to a synthetic register (n+1200).
14214 This is so we can differentiate between 64-bit and 32-bit saves.
14215 Words cannot describe this nastiness. */
14217 gcc_assert (GET_CODE (SET_DEST (real)) == MEM
14218 && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS
14219 && GET_CODE (SET_SRC (real)) == REG);
14221 /* Transform:
14222 (set (mem (plus (reg x) (const y)))
14223 (reg z))
14224 into:
14225 (set (mem (plus (reg x) (const y+4)))
14226 (reg z+1200))
14229 real2 = copy_rtx (real);
14230 PUT_MODE (SET_DEST (real2), SImode);
14231 reg = SET_SRC (real2);
14232 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
14233 synth = copy_rtx (real2);
14235 if (BYTES_BIG_ENDIAN)
14237 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
14238 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
14241 reg = SET_SRC (synth);
14243 synth = replace_rtx (synth, reg,
14244 gen_rtx_REG (SImode, REGNO (reg) + 1200));
14246 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
14247 synth = replace_rtx (synth, offset,
14248 GEN_INT (INTVAL (offset)
14249 + (BYTES_BIG_ENDIAN ? 0 : 4)));
14251 RTX_FRAME_RELATED_P (synth) = 1;
14252 RTX_FRAME_RELATED_P (real2) = 1;
14253 if (BYTES_BIG_ENDIAN)
14254 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
14255 else
14256 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
14258 return real;
14261 /* Returns an insn that has a vrsave set operation with the
14262 appropriate CLOBBERs. */
14264 static rtx
14265 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
14267 int nclobs, i;
14268 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
14269 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14271 clobs[0]
14272 = gen_rtx_SET (VOIDmode,
14273 vrsave,
14274 gen_rtx_UNSPEC_VOLATILE (SImode,
14275 gen_rtvec (2, reg, vrsave),
14276 UNSPECV_SET_VRSAVE));
14278 nclobs = 1;
14280 /* We need to clobber the registers in the mask so the scheduler
14281 does not move sets to VRSAVE before sets of AltiVec registers.
14283 However, if the function receives nonlocal gotos, reload will set
14284 all call saved registers live. We will end up with:
14286 (set (reg 999) (mem))
14287 (parallel [ (set (reg vrsave) (unspec blah))
14288 (clobber (reg 999))])
14290 The clobber will cause the store into reg 999 to be dead, and
14291 flow will attempt to delete an epilogue insn. In this case, we
14292 need an unspec use/set of the register. */
14294 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
14295 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14297 if (!epiloguep || call_used_regs [i])
14298 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
14299 gen_rtx_REG (V4SImode, i));
14300 else
14302 rtx reg = gen_rtx_REG (V4SImode, i);
14304 clobs[nclobs++]
14305 = gen_rtx_SET (VOIDmode,
14306 reg,
14307 gen_rtx_UNSPEC (V4SImode,
14308 gen_rtvec (1, reg), 27));
14312 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
14314 for (i = 0; i < nclobs; ++i)
14315 XVECEXP (insn, 0, i) = clobs[i];
14317 return insn;
14320 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
14321 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
14323 static void
14324 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
14325 unsigned int regno, int offset, HOST_WIDE_INT total_size)
14327 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
14328 rtx replacea, replaceb;
14330 int_rtx = GEN_INT (offset);
14332 /* Some cases that need register indexed addressing. */
14333 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
14334 || (TARGET_E500_DOUBLE && mode == DFmode)
14335 || (TARGET_SPE_ABI
14336 && SPE_VECTOR_MODE (mode)
14337 && !SPE_CONST_OFFSET_OK (offset)))
14339 /* Whomever calls us must make sure r11 is available in the
14340 flow path of instructions in the prologue. */
14341 offset_rtx = gen_rtx_REG (Pmode, 11);
14342 emit_move_insn (offset_rtx, int_rtx);
14344 replacea = offset_rtx;
14345 replaceb = int_rtx;
14347 else
14349 offset_rtx = int_rtx;
14350 replacea = NULL_RTX;
14351 replaceb = NULL_RTX;
14354 reg = gen_rtx_REG (mode, regno);
14355 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
14356 mem = gen_frame_mem (mode, addr);
14358 insn = emit_move_insn (mem, reg);
14360 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
14363 /* Emit an offset memory reference suitable for a frame store, while
14364 converting to a valid addressing mode. */
14366 static rtx
14367 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
14369 rtx int_rtx, offset_rtx;
14371 int_rtx = GEN_INT (offset);
14373 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
14374 || (TARGET_E500_DOUBLE && mode == DFmode))
14376 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14377 emit_move_insn (offset_rtx, int_rtx);
14379 else
14380 offset_rtx = int_rtx;
14382 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
14385 /* Look for user-defined global regs. We should not save and restore these,
14386 and cannot use stmw/lmw if there are any in its range. */
14388 static bool
14389 no_global_regs_above (int first_greg)
14391 int i;
14392 for (i = 0; i < 32 - first_greg; i++)
14393 if (global_regs[first_greg + i])
14394 return false;
14395 return true;
14398 #ifndef TARGET_FIX_AND_CONTINUE
14399 #define TARGET_FIX_AND_CONTINUE 0
14400 #endif
14402 /* Emit function prologue as insns. */
14404 void
14405 rs6000_emit_prologue (void)
14407 rs6000_stack_t *info = rs6000_stack_info ();
14408 enum machine_mode reg_mode = Pmode;
14409 int reg_size = TARGET_32BIT ? 4 : 8;
14410 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14411 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
14412 rtx frame_reg_rtx = sp_reg_rtx;
14413 rtx cr_save_rtx = NULL_RTX;
14414 rtx insn;
14415 int saving_FPRs_inline;
14416 int using_store_multiple;
14417 HOST_WIDE_INT sp_offset = 0;
14419 if (TARGET_FIX_AND_CONTINUE)
14421 /* gdb on darwin arranges to forward a function from the old
14422 address by modifying the first 5 instructions of the function
14423 to branch to the overriding function. This is necessary to
14424 permit function pointers that point to the old function to
14425 actually forward to the new function. */
14426 emit_insn (gen_nop ());
14427 emit_insn (gen_nop ());
14428 emit_insn (gen_nop ());
14429 emit_insn (gen_nop ());
14430 emit_insn (gen_nop ());
14433 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14435 reg_mode = V2SImode;
14436 reg_size = 8;
14439 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
14440 && (!TARGET_SPE_ABI
14441 || info->spe_64bit_regs_used == 0)
14442 && info->first_gp_reg_save < 31
14443 && no_global_regs_above (info->first_gp_reg_save));
14444 saving_FPRs_inline = (info->first_fp_reg_save == 64
14445 || FP_SAVE_INLINE (info->first_fp_reg_save)
14446 || current_function_calls_eh_return
14447 || cfun->machine->ra_need_lr);
14449 /* For V.4, update stack before we do any saving and set back pointer. */
14450 if (info->push_p
14451 && (DEFAULT_ABI == ABI_V4
14452 || current_function_calls_eh_return))
14454 if (info->total_size < 32767)
14455 sp_offset = info->total_size;
14456 else
14457 frame_reg_rtx = frame_ptr_rtx;
14458 rs6000_emit_allocate_stack (info->total_size,
14459 (frame_reg_rtx != sp_reg_rtx
14460 && (info->cr_save_p
14461 || info->lr_save_p
14462 || info->first_fp_reg_save < 64
14463 || info->first_gp_reg_save < 32
14464 )));
14465 if (frame_reg_rtx != sp_reg_rtx)
14466 rs6000_emit_stack_tie ();
14469 /* Handle world saves specially here. */
14470 if (WORLD_SAVE_P (info))
14472 int i, j, sz;
14473 rtx treg;
14474 rtvec p;
14476 /* save_world expects lr in r0. */
14477 if (info->lr_save_p)
14479 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14480 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14481 RTX_FRAME_RELATED_P (insn) = 1;
14484 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
14485 assumptions about the offsets of various bits of the stack
14486 frame. */
14487 gcc_assert (info->gp_save_offset == -220
14488 && info->fp_save_offset == -144
14489 && info->lr_save_offset == 8
14490 && info->cr_save_offset == 4
14491 && info->push_p
14492 && info->lr_save_p
14493 && (!current_function_calls_eh_return
14494 || info->ehrd_offset == -432)
14495 && info->vrsave_save_offset == -224
14496 && info->altivec_save_offset == (-224 -16 -192));
14498 treg = gen_rtx_REG (SImode, 11);
14499 emit_move_insn (treg, GEN_INT (-info->total_size));
14501 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
14502 in R11. It also clobbers R12, so beware! */
14504 /* Preserve CR2 for save_world prologues */
14505 sz = 6;
14506 sz += 32 - info->first_gp_reg_save;
14507 sz += 64 - info->first_fp_reg_save;
14508 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
14509 p = rtvec_alloc (sz);
14510 j = 0;
14511 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
14512 gen_rtx_REG (Pmode,
14513 LINK_REGISTER_REGNUM));
14514 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
14515 gen_rtx_SYMBOL_REF (Pmode,
14516 "*save_world"));
14517 /* We do floats first so that the instruction pattern matches
14518 properly. */
14519 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14521 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14522 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14523 GEN_INT (info->fp_save_offset
14524 + sp_offset + 8 * i));
14525 rtx mem = gen_frame_mem (DFmode, addr);
14527 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14529 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
14531 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
14532 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14533 GEN_INT (info->altivec_save_offset
14534 + sp_offset + 16 * i));
14535 rtx mem = gen_frame_mem (V4SImode, addr);
14537 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14539 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14541 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14542 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14543 GEN_INT (info->gp_save_offset
14544 + sp_offset + reg_size * i));
14545 rtx mem = gen_frame_mem (reg_mode, addr);
14547 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14551 /* CR register traditionally saved as CR2. */
14552 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14553 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14554 GEN_INT (info->cr_save_offset
14555 + sp_offset));
14556 rtx mem = gen_frame_mem (reg_mode, addr);
14558 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14560 /* Prevent any attempt to delete the setting of r0 and treg! */
14561 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 0));
14562 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, treg);
14563 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode, sp_reg_rtx);
14565 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14566 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14567 NULL_RTX, NULL_RTX);
14569 if (current_function_calls_eh_return)
14571 unsigned int i;
14572 for (i = 0; ; ++i)
14574 unsigned int regno = EH_RETURN_DATA_REGNO (i);
14575 if (regno == INVALID_REGNUM)
14576 break;
14577 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14578 info->ehrd_offset + sp_offset
14579 + reg_size * (int) i,
14580 info->total_size);
14585 /* Save AltiVec registers if needed. */
14586 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14588 int i;
14590 /* There should be a non inline version of this, for when we
14591 are saving lots of vector registers. */
14592 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14593 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14595 rtx areg, savereg, mem;
14596 int offset;
14598 offset = info->altivec_save_offset + sp_offset
14599 + 16 * (i - info->first_altivec_reg_save);
14601 savereg = gen_rtx_REG (V4SImode, i);
14603 areg = gen_rtx_REG (Pmode, 0);
14604 emit_move_insn (areg, GEN_INT (offset));
14606 /* AltiVec addressing mode is [reg+reg]. */
14607 mem = gen_frame_mem (V4SImode,
14608 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
14610 insn = emit_move_insn (mem, savereg);
14612 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14613 areg, GEN_INT (offset));
14617 /* VRSAVE is a bit vector representing which AltiVec registers
14618 are used. The OS uses this to determine which vector
14619 registers to save on a context switch. We need to save
14620 VRSAVE on the stack frame, add whatever AltiVec registers we
14621 used in this function, and do the corresponding magic in the
14622 epilogue. */
14624 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14625 && info->vrsave_mask != 0)
14627 rtx reg, mem, vrsave;
14628 int offset;
14630 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14631 as frame_reg_rtx and r11 as the static chain pointer for
14632 nested functions. */
14633 reg = gen_rtx_REG (SImode, 0);
14634 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14635 if (TARGET_MACHO)
14636 emit_insn (gen_get_vrsave_internal (reg));
14637 else
14638 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
14640 if (!WORLD_SAVE_P (info))
14642 /* Save VRSAVE. */
14643 offset = info->vrsave_save_offset + sp_offset;
14644 mem = gen_frame_mem (SImode,
14645 gen_rtx_PLUS (Pmode, frame_reg_rtx,
14646 GEN_INT (offset)));
14647 insn = emit_move_insn (mem, reg);
14650 /* Include the registers in the mask. */
14651 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
14653 insn = emit_insn (generate_set_vrsave (reg, info, 0));
14656 /* If we use the link register, get it into r0. */
14657 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14659 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14660 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14661 RTX_FRAME_RELATED_P (insn) = 1;
14664 /* If we need to save CR, put it into r12. */
14665 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
14667 rtx set;
14669 cr_save_rtx = gen_rtx_REG (SImode, 12);
14670 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14671 RTX_FRAME_RELATED_P (insn) = 1;
14672 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14673 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14674 But that's OK. All we have to do is specify that _one_ condition
14675 code register is saved in this stack slot. The thrower's epilogue
14676 will then restore all the call-saved registers.
14677 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14678 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
14679 gen_rtx_REG (SImode, CR2_REGNO));
14680 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14681 set,
14682 REG_NOTES (insn));
14685 /* Do any required saving of fpr's. If only one or two to save, do
14686 it ourselves. Otherwise, call function. */
14687 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
14689 int i;
14690 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14691 if ((regs_ever_live[info->first_fp_reg_save+i]
14692 && ! call_used_regs[info->first_fp_reg_save+i]))
14693 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
14694 info->first_fp_reg_save + i,
14695 info->fp_save_offset + sp_offset + 8 * i,
14696 info->total_size);
14698 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
14700 int i;
14701 char rname[30];
14702 const char *alloc_rname;
14703 rtvec p;
14704 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
14706 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
14707 gen_rtx_REG (Pmode,
14708 LINK_REGISTER_REGNUM));
14709 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
14710 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
14711 alloc_rname = ggc_strdup (rname);
14712 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
14713 gen_rtx_SYMBOL_REF (Pmode,
14714 alloc_rname));
14715 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14717 rtx addr, reg, mem;
14718 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14719 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14720 GEN_INT (info->fp_save_offset
14721 + sp_offset + 8*i));
14722 mem = gen_frame_mem (DFmode, addr);
14724 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
14726 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14727 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14728 NULL_RTX, NULL_RTX);
14731 /* Save GPRs. This is done as a PARALLEL if we are using
14732 the store-multiple instructions. */
14733 if (!WORLD_SAVE_P (info) && using_store_multiple)
14735 rtvec p;
14736 int i;
14737 p = rtvec_alloc (32 - info->first_gp_reg_save);
14738 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14740 rtx addr, reg, mem;
14741 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14742 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14743 GEN_INT (info->gp_save_offset
14744 + sp_offset
14745 + reg_size * i));
14746 mem = gen_frame_mem (reg_mode, addr);
14748 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
14750 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14751 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14752 NULL_RTX, NULL_RTX);
14754 else if (!WORLD_SAVE_P (info))
14756 int i;
14757 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14758 if ((regs_ever_live[info->first_gp_reg_save + i]
14759 && (!call_used_regs[info->first_gp_reg_save + i]
14760 || (i + info->first_gp_reg_save
14761 == RS6000_PIC_OFFSET_TABLE_REGNUM
14762 && TARGET_TOC && TARGET_MINIMAL_TOC)))
14763 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14764 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14765 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
14767 rtx addr, reg, mem;
14768 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14770 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14772 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
14773 rtx b;
14775 if (!SPE_CONST_OFFSET_OK (offset))
14777 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14778 emit_move_insn (b, GEN_INT (offset));
14780 else
14781 b = GEN_INT (offset);
14783 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
14784 mem = gen_frame_mem (V2SImode, addr);
14785 insn = emit_move_insn (mem, reg);
14787 if (GET_CODE (b) == CONST_INT)
14788 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14789 NULL_RTX, NULL_RTX);
14790 else
14791 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14792 b, GEN_INT (offset));
14794 else
14796 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14797 GEN_INT (info->gp_save_offset
14798 + sp_offset
14799 + reg_size * i));
14800 mem = gen_frame_mem (reg_mode, addr);
14802 insn = emit_move_insn (mem, reg);
14803 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14804 NULL_RTX, NULL_RTX);
14809 /* ??? There's no need to emit actual instructions here, but it's the
14810 easiest way to get the frame unwind information emitted. */
14811 if (!WORLD_SAVE_P (info) && current_function_calls_eh_return)
14813 unsigned int i, regno;
14815 /* In AIX ABI we need to pretend we save r2 here. */
14816 if (TARGET_AIX)
14818 rtx addr, reg, mem;
14820 reg = gen_rtx_REG (reg_mode, 2);
14821 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14822 GEN_INT (sp_offset + 5 * reg_size));
14823 mem = gen_frame_mem (reg_mode, addr);
14825 insn = emit_move_insn (mem, reg);
14826 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14827 NULL_RTX, NULL_RTX);
14828 PATTERN (insn) = gen_blockage ();
14831 for (i = 0; ; ++i)
14833 regno = EH_RETURN_DATA_REGNO (i);
14834 if (regno == INVALID_REGNUM)
14835 break;
14837 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14838 info->ehrd_offset + sp_offset
14839 + reg_size * (int) i,
14840 info->total_size);
14844 /* Save lr if we used it. */
14845 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14847 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14848 GEN_INT (info->lr_save_offset + sp_offset));
14849 rtx reg = gen_rtx_REG (Pmode, 0);
14850 rtx mem = gen_rtx_MEM (Pmode, addr);
14851 /* This should not be of frame_alias_set, because of
14852 __builtin_return_address. */
14854 insn = emit_move_insn (mem, reg);
14855 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14856 NULL_RTX, NULL_RTX);
14859 /* Save CR if we use any that must be preserved. */
14860 if (!WORLD_SAVE_P (info) && info->cr_save_p)
14862 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14863 GEN_INT (info->cr_save_offset + sp_offset));
14864 rtx mem = gen_frame_mem (SImode, addr);
14865 /* See the large comment above about why CR2_REGNO is used. */
14866 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
14868 /* If r12 was used to hold the original sp, copy cr into r0 now
14869 that it's free. */
14870 if (REGNO (frame_reg_rtx) == 12)
14872 rtx set;
14874 cr_save_rtx = gen_rtx_REG (SImode, 0);
14875 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14876 RTX_FRAME_RELATED_P (insn) = 1;
14877 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
14878 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14879 set,
14880 REG_NOTES (insn));
14883 insn = emit_move_insn (mem, cr_save_rtx);
14885 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14886 NULL_RTX, NULL_RTX);
14889 /* Update stack and set back pointer unless this is V.4,
14890 for which it was done previously. */
14891 if (!WORLD_SAVE_P (info) && info->push_p
14892 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
14893 rs6000_emit_allocate_stack (info->total_size, FALSE);
14895 /* Set frame pointer, if needed. */
14896 if (frame_pointer_needed)
14898 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
14899 sp_reg_rtx);
14900 RTX_FRAME_RELATED_P (insn) = 1;
14903 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
14904 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
14905 || (DEFAULT_ABI == ABI_V4
14906 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
14907 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
14909 /* If emit_load_toc_table will use the link register, we need to save
14910 it. We use R12 for this purpose because emit_load_toc_table
14911 can use register 0. This allows us to use a plain 'blr' to return
14912 from the procedure more often. */
14913 int save_LR_around_toc_setup = (TARGET_ELF
14914 && DEFAULT_ABI != ABI_AIX
14915 && flag_pic
14916 && ! info->lr_save_p
14917 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
14918 if (save_LR_around_toc_setup)
14920 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
14922 insn = emit_move_insn (frame_ptr_rtx, lr);
14923 rs6000_maybe_dead (insn);
14924 RTX_FRAME_RELATED_P (insn) = 1;
14926 rs6000_emit_load_toc_table (TRUE);
14928 insn = emit_move_insn (lr, frame_ptr_rtx);
14929 rs6000_maybe_dead (insn);
14930 RTX_FRAME_RELATED_P (insn) = 1;
14932 else
14933 rs6000_emit_load_toc_table (TRUE);
14936 #if TARGET_MACHO
14937 if (DEFAULT_ABI == ABI_DARWIN
14938 && flag_pic && current_function_uses_pic_offset_table)
14940 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
14941 rtx src = machopic_function_base_sym ();
14943 /* Save and restore LR locally around this call (in R0). */
14944 if (!info->lr_save_p)
14945 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode, 0), lr));
14947 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr, src)));
14949 insn = emit_move_insn (gen_rtx_REG (Pmode,
14950 RS6000_PIC_OFFSET_TABLE_REGNUM),
14951 lr);
14952 rs6000_maybe_dead (insn);
14954 if (!info->lr_save_p)
14955 rs6000_maybe_dead (emit_move_insn (lr, gen_rtx_REG (Pmode, 0)));
14957 #endif
14960 /* Write function prologue. */
14962 static void
14963 rs6000_output_function_prologue (FILE *file,
14964 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
14966 rs6000_stack_t *info = rs6000_stack_info ();
14968 if (TARGET_DEBUG_STACK)
14969 debug_stack_info (info);
14971 /* Write .extern for any function we will call to save and restore
14972 fp values. */
14973 if (info->first_fp_reg_save < 64
14974 && !FP_SAVE_INLINE (info->first_fp_reg_save))
14975 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
14976 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
14977 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
14978 RESTORE_FP_SUFFIX);
14980 /* Write .extern for AIX common mode routines, if needed. */
14981 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
14983 fputs ("\t.extern __mulh\n", file);
14984 fputs ("\t.extern __mull\n", file);
14985 fputs ("\t.extern __divss\n", file);
14986 fputs ("\t.extern __divus\n", file);
14987 fputs ("\t.extern __quoss\n", file);
14988 fputs ("\t.extern __quous\n", file);
14989 common_mode_defined = 1;
14992 if (! HAVE_prologue)
14994 start_sequence ();
14996 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
14997 the "toplevel" insn chain. */
14998 emit_note (NOTE_INSN_DELETED);
14999 rs6000_emit_prologue ();
15000 emit_note (NOTE_INSN_DELETED);
15002 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15004 rtx insn;
15005 unsigned addr = 0;
15006 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15008 INSN_ADDRESSES_NEW (insn, addr);
15009 addr += 4;
15013 if (TARGET_DEBUG_STACK)
15014 debug_rtx_list (get_insns (), 100);
15015 final (get_insns (), file, FALSE);
15016 end_sequence ();
15019 rs6000_pic_labelno++;
15022 /* Emit function epilogue as insns.
15024 At present, dwarf2out_frame_debug_expr doesn't understand
15025 register restores, so we don't bother setting RTX_FRAME_RELATED_P
15026 anywhere in the epilogue. Most of the insns below would in any case
15027 need special notes to explain where r11 is in relation to the stack. */
15029 void
15030 rs6000_emit_epilogue (int sibcall)
15032 rs6000_stack_t *info;
15033 int restoring_FPRs_inline;
15034 int using_load_multiple;
15035 int using_mtcr_multiple;
15036 int use_backchain_to_restore_sp;
15037 int sp_offset = 0;
15038 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
15039 rtx frame_reg_rtx = sp_reg_rtx;
15040 enum machine_mode reg_mode = Pmode;
15041 int reg_size = TARGET_32BIT ? 4 : 8;
15042 int i;
15044 info = rs6000_stack_info ();
15046 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15048 reg_mode = V2SImode;
15049 reg_size = 8;
15052 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
15053 && (!TARGET_SPE_ABI
15054 || info->spe_64bit_regs_used == 0)
15055 && info->first_gp_reg_save < 31
15056 && no_global_regs_above (info->first_gp_reg_save));
15057 restoring_FPRs_inline = (sibcall
15058 || current_function_calls_eh_return
15059 || info->first_fp_reg_save == 64
15060 || FP_SAVE_INLINE (info->first_fp_reg_save));
15061 use_backchain_to_restore_sp = (frame_pointer_needed
15062 || current_function_calls_alloca
15063 || info->total_size > 32767);
15064 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
15065 || rs6000_cpu == PROCESSOR_PPC603
15066 || rs6000_cpu == PROCESSOR_PPC750
15067 || optimize_size);
15069 if (WORLD_SAVE_P (info))
15071 int i, j;
15072 char rname[30];
15073 const char *alloc_rname;
15074 rtvec p;
15076 /* eh_rest_world_r10 will return to the location saved in the LR
15077 stack slot (which is not likely to be our caller.)
15078 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
15079 rest_world is similar, except any R10 parameter is ignored.
15080 The exception-handling stuff that was here in 2.95 is no
15081 longer necessary. */
15083 p = rtvec_alloc (9
15085 + 32 - info->first_gp_reg_save
15086 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
15087 + 63 + 1 - info->first_fp_reg_save);
15089 strcpy (rname, ((current_function_calls_eh_return) ?
15090 "*eh_rest_world_r10" : "*rest_world"));
15091 alloc_rname = ggc_strdup (rname);
15093 j = 0;
15094 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
15095 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
15096 gen_rtx_REG (Pmode,
15097 LINK_REGISTER_REGNUM));
15098 RTVEC_ELT (p, j++)
15099 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
15100 /* The instruction pattern requires a clobber here;
15101 it is shared with the restVEC helper. */
15102 RTVEC_ELT (p, j++)
15103 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
15106 /* CR register traditionally saved as CR2. */
15107 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
15108 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15109 GEN_INT (info->cr_save_offset));
15110 rtx mem = gen_frame_mem (reg_mode, addr);
15112 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15115 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15117 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15118 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15119 GEN_INT (info->gp_save_offset
15120 + reg_size * i));
15121 rtx mem = gen_frame_mem (reg_mode, addr);
15123 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15125 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
15127 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
15128 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15129 GEN_INT (info->altivec_save_offset
15130 + 16 * i));
15131 rtx mem = gen_frame_mem (V4SImode, addr);
15133 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15135 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
15137 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15138 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15139 GEN_INT (info->fp_save_offset
15140 + 8 * i));
15141 rtx mem = gen_frame_mem (DFmode, addr);
15143 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15145 RTVEC_ELT (p, j++)
15146 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
15147 RTVEC_ELT (p, j++)
15148 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
15149 RTVEC_ELT (p, j++)
15150 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
15151 RTVEC_ELT (p, j++)
15152 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
15153 RTVEC_ELT (p, j++)
15154 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
15155 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15157 return;
15160 /* If we have a frame pointer, a call to alloca, or a large stack
15161 frame, restore the old stack pointer using the backchain. Otherwise,
15162 we know what size to update it with. */
15163 if (use_backchain_to_restore_sp)
15165 /* Under V.4, don't reset the stack pointer until after we're done
15166 loading the saved registers. */
15167 if (DEFAULT_ABI == ABI_V4)
15168 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
15170 emit_move_insn (frame_reg_rtx,
15171 gen_rtx_MEM (Pmode, sp_reg_rtx));
15173 else if (info->push_p)
15175 if (DEFAULT_ABI == ABI_V4
15176 || current_function_calls_eh_return)
15177 sp_offset = info->total_size;
15178 else
15180 emit_insn (TARGET_32BIT
15181 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15182 GEN_INT (info->total_size))
15183 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15184 GEN_INT (info->total_size)));
15188 /* Restore AltiVec registers if needed. */
15189 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
15191 int i;
15193 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
15194 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
15196 rtx addr, areg, mem;
15198 areg = gen_rtx_REG (Pmode, 0);
15199 emit_move_insn
15200 (areg, GEN_INT (info->altivec_save_offset
15201 + sp_offset
15202 + 16 * (i - info->first_altivec_reg_save)));
15204 /* AltiVec addressing mode is [reg+reg]. */
15205 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
15206 mem = gen_frame_mem (V4SImode, addr);
15208 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
15212 /* Restore VRSAVE if needed. */
15213 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
15214 && info->vrsave_mask != 0)
15216 rtx addr, mem, reg;
15218 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15219 GEN_INT (info->vrsave_save_offset + sp_offset));
15220 mem = gen_frame_mem (SImode, addr);
15221 reg = gen_rtx_REG (SImode, 12);
15222 emit_move_insn (reg, mem);
15224 emit_insn (generate_set_vrsave (reg, info, 1));
15227 /* Get the old lr if we saved it. */
15228 if (info->lr_save_p)
15230 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
15231 info->lr_save_offset + sp_offset);
15233 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
15236 /* Get the old cr if we saved it. */
15237 if (info->cr_save_p)
15239 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15240 GEN_INT (info->cr_save_offset + sp_offset));
15241 rtx mem = gen_frame_mem (SImode, addr);
15243 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
15246 /* Set LR here to try to overlap restores below. */
15247 if (info->lr_save_p)
15248 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
15249 gen_rtx_REG (Pmode, 0));
15251 /* Load exception handler data registers, if needed. */
15252 if (current_function_calls_eh_return)
15254 unsigned int i, regno;
15256 if (TARGET_AIX)
15258 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15259 GEN_INT (sp_offset + 5 * reg_size));
15260 rtx mem = gen_frame_mem (reg_mode, addr);
15262 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
15265 for (i = 0; ; ++i)
15267 rtx mem;
15269 regno = EH_RETURN_DATA_REGNO (i);
15270 if (regno == INVALID_REGNUM)
15271 break;
15273 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
15274 info->ehrd_offset + sp_offset
15275 + reg_size * (int) i);
15277 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
15281 /* Restore GPRs. This is done as a PARALLEL if we are using
15282 the load-multiple instructions. */
15283 if (using_load_multiple)
15285 rtvec p;
15286 p = rtvec_alloc (32 - info->first_gp_reg_save);
15287 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15289 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15290 GEN_INT (info->gp_save_offset
15291 + sp_offset
15292 + reg_size * i));
15293 rtx mem = gen_frame_mem (reg_mode, addr);
15295 RTVEC_ELT (p, i) =
15296 gen_rtx_SET (VOIDmode,
15297 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
15298 mem);
15300 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15302 else
15303 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15304 if ((regs_ever_live[info->first_gp_reg_save + i]
15305 && (!call_used_regs[info->first_gp_reg_save + i]
15306 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
15307 && TARGET_TOC && TARGET_MINIMAL_TOC)))
15308 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
15309 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
15310 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
15312 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15313 GEN_INT (info->gp_save_offset
15314 + sp_offset
15315 + reg_size * i));
15316 rtx mem = gen_frame_mem (reg_mode, addr);
15318 /* Restore 64-bit quantities for SPE. */
15319 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15321 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
15322 rtx b;
15324 if (!SPE_CONST_OFFSET_OK (offset))
15326 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
15327 emit_move_insn (b, GEN_INT (offset));
15329 else
15330 b = GEN_INT (offset);
15332 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
15333 mem = gen_frame_mem (V2SImode, addr);
15336 emit_move_insn (gen_rtx_REG (reg_mode,
15337 info->first_gp_reg_save + i), mem);
15340 /* Restore fpr's if we need to do it without calling a function. */
15341 if (restoring_FPRs_inline)
15342 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15343 if ((regs_ever_live[info->first_fp_reg_save+i]
15344 && ! call_used_regs[info->first_fp_reg_save+i]))
15346 rtx addr, mem;
15347 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15348 GEN_INT (info->fp_save_offset
15349 + sp_offset
15350 + 8 * i));
15351 mem = gen_frame_mem (DFmode, addr);
15353 emit_move_insn (gen_rtx_REG (DFmode,
15354 info->first_fp_reg_save + i),
15355 mem);
15358 /* If we saved cr, restore it here. Just those that were used. */
15359 if (info->cr_save_p)
15361 rtx r12_rtx = gen_rtx_REG (SImode, 12);
15362 int count = 0;
15364 if (using_mtcr_multiple)
15366 for (i = 0; i < 8; i++)
15367 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15368 count++;
15369 gcc_assert (count);
15372 if (using_mtcr_multiple && count > 1)
15374 rtvec p;
15375 int ndx;
15377 p = rtvec_alloc (count);
15379 ndx = 0;
15380 for (i = 0; i < 8; i++)
15381 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15383 rtvec r = rtvec_alloc (2);
15384 RTVEC_ELT (r, 0) = r12_rtx;
15385 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
15386 RTVEC_ELT (p, ndx) =
15387 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
15388 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
15389 ndx++;
15391 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15392 gcc_assert (ndx == count);
15394 else
15395 for (i = 0; i < 8; i++)
15396 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15398 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
15399 CR0_REGNO+i),
15400 r12_rtx));
15404 /* If this is V.4, unwind the stack pointer after all of the loads
15405 have been done. */
15406 if (frame_reg_rtx != sp_reg_rtx)
15408 /* This blockage is needed so that sched doesn't decide to move
15409 the sp change before the register restores. */
15410 rs6000_emit_stack_tie ();
15411 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
15413 else if (sp_offset != 0)
15414 emit_insn (TARGET_32BIT
15415 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15416 GEN_INT (sp_offset))
15417 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15418 GEN_INT (sp_offset)));
15420 if (current_function_calls_eh_return)
15422 rtx sa = EH_RETURN_STACKADJ_RTX;
15423 emit_insn (TARGET_32BIT
15424 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
15425 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
15428 if (!sibcall)
15430 rtvec p;
15431 if (! restoring_FPRs_inline)
15432 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
15433 else
15434 p = rtvec_alloc (2);
15436 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
15437 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
15438 gen_rtx_REG (Pmode,
15439 LINK_REGISTER_REGNUM));
15441 /* If we have to restore more than two FP registers, branch to the
15442 restore function. It will return to our caller. */
15443 if (! restoring_FPRs_inline)
15445 int i;
15446 char rname[30];
15447 const char *alloc_rname;
15449 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
15450 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
15451 alloc_rname = ggc_strdup (rname);
15452 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
15453 gen_rtx_SYMBOL_REF (Pmode,
15454 alloc_rname));
15456 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15458 rtx addr, mem;
15459 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
15460 GEN_INT (info->fp_save_offset + 8*i));
15461 mem = gen_frame_mem (DFmode, addr);
15463 RTVEC_ELT (p, i+3) =
15464 gen_rtx_SET (VOIDmode,
15465 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
15466 mem);
15470 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15474 /* Write function epilogue. */
15476 static void
15477 rs6000_output_function_epilogue (FILE *file,
15478 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
15480 if (! HAVE_epilogue)
15482 rtx insn = get_last_insn ();
15483 /* If the last insn was a BARRIER, we don't have to write anything except
15484 the trace table. */
15485 if (GET_CODE (insn) == NOTE)
15486 insn = prev_nonnote_insn (insn);
15487 if (insn == 0 || GET_CODE (insn) != BARRIER)
15489 /* This is slightly ugly, but at least we don't have two
15490 copies of the epilogue-emitting code. */
15491 start_sequence ();
15493 /* A NOTE_INSN_DELETED is supposed to be at the start
15494 and end of the "toplevel" insn chain. */
15495 emit_note (NOTE_INSN_DELETED);
15496 rs6000_emit_epilogue (FALSE);
15497 emit_note (NOTE_INSN_DELETED);
15499 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15501 rtx insn;
15502 unsigned addr = 0;
15503 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15505 INSN_ADDRESSES_NEW (insn, addr);
15506 addr += 4;
15510 if (TARGET_DEBUG_STACK)
15511 debug_rtx_list (get_insns (), 100);
15512 final (get_insns (), file, FALSE);
15513 end_sequence ();
15517 #if TARGET_MACHO
15518 macho_branch_islands ();
15519 /* Mach-O doesn't support labels at the end of objects, so if
15520 it looks like we might want one, insert a NOP. */
15522 rtx insn = get_last_insn ();
15523 while (insn
15524 && NOTE_P (insn)
15525 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL)
15526 insn = PREV_INSN (insn);
15527 if (insn
15528 && (LABEL_P (insn)
15529 || (NOTE_P (insn)
15530 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
15531 fputs ("\tnop\n", file);
15533 #endif
15535 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15536 on its format.
15538 We don't output a traceback table if -finhibit-size-directive was
15539 used. The documentation for -finhibit-size-directive reads
15540 ``don't output a @code{.size} assembler directive, or anything
15541 else that would cause trouble if the function is split in the
15542 middle, and the two halves are placed at locations far apart in
15543 memory.'' The traceback table has this property, since it
15544 includes the offset from the start of the function to the
15545 traceback table itself.
15547 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15548 different traceback table. */
15549 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
15550 && rs6000_traceback != traceback_none && !current_function_is_thunk)
15552 const char *fname = NULL;
15553 const char *language_string = lang_hooks.name;
15554 int fixed_parms = 0, float_parms = 0, parm_info = 0;
15555 int i;
15556 int optional_tbtab;
15557 rs6000_stack_t *info = rs6000_stack_info ();
15559 if (rs6000_traceback == traceback_full)
15560 optional_tbtab = 1;
15561 else if (rs6000_traceback == traceback_part)
15562 optional_tbtab = 0;
15563 else
15564 optional_tbtab = !optimize_size && !TARGET_ELF;
15566 if (optional_tbtab)
15568 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
15569 while (*fname == '.') /* V.4 encodes . in the name */
15570 fname++;
15572 /* Need label immediately before tbtab, so we can compute
15573 its offset from the function start. */
15574 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15575 ASM_OUTPUT_LABEL (file, fname);
15578 /* The .tbtab pseudo-op can only be used for the first eight
15579 expressions, since it can't handle the possibly variable
15580 length fields that follow. However, if you omit the optional
15581 fields, the assembler outputs zeros for all optional fields
15582 anyways, giving each variable length field is minimum length
15583 (as defined in sys/debug.h). Thus we can not use the .tbtab
15584 pseudo-op at all. */
15586 /* An all-zero word flags the start of the tbtab, for debuggers
15587 that have to find it by searching forward from the entry
15588 point or from the current pc. */
15589 fputs ("\t.long 0\n", file);
15591 /* Tbtab format type. Use format type 0. */
15592 fputs ("\t.byte 0,", file);
15594 /* Language type. Unfortunately, there does not seem to be any
15595 official way to discover the language being compiled, so we
15596 use language_string.
15597 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15598 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
15599 a number, so for now use 9. */
15600 if (! strcmp (language_string, "GNU C"))
15601 i = 0;
15602 else if (! strcmp (language_string, "GNU F77")
15603 || ! strcmp (language_string, "GNU F95"))
15604 i = 1;
15605 else if (! strcmp (language_string, "GNU Pascal"))
15606 i = 2;
15607 else if (! strcmp (language_string, "GNU Ada"))
15608 i = 3;
15609 else if (! strcmp (language_string, "GNU C++")
15610 || ! strcmp (language_string, "GNU Objective-C++"))
15611 i = 9;
15612 else if (! strcmp (language_string, "GNU Java"))
15613 i = 13;
15614 else if (! strcmp (language_string, "GNU Objective-C"))
15615 i = 14;
15616 else
15617 gcc_unreachable ();
15618 fprintf (file, "%d,", i);
15620 /* 8 single bit fields: global linkage (not set for C extern linkage,
15621 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15622 from start of procedure stored in tbtab, internal function, function
15623 has controlled storage, function has no toc, function uses fp,
15624 function logs/aborts fp operations. */
15625 /* Assume that fp operations are used if any fp reg must be saved. */
15626 fprintf (file, "%d,",
15627 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
15629 /* 6 bitfields: function is interrupt handler, name present in
15630 proc table, function calls alloca, on condition directives
15631 (controls stack walks, 3 bits), saves condition reg, saves
15632 link reg. */
15633 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15634 set up as a frame pointer, even when there is no alloca call. */
15635 fprintf (file, "%d,",
15636 ((optional_tbtab << 6)
15637 | ((optional_tbtab & frame_pointer_needed) << 5)
15638 | (info->cr_save_p << 1)
15639 | (info->lr_save_p)));
15641 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15642 (6 bits). */
15643 fprintf (file, "%d,",
15644 (info->push_p << 7) | (64 - info->first_fp_reg_save));
15646 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15647 fprintf (file, "%d,", (32 - first_reg_to_save ()));
15649 if (optional_tbtab)
15651 /* Compute the parameter info from the function decl argument
15652 list. */
15653 tree decl;
15654 int next_parm_info_bit = 31;
15656 for (decl = DECL_ARGUMENTS (current_function_decl);
15657 decl; decl = TREE_CHAIN (decl))
15659 rtx parameter = DECL_INCOMING_RTL (decl);
15660 enum machine_mode mode = GET_MODE (parameter);
15662 if (GET_CODE (parameter) == REG)
15664 if (SCALAR_FLOAT_MODE_P (mode))
15666 int bits;
15668 float_parms++;
15670 switch (mode)
15672 case SFmode:
15673 bits = 0x2;
15674 break;
15676 case DFmode:
15677 case TFmode:
15678 bits = 0x3;
15679 break;
15681 default:
15682 gcc_unreachable ();
15685 /* If only one bit will fit, don't or in this entry. */
15686 if (next_parm_info_bit > 0)
15687 parm_info |= (bits << (next_parm_info_bit - 1));
15688 next_parm_info_bit -= 2;
15690 else
15692 fixed_parms += ((GET_MODE_SIZE (mode)
15693 + (UNITS_PER_WORD - 1))
15694 / UNITS_PER_WORD);
15695 next_parm_info_bit -= 1;
15701 /* Number of fixed point parameters. */
15702 /* This is actually the number of words of fixed point parameters; thus
15703 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15704 fprintf (file, "%d,", fixed_parms);
15706 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15707 all on stack. */
15708 /* This is actually the number of fp registers that hold parameters;
15709 and thus the maximum value is 13. */
15710 /* Set parameters on stack bit if parameters are not in their original
15711 registers, regardless of whether they are on the stack? Xlc
15712 seems to set the bit when not optimizing. */
15713 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
15715 if (! optional_tbtab)
15716 return;
15718 /* Optional fields follow. Some are variable length. */
15720 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15721 11 double float. */
15722 /* There is an entry for each parameter in a register, in the order that
15723 they occur in the parameter list. Any intervening arguments on the
15724 stack are ignored. If the list overflows a long (max possible length
15725 34 bits) then completely leave off all elements that don't fit. */
15726 /* Only emit this long if there was at least one parameter. */
15727 if (fixed_parms || float_parms)
15728 fprintf (file, "\t.long %d\n", parm_info);
15730 /* Offset from start of code to tb table. */
15731 fputs ("\t.long ", file);
15732 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15733 if (TARGET_AIX)
15734 RS6000_OUTPUT_BASENAME (file, fname);
15735 else
15736 assemble_name (file, fname);
15737 putc ('-', file);
15738 rs6000_output_function_entry (file, fname);
15739 putc ('\n', file);
15741 /* Interrupt handler mask. */
15742 /* Omit this long, since we never set the interrupt handler bit
15743 above. */
15745 /* Number of CTL (controlled storage) anchors. */
15746 /* Omit this long, since the has_ctl bit is never set above. */
15748 /* Displacement into stack of each CTL anchor. */
15749 /* Omit this list of longs, because there are no CTL anchors. */
15751 /* Length of function name. */
15752 if (*fname == '*')
15753 ++fname;
15754 fprintf (file, "\t.short %d\n", (int) strlen (fname));
15756 /* Function name. */
15757 assemble_string (fname, strlen (fname));
15759 /* Register for alloca automatic storage; this is always reg 31.
15760 Only emit this if the alloca bit was set above. */
15761 if (frame_pointer_needed)
15762 fputs ("\t.byte 31\n", file);
15764 fputs ("\t.align 2\n", file);
15768 /* A C compound statement that outputs the assembler code for a thunk
15769 function, used to implement C++ virtual function calls with
15770 multiple inheritance. The thunk acts as a wrapper around a virtual
15771 function, adjusting the implicit object parameter before handing
15772 control off to the real function.
15774 First, emit code to add the integer DELTA to the location that
15775 contains the incoming first argument. Assume that this argument
15776 contains a pointer, and is the one used to pass the `this' pointer
15777 in C++. This is the incoming argument *before* the function
15778 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15779 values of all other incoming arguments.
15781 After the addition, emit code to jump to FUNCTION, which is a
15782 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15783 not touch the return address. Hence returning from FUNCTION will
15784 return to whoever called the current `thunk'.
15786 The effect must be as if FUNCTION had been called directly with the
15787 adjusted first argument. This macro is responsible for emitting
15788 all of the code for a thunk function; output_function_prologue()
15789 and output_function_epilogue() are not invoked.
15791 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15792 been extracted from it.) It might possibly be useful on some
15793 targets, but probably not.
15795 If you do not define this macro, the target-independent code in the
15796 C++ frontend will generate a less efficient heavyweight thunk that
15797 calls FUNCTION instead of jumping to it. The generic approach does
15798 not support varargs. */
15800 static void
15801 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
15802 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
15803 tree function)
15805 rtx this, insn, funexp;
15807 reload_completed = 1;
15808 epilogue_completed = 1;
15809 no_new_pseudos = 1;
15810 reset_block_changes ();
15812 /* Mark the end of the (empty) prologue. */
15813 emit_note (NOTE_INSN_PROLOGUE_END);
15815 /* Find the "this" pointer. If the function returns a structure,
15816 the structure return pointer is in r3. */
15817 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
15818 this = gen_rtx_REG (Pmode, 4);
15819 else
15820 this = gen_rtx_REG (Pmode, 3);
15822 /* Apply the constant offset, if required. */
15823 if (delta)
15825 rtx delta_rtx = GEN_INT (delta);
15826 emit_insn (TARGET_32BIT
15827 ? gen_addsi3 (this, this, delta_rtx)
15828 : gen_adddi3 (this, this, delta_rtx));
15831 /* Apply the offset from the vtable, if required. */
15832 if (vcall_offset)
15834 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
15835 rtx tmp = gen_rtx_REG (Pmode, 12);
15837 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
15838 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
15840 emit_insn (TARGET_32BIT
15841 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
15842 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
15843 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
15845 else
15847 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
15849 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
15851 emit_insn (TARGET_32BIT
15852 ? gen_addsi3 (this, this, tmp)
15853 : gen_adddi3 (this, this, tmp));
15856 /* Generate a tail call to the target function. */
15857 if (!TREE_USED (function))
15859 assemble_external (function);
15860 TREE_USED (function) = 1;
15862 funexp = XEXP (DECL_RTL (function), 0);
15863 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
15865 #if TARGET_MACHO
15866 if (MACHOPIC_INDIRECT)
15867 funexp = machopic_indirect_call_target (funexp);
15868 #endif
15870 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
15871 generate sibcall RTL explicitly. */
15872 insn = emit_call_insn (
15873 gen_rtx_PARALLEL (VOIDmode,
15874 gen_rtvec (4,
15875 gen_rtx_CALL (VOIDmode,
15876 funexp, const0_rtx),
15877 gen_rtx_USE (VOIDmode, const0_rtx),
15878 gen_rtx_USE (VOIDmode,
15879 gen_rtx_REG (SImode,
15880 LINK_REGISTER_REGNUM)),
15881 gen_rtx_RETURN (VOIDmode))));
15882 SIBLING_CALL_P (insn) = 1;
15883 emit_barrier ();
15885 /* Run just enough of rest_of_compilation to get the insns emitted.
15886 There's not really enough bulk here to make other passes such as
15887 instruction scheduling worth while. Note that use_thunk calls
15888 assemble_start_function and assemble_end_function. */
15889 insn = get_insns ();
15890 insn_locators_initialize ();
15891 shorten_branches (insn);
15892 final_start_function (insn, file, 1);
15893 final (insn, file, 1);
15894 final_end_function ();
15896 reload_completed = 0;
15897 epilogue_completed = 0;
15898 no_new_pseudos = 0;
15901 /* A quick summary of the various types of 'constant-pool tables'
15902 under PowerPC:
15904 Target Flags Name One table per
15905 AIX (none) AIX TOC object file
15906 AIX -mfull-toc AIX TOC object file
15907 AIX -mminimal-toc AIX minimal TOC translation unit
15908 SVR4/EABI (none) SVR4 SDATA object file
15909 SVR4/EABI -fpic SVR4 pic object file
15910 SVR4/EABI -fPIC SVR4 PIC translation unit
15911 SVR4/EABI -mrelocatable EABI TOC function
15912 SVR4/EABI -maix AIX TOC object file
15913 SVR4/EABI -maix -mminimal-toc
15914 AIX minimal TOC translation unit
15916 Name Reg. Set by entries contains:
15917 made by addrs? fp? sum?
15919 AIX TOC 2 crt0 as Y option option
15920 AIX minimal TOC 30 prolog gcc Y Y option
15921 SVR4 SDATA 13 crt0 gcc N Y N
15922 SVR4 pic 30 prolog ld Y not yet N
15923 SVR4 PIC 30 prolog gcc Y option option
15924 EABI TOC 30 prolog gcc Y option option
15928 /* Hash functions for the hash table. */
15930 static unsigned
15931 rs6000_hash_constant (rtx k)
15933 enum rtx_code code = GET_CODE (k);
15934 enum machine_mode mode = GET_MODE (k);
15935 unsigned result = (code << 3) ^ mode;
15936 const char *format;
15937 int flen, fidx;
15939 format = GET_RTX_FORMAT (code);
15940 flen = strlen (format);
15941 fidx = 0;
15943 switch (code)
15945 case LABEL_REF:
15946 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
15948 case CONST_DOUBLE:
15949 if (mode != VOIDmode)
15950 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
15951 flen = 2;
15952 break;
15954 case CODE_LABEL:
15955 fidx = 3;
15956 break;
15958 default:
15959 break;
15962 for (; fidx < flen; fidx++)
15963 switch (format[fidx])
15965 case 's':
15967 unsigned i, len;
15968 const char *str = XSTR (k, fidx);
15969 len = strlen (str);
15970 result = result * 613 + len;
15971 for (i = 0; i < len; i++)
15972 result = result * 613 + (unsigned) str[i];
15973 break;
15975 case 'u':
15976 case 'e':
15977 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
15978 break;
15979 case 'i':
15980 case 'n':
15981 result = result * 613 + (unsigned) XINT (k, fidx);
15982 break;
15983 case 'w':
15984 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
15985 result = result * 613 + (unsigned) XWINT (k, fidx);
15986 else
15988 size_t i;
15989 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
15990 result = result * 613 + (unsigned) (XWINT (k, fidx)
15991 >> CHAR_BIT * i);
15993 break;
15994 case '0':
15995 break;
15996 default:
15997 gcc_unreachable ();
16000 return result;
16003 static unsigned
16004 toc_hash_function (const void *hash_entry)
16006 const struct toc_hash_struct *thc =
16007 (const struct toc_hash_struct *) hash_entry;
16008 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
16011 /* Compare H1 and H2 for equivalence. */
16013 static int
16014 toc_hash_eq (const void *h1, const void *h2)
16016 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
16017 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
16019 if (((const struct toc_hash_struct *) h1)->key_mode
16020 != ((const struct toc_hash_struct *) h2)->key_mode)
16021 return 0;
16023 return rtx_equal_p (r1, r2);
16026 /* These are the names given by the C++ front-end to vtables, and
16027 vtable-like objects. Ideally, this logic should not be here;
16028 instead, there should be some programmatic way of inquiring as
16029 to whether or not an object is a vtable. */
16031 #define VTABLE_NAME_P(NAME) \
16032 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
16033 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
16034 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
16035 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
16036 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
16038 void
16039 rs6000_output_symbol_ref (FILE *file, rtx x)
16041 /* Currently C++ toc references to vtables can be emitted before it
16042 is decided whether the vtable is public or private. If this is
16043 the case, then the linker will eventually complain that there is
16044 a reference to an unknown section. Thus, for vtables only,
16045 we emit the TOC reference to reference the symbol and not the
16046 section. */
16047 const char *name = XSTR (x, 0);
16049 if (VTABLE_NAME_P (name))
16051 RS6000_OUTPUT_BASENAME (file, name);
16053 else
16054 assemble_name (file, name);
16057 /* Output a TOC entry. We derive the entry name from what is being
16058 written. */
16060 void
16061 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
16063 char buf[256];
16064 const char *name = buf;
16065 const char *real_name;
16066 rtx base = x;
16067 HOST_WIDE_INT offset = 0;
16069 gcc_assert (!TARGET_NO_TOC);
16071 /* When the linker won't eliminate them, don't output duplicate
16072 TOC entries (this happens on AIX if there is any kind of TOC,
16073 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
16074 CODE_LABELs. */
16075 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
16077 struct toc_hash_struct *h;
16078 void * * found;
16080 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
16081 time because GGC is not initialized at that point. */
16082 if (toc_hash_table == NULL)
16083 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
16084 toc_hash_eq, NULL);
16086 h = ggc_alloc (sizeof (*h));
16087 h->key = x;
16088 h->key_mode = mode;
16089 h->labelno = labelno;
16091 found = htab_find_slot (toc_hash_table, h, 1);
16092 if (*found == NULL)
16093 *found = h;
16094 else /* This is indeed a duplicate.
16095 Set this label equal to that label. */
16097 fputs ("\t.set ", file);
16098 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
16099 fprintf (file, "%d,", labelno);
16100 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
16101 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
16102 found)->labelno));
16103 return;
16107 /* If we're going to put a double constant in the TOC, make sure it's
16108 aligned properly when strict alignment is on. */
16109 if (GET_CODE (x) == CONST_DOUBLE
16110 && STRICT_ALIGNMENT
16111 && GET_MODE_BITSIZE (mode) >= 64
16112 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
16113 ASM_OUTPUT_ALIGN (file, 3);
16116 (*targetm.asm_out.internal_label) (file, "LC", labelno);
16118 /* Handle FP constants specially. Note that if we have a minimal
16119 TOC, things we put here aren't actually in the TOC, so we can allow
16120 FP constants. */
16121 if (GET_CODE (x) == CONST_DOUBLE &&
16122 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
16124 REAL_VALUE_TYPE rv;
16125 long k[4];
16127 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16128 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16129 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
16130 else
16131 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
16133 if (TARGET_64BIT)
16135 if (TARGET_MINIMAL_TOC)
16136 fputs (DOUBLE_INT_ASM_OP, file);
16137 else
16138 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16139 k[0] & 0xffffffff, k[1] & 0xffffffff,
16140 k[2] & 0xffffffff, k[3] & 0xffffffff);
16141 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
16142 k[0] & 0xffffffff, k[1] & 0xffffffff,
16143 k[2] & 0xffffffff, k[3] & 0xffffffff);
16144 return;
16146 else
16148 if (TARGET_MINIMAL_TOC)
16149 fputs ("\t.long ", file);
16150 else
16151 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16152 k[0] & 0xffffffff, k[1] & 0xffffffff,
16153 k[2] & 0xffffffff, k[3] & 0xffffffff);
16154 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
16155 k[0] & 0xffffffff, k[1] & 0xffffffff,
16156 k[2] & 0xffffffff, k[3] & 0xffffffff);
16157 return;
16160 else if (GET_CODE (x) == CONST_DOUBLE &&
16161 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
16163 REAL_VALUE_TYPE rv;
16164 long k[2];
16166 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16168 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16169 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
16170 else
16171 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
16173 if (TARGET_64BIT)
16175 if (TARGET_MINIMAL_TOC)
16176 fputs (DOUBLE_INT_ASM_OP, file);
16177 else
16178 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
16179 k[0] & 0xffffffff, k[1] & 0xffffffff);
16180 fprintf (file, "0x%lx%08lx\n",
16181 k[0] & 0xffffffff, k[1] & 0xffffffff);
16182 return;
16184 else
16186 if (TARGET_MINIMAL_TOC)
16187 fputs ("\t.long ", file);
16188 else
16189 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
16190 k[0] & 0xffffffff, k[1] & 0xffffffff);
16191 fprintf (file, "0x%lx,0x%lx\n",
16192 k[0] & 0xffffffff, k[1] & 0xffffffff);
16193 return;
16196 else if (GET_CODE (x) == CONST_DOUBLE &&
16197 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
16199 REAL_VALUE_TYPE rv;
16200 long l;
16202 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16203 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16204 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
16205 else
16206 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
16208 if (TARGET_64BIT)
16210 if (TARGET_MINIMAL_TOC)
16211 fputs (DOUBLE_INT_ASM_OP, file);
16212 else
16213 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
16214 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
16215 return;
16217 else
16219 if (TARGET_MINIMAL_TOC)
16220 fputs ("\t.long ", file);
16221 else
16222 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
16223 fprintf (file, "0x%lx\n", l & 0xffffffff);
16224 return;
16227 else if (GET_MODE (x) == VOIDmode
16228 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
16230 unsigned HOST_WIDE_INT low;
16231 HOST_WIDE_INT high;
16233 if (GET_CODE (x) == CONST_DOUBLE)
16235 low = CONST_DOUBLE_LOW (x);
16236 high = CONST_DOUBLE_HIGH (x);
16238 else
16239 #if HOST_BITS_PER_WIDE_INT == 32
16241 low = INTVAL (x);
16242 high = (low & 0x80000000) ? ~0 : 0;
16244 #else
16246 low = INTVAL (x) & 0xffffffff;
16247 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
16249 #endif
16251 /* TOC entries are always Pmode-sized, but since this
16252 is a bigendian machine then if we're putting smaller
16253 integer constants in the TOC we have to pad them.
16254 (This is still a win over putting the constants in
16255 a separate constant pool, because then we'd have
16256 to have both a TOC entry _and_ the actual constant.)
16258 For a 32-bit target, CONST_INT values are loaded and shifted
16259 entirely within `low' and can be stored in one TOC entry. */
16261 /* It would be easy to make this work, but it doesn't now. */
16262 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
16264 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
16266 #if HOST_BITS_PER_WIDE_INT == 32
16267 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
16268 POINTER_SIZE, &low, &high, 0);
16269 #else
16270 low |= high << 32;
16271 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
16272 high = (HOST_WIDE_INT) low >> 32;
16273 low &= 0xffffffff;
16274 #endif
16277 if (TARGET_64BIT)
16279 if (TARGET_MINIMAL_TOC)
16280 fputs (DOUBLE_INT_ASM_OP, file);
16281 else
16282 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
16283 (long) high & 0xffffffff, (long) low & 0xffffffff);
16284 fprintf (file, "0x%lx%08lx\n",
16285 (long) high & 0xffffffff, (long) low & 0xffffffff);
16286 return;
16288 else
16290 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
16292 if (TARGET_MINIMAL_TOC)
16293 fputs ("\t.long ", file);
16294 else
16295 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
16296 (long) high & 0xffffffff, (long) low & 0xffffffff);
16297 fprintf (file, "0x%lx,0x%lx\n",
16298 (long) high & 0xffffffff, (long) low & 0xffffffff);
16300 else
16302 if (TARGET_MINIMAL_TOC)
16303 fputs ("\t.long ", file);
16304 else
16305 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
16306 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
16308 return;
16312 if (GET_CODE (x) == CONST)
16314 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
16316 base = XEXP (XEXP (x, 0), 0);
16317 offset = INTVAL (XEXP (XEXP (x, 0), 1));
16320 switch (GET_CODE (base))
16322 case SYMBOL_REF:
16323 name = XSTR (base, 0);
16324 break;
16326 case LABEL_REF:
16327 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
16328 CODE_LABEL_NUMBER (XEXP (base, 0)));
16329 break;
16331 case CODE_LABEL:
16332 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
16333 break;
16335 default:
16336 gcc_unreachable ();
16339 real_name = (*targetm.strip_name_encoding) (name);
16340 if (TARGET_MINIMAL_TOC)
16341 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
16342 else
16344 fprintf (file, "\t.tc %s", real_name);
16346 if (offset < 0)
16347 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
16348 else if (offset)
16349 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
16351 fputs ("[TC],", file);
16354 /* Currently C++ toc references to vtables can be emitted before it
16355 is decided whether the vtable is public or private. If this is
16356 the case, then the linker will eventually complain that there is
16357 a TOC reference to an unknown section. Thus, for vtables only,
16358 we emit the TOC reference to reference the symbol and not the
16359 section. */
16360 if (VTABLE_NAME_P (name))
16362 RS6000_OUTPUT_BASENAME (file, name);
16363 if (offset < 0)
16364 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
16365 else if (offset > 0)
16366 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
16368 else
16369 output_addr_const (file, x);
16370 putc ('\n', file);
16373 /* Output an assembler pseudo-op to write an ASCII string of N characters
16374 starting at P to FILE.
16376 On the RS/6000, we have to do this using the .byte operation and
16377 write out special characters outside the quoted string.
16378 Also, the assembler is broken; very long strings are truncated,
16379 so we must artificially break them up early. */
16381 void
16382 output_ascii (FILE *file, const char *p, int n)
16384 char c;
16385 int i, count_string;
16386 const char *for_string = "\t.byte \"";
16387 const char *for_decimal = "\t.byte ";
16388 const char *to_close = NULL;
16390 count_string = 0;
16391 for (i = 0; i < n; i++)
16393 c = *p++;
16394 if (c >= ' ' && c < 0177)
16396 if (for_string)
16397 fputs (for_string, file);
16398 putc (c, file);
16400 /* Write two quotes to get one. */
16401 if (c == '"')
16403 putc (c, file);
16404 ++count_string;
16407 for_string = NULL;
16408 for_decimal = "\"\n\t.byte ";
16409 to_close = "\"\n";
16410 ++count_string;
16412 if (count_string >= 512)
16414 fputs (to_close, file);
16416 for_string = "\t.byte \"";
16417 for_decimal = "\t.byte ";
16418 to_close = NULL;
16419 count_string = 0;
16422 else
16424 if (for_decimal)
16425 fputs (for_decimal, file);
16426 fprintf (file, "%d", c);
16428 for_string = "\n\t.byte \"";
16429 for_decimal = ", ";
16430 to_close = "\n";
16431 count_string = 0;
16435 /* Now close the string if we have written one. Then end the line. */
16436 if (to_close)
16437 fputs (to_close, file);
16440 /* Generate a unique section name for FILENAME for a section type
16441 represented by SECTION_DESC. Output goes into BUF.
16443 SECTION_DESC can be any string, as long as it is different for each
16444 possible section type.
16446 We name the section in the same manner as xlc. The name begins with an
16447 underscore followed by the filename (after stripping any leading directory
16448 names) with the last period replaced by the string SECTION_DESC. If
16449 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16450 the name. */
16452 void
16453 rs6000_gen_section_name (char **buf, const char *filename,
16454 const char *section_desc)
16456 const char *q, *after_last_slash, *last_period = 0;
16457 char *p;
16458 int len;
16460 after_last_slash = filename;
16461 for (q = filename; *q; q++)
16463 if (*q == '/')
16464 after_last_slash = q + 1;
16465 else if (*q == '.')
16466 last_period = q;
16469 len = strlen (after_last_slash) + strlen (section_desc) + 2;
16470 *buf = (char *) xmalloc (len);
16472 p = *buf;
16473 *p++ = '_';
16475 for (q = after_last_slash; *q; q++)
16477 if (q == last_period)
16479 strcpy (p, section_desc);
16480 p += strlen (section_desc);
16481 break;
16484 else if (ISALNUM (*q))
16485 *p++ = *q;
16488 if (last_period == 0)
16489 strcpy (p, section_desc);
16490 else
16491 *p = '\0';
16494 /* Emit profile function. */
16496 void
16497 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
16499 /* Non-standard profiling for kernels, which just saves LR then calls
16500 _mcount without worrying about arg saves. The idea is to change
16501 the function prologue as little as possible as it isn't easy to
16502 account for arg save/restore code added just for _mcount. */
16503 if (TARGET_PROFILE_KERNEL)
16504 return;
16506 if (DEFAULT_ABI == ABI_AIX)
16508 #ifndef NO_PROFILE_COUNTERS
16509 # define NO_PROFILE_COUNTERS 0
16510 #endif
16511 if (NO_PROFILE_COUNTERS)
16512 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
16513 else
16515 char buf[30];
16516 const char *label_name;
16517 rtx fun;
16519 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16520 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
16521 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
16523 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
16524 fun, Pmode);
16527 else if (DEFAULT_ABI == ABI_DARWIN)
16529 const char *mcount_name = RS6000_MCOUNT;
16530 int caller_addr_regno = LINK_REGISTER_REGNUM;
16532 /* Be conservative and always set this, at least for now. */
16533 current_function_uses_pic_offset_table = 1;
16535 #if TARGET_MACHO
16536 /* For PIC code, set up a stub and collect the caller's address
16537 from r0, which is where the prologue puts it. */
16538 if (MACHOPIC_INDIRECT
16539 && current_function_uses_pic_offset_table)
16540 caller_addr_regno = 0;
16541 #endif
16542 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
16543 0, VOIDmode, 1,
16544 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
16548 /* Write function profiler code. */
16550 void
16551 output_function_profiler (FILE *file, int labelno)
16553 char buf[100];
16555 switch (DEFAULT_ABI)
16557 default:
16558 gcc_unreachable ();
16560 case ABI_V4:
16561 if (!TARGET_32BIT)
16563 warning (0, "no profiling of 64-bit code for this ABI");
16564 return;
16566 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16567 fprintf (file, "\tmflr %s\n", reg_names[0]);
16568 if (NO_PROFILE_COUNTERS)
16570 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16571 reg_names[0], reg_names[1]);
16573 else if (TARGET_SECURE_PLT && flag_pic)
16575 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16576 reg_names[0], reg_names[1]);
16577 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16578 asm_fprintf (file, "\t{cau|addis} %s,%s,",
16579 reg_names[12], reg_names[12]);
16580 assemble_name (file, buf);
16581 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
16582 assemble_name (file, buf);
16583 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
16585 else if (flag_pic == 1)
16587 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
16588 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16589 reg_names[0], reg_names[1]);
16590 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16591 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
16592 assemble_name (file, buf);
16593 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
16595 else if (flag_pic > 1)
16597 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16598 reg_names[0], reg_names[1]);
16599 /* Now, we need to get the address of the label. */
16600 fputs ("\tbcl 20,31,1f\n\t.long ", file);
16601 assemble_name (file, buf);
16602 fputs ("-.\n1:", file);
16603 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
16604 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
16605 reg_names[0], reg_names[11]);
16606 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
16607 reg_names[0], reg_names[0], reg_names[11]);
16609 else
16611 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
16612 assemble_name (file, buf);
16613 fputs ("@ha\n", file);
16614 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16615 reg_names[0], reg_names[1]);
16616 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
16617 assemble_name (file, buf);
16618 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
16621 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16622 fprintf (file, "\tbl %s%s\n",
16623 RS6000_MCOUNT, flag_pic ? "@plt" : "");
16624 break;
16626 case ABI_AIX:
16627 case ABI_DARWIN:
16628 if (!TARGET_PROFILE_KERNEL)
16630 /* Don't do anything, done in output_profile_hook (). */
16632 else
16634 gcc_assert (!TARGET_32BIT);
16636 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
16637 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
16639 if (cfun->static_chain_decl != NULL)
16641 asm_fprintf (file, "\tstd %s,24(%s)\n",
16642 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16643 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16644 asm_fprintf (file, "\tld %s,24(%s)\n",
16645 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16647 else
16648 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16650 break;
16656 /* The following variable value is the last issued insn. */
16658 static rtx last_scheduled_insn;
16660 /* The following variable helps to balance issuing of load and
16661 store instructions */
16663 static int load_store_pendulum;
16665 /* Power4 load update and store update instructions are cracked into a
16666 load or store and an integer insn which are executed in the same cycle.
16667 Branches have their own dispatch slot which does not count against the
16668 GCC issue rate, but it changes the program flow so there are no other
16669 instructions to issue in this cycle. */
16671 static int
16672 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
16673 int verbose ATTRIBUTE_UNUSED,
16674 rtx insn, int more)
16676 last_scheduled_insn = insn;
16677 if (GET_CODE (PATTERN (insn)) == USE
16678 || GET_CODE (PATTERN (insn)) == CLOBBER)
16680 cached_can_issue_more = more;
16681 return cached_can_issue_more;
16684 if (insn_terminates_group_p (insn, current_group))
16686 cached_can_issue_more = 0;
16687 return cached_can_issue_more;
16690 /* If no reservation, but reach here */
16691 if (recog_memoized (insn) < 0)
16692 return more;
16694 if (rs6000_sched_groups)
16696 if (is_microcoded_insn (insn))
16697 cached_can_issue_more = 0;
16698 else if (is_cracked_insn (insn))
16699 cached_can_issue_more = more > 2 ? more - 2 : 0;
16700 else
16701 cached_can_issue_more = more - 1;
16703 return cached_can_issue_more;
16706 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
16707 return 0;
16709 cached_can_issue_more = more - 1;
16710 return cached_can_issue_more;
16713 /* Adjust the cost of a scheduling dependency. Return the new cost of
16714 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16716 static int
16717 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
16719 enum attr_type attr_type;
16721 if (! recog_memoized (insn))
16722 return 0;
16724 switch (REG_NOTE_KIND (link))
16726 case REG_DEP_TRUE:
16728 /* Data dependency; DEP_INSN writes a register that INSN reads
16729 some cycles later. */
16731 /* Separate a load from a narrower, dependent store. */
16732 if (rs6000_sched_groups
16733 && GET_CODE (PATTERN (insn)) == SET
16734 && GET_CODE (PATTERN (dep_insn)) == SET
16735 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
16736 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
16737 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
16738 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
16739 return cost + 14;
16741 attr_type = get_attr_type (insn);
16743 switch (attr_type)
16745 case TYPE_JMPREG:
16746 /* Tell the first scheduling pass about the latency between
16747 a mtctr and bctr (and mtlr and br/blr). The first
16748 scheduling pass will not know about this latency since
16749 the mtctr instruction, which has the latency associated
16750 to it, will be generated by reload. */
16751 return TARGET_POWER ? 5 : 4;
16752 case TYPE_BRANCH:
16753 /* Leave some extra cycles between a compare and its
16754 dependent branch, to inhibit expensive mispredicts. */
16755 if ((rs6000_cpu_attr == CPU_PPC603
16756 || rs6000_cpu_attr == CPU_PPC604
16757 || rs6000_cpu_attr == CPU_PPC604E
16758 || rs6000_cpu_attr == CPU_PPC620
16759 || rs6000_cpu_attr == CPU_PPC630
16760 || rs6000_cpu_attr == CPU_PPC750
16761 || rs6000_cpu_attr == CPU_PPC7400
16762 || rs6000_cpu_attr == CPU_PPC7450
16763 || rs6000_cpu_attr == CPU_POWER4
16764 || rs6000_cpu_attr == CPU_POWER5
16765 || rs6000_cpu_attr == CPU_CELL)
16766 && recog_memoized (dep_insn)
16767 && (INSN_CODE (dep_insn) >= 0))
16769 switch (get_attr_type (dep_insn))
16771 case TYPE_CMP:
16772 case TYPE_COMPARE:
16773 case TYPE_DELAYED_COMPARE:
16774 case TYPE_IMUL_COMPARE:
16775 case TYPE_LMUL_COMPARE:
16776 case TYPE_FPCOMPARE:
16777 case TYPE_CR_LOGICAL:
16778 case TYPE_DELAYED_CR:
16779 return cost + 2;
16780 default:
16781 break;
16783 break;
16785 case TYPE_STORE:
16786 case TYPE_STORE_U:
16787 case TYPE_STORE_UX:
16788 case TYPE_FPSTORE:
16789 case TYPE_FPSTORE_U:
16790 case TYPE_FPSTORE_UX:
16791 if ((rs6000_cpu == PROCESSOR_POWER6)
16792 && recog_memoized (dep_insn)
16793 && (INSN_CODE (dep_insn) >= 0))
16796 if (GET_CODE (PATTERN (insn)) != SET)
16797 /* If this happens, we have to extend this to schedule
16798 optimally. Return default for now. */
16799 return cost;
16801 /* Adjust the cost for the case where the value written
16802 by a fixed point operation is used as the address
16803 gen value on a store. */
16804 switch (get_attr_type (dep_insn))
16806 case TYPE_LOAD:
16807 case TYPE_LOAD_U:
16808 case TYPE_LOAD_UX:
16809 case TYPE_CNTLZ:
16811 if (! store_data_bypass_p (dep_insn, insn))
16812 return 4;
16813 break;
16815 case TYPE_LOAD_EXT:
16816 case TYPE_LOAD_EXT_U:
16817 case TYPE_LOAD_EXT_UX:
16818 case TYPE_VAR_SHIFT_ROTATE:
16819 case TYPE_VAR_DELAYED_COMPARE:
16821 if (! store_data_bypass_p (dep_insn, insn))
16822 return 6;
16823 break;
16825 case TYPE_INTEGER:
16826 case TYPE_COMPARE:
16827 case TYPE_FAST_COMPARE:
16828 case TYPE_EXTS:
16829 case TYPE_SHIFT:
16830 case TYPE_INSERT_WORD:
16831 case TYPE_INSERT_DWORD:
16832 case TYPE_FPLOAD_U:
16833 case TYPE_FPLOAD_UX:
16834 case TYPE_STORE_U:
16835 case TYPE_STORE_UX:
16836 case TYPE_FPSTORE_U:
16837 case TYPE_FPSTORE_UX:
16839 if (! store_data_bypass_p (dep_insn, insn))
16840 return 3;
16841 break;
16843 case TYPE_IMUL:
16844 case TYPE_IMUL2:
16845 case TYPE_IMUL3:
16846 case TYPE_LMUL:
16847 case TYPE_IMUL_COMPARE:
16848 case TYPE_LMUL_COMPARE:
16850 if (! store_data_bypass_p (dep_insn, insn))
16851 return 17;
16852 break;
16854 case TYPE_IDIV:
16856 if (! store_data_bypass_p (dep_insn, insn))
16857 return 45;
16858 break;
16860 case TYPE_LDIV:
16862 if (! store_data_bypass_p (dep_insn, insn))
16863 return 57;
16864 break;
16866 default:
16867 break;
16870 break;
16872 case TYPE_LOAD:
16873 case TYPE_LOAD_U:
16874 case TYPE_LOAD_UX:
16875 case TYPE_LOAD_EXT:
16876 case TYPE_LOAD_EXT_U:
16877 case TYPE_LOAD_EXT_UX:
16878 if ((rs6000_cpu == PROCESSOR_POWER6)
16879 && recog_memoized (dep_insn)
16880 && (INSN_CODE (dep_insn) >= 0))
16883 /* Adjust the cost for the case where the value written
16884 by a fixed point instruction is used within the address
16885 gen portion of a subsequent load(u)(x) */
16886 switch (get_attr_type (dep_insn))
16888 case TYPE_LOAD:
16889 case TYPE_LOAD_U:
16890 case TYPE_LOAD_UX:
16891 case TYPE_CNTLZ:
16893 if (set_to_load_agen (dep_insn, insn))
16894 return 4;
16895 break;
16897 case TYPE_LOAD_EXT:
16898 case TYPE_LOAD_EXT_U:
16899 case TYPE_LOAD_EXT_UX:
16900 case TYPE_VAR_SHIFT_ROTATE:
16901 case TYPE_VAR_DELAYED_COMPARE:
16903 if (set_to_load_agen (dep_insn, insn))
16904 return 6;
16905 break;
16907 case TYPE_INTEGER:
16908 case TYPE_COMPARE:
16909 case TYPE_FAST_COMPARE:
16910 case TYPE_EXTS:
16911 case TYPE_SHIFT:
16912 case TYPE_INSERT_WORD:
16913 case TYPE_INSERT_DWORD:
16914 case TYPE_FPLOAD_U:
16915 case TYPE_FPLOAD_UX:
16916 case TYPE_STORE_U:
16917 case TYPE_STORE_UX:
16918 case TYPE_FPSTORE_U:
16919 case TYPE_FPSTORE_UX:
16921 if (set_to_load_agen (dep_insn, insn))
16922 return 3;
16923 break;
16925 case TYPE_IMUL:
16926 case TYPE_IMUL2:
16927 case TYPE_IMUL3:
16928 case TYPE_LMUL:
16929 case TYPE_IMUL_COMPARE:
16930 case TYPE_LMUL_COMPARE:
16932 if (set_to_load_agen (dep_insn, insn))
16933 return 17;
16934 break;
16936 case TYPE_IDIV:
16938 if (set_to_load_agen (dep_insn, insn))
16939 return 45;
16940 break;
16942 case TYPE_LDIV:
16944 if (set_to_load_agen (dep_insn, insn))
16945 return 57;
16946 break;
16948 default:
16949 break;
16952 break;
16954 case TYPE_FPLOAD:
16955 if ((rs6000_cpu == PROCESSOR_POWER6)
16956 && recog_memoized (dep_insn)
16957 && (INSN_CODE (dep_insn) >= 0)
16958 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
16959 return 2;
16961 default:
16962 break;
16965 /* Fall out to return default cost. */
16967 break;
16969 case REG_DEP_OUTPUT:
16970 /* Output dependency; DEP_INSN writes a register that INSN writes some
16971 cycles later. */
16972 if ((rs6000_cpu == PROCESSOR_POWER6)
16973 && recog_memoized (dep_insn)
16974 && (INSN_CODE (dep_insn) >= 0))
16976 attr_type = get_attr_type (insn);
16978 switch (attr_type)
16980 case TYPE_FP:
16981 if (get_attr_type (dep_insn) == TYPE_FP)
16982 return 1;
16983 break;
16984 case TYPE_FPLOAD:
16985 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
16986 return 2;
16987 break;
16988 default:
16989 break;
16992 case REG_DEP_ANTI:
16993 /* Anti dependency; DEP_INSN reads a register that INSN writes some
16994 cycles later. */
16995 return 0;
16997 default:
16998 gcc_unreachable ();
17001 return cost;
17004 /* The function returns a true if INSN is microcoded.
17005 Return false otherwise. */
17007 static bool
17008 is_microcoded_insn (rtx insn)
17010 if (!insn || !INSN_P (insn)
17011 || GET_CODE (PATTERN (insn)) == USE
17012 || GET_CODE (PATTERN (insn)) == CLOBBER)
17013 return false;
17015 if (rs6000_cpu_attr == CPU_CELL)
17016 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
17018 if (rs6000_sched_groups)
17020 enum attr_type type = get_attr_type (insn);
17021 if (type == TYPE_LOAD_EXT_U
17022 || type == TYPE_LOAD_EXT_UX
17023 || type == TYPE_LOAD_UX
17024 || type == TYPE_STORE_UX
17025 || type == TYPE_MFCR)
17026 return true;
17029 return false;
17032 /* The function returns true if INSN is cracked into 2 instructions
17033 by the processor (and therefore occupies 2 issue slots). */
17035 static bool
17036 is_cracked_insn (rtx insn)
17038 if (!insn || !INSN_P (insn)
17039 || GET_CODE (PATTERN (insn)) == USE
17040 || GET_CODE (PATTERN (insn)) == CLOBBER)
17041 return false;
17043 if (rs6000_sched_groups)
17045 enum attr_type type = get_attr_type (insn);
17046 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
17047 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
17048 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
17049 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
17050 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
17051 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
17052 || type == TYPE_IDIV || type == TYPE_LDIV
17053 || type == TYPE_INSERT_WORD)
17054 return true;
17057 return false;
17060 /* The function returns true if INSN can be issued only from
17061 the branch slot. */
17063 static bool
17064 is_branch_slot_insn (rtx insn)
17066 if (!insn || !INSN_P (insn)
17067 || GET_CODE (PATTERN (insn)) == USE
17068 || GET_CODE (PATTERN (insn)) == CLOBBER)
17069 return false;
17071 if (rs6000_sched_groups)
17073 enum attr_type type = get_attr_type (insn);
17074 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
17075 return true;
17076 return false;
17079 return false;
17082 /* The function returns true if out_inst sets a value that is
17083 used in the address generation computation of in_insn */
17084 static bool
17085 set_to_load_agen (rtx out_insn, rtx in_insn)
17087 rtx out_set, in_set;
17089 /* For performance reasons, only handle the simple case where
17090 both loads are a single_set. */
17091 out_set = single_set (out_insn);
17092 if (out_set)
17094 in_set = single_set (in_insn);
17095 if (in_set)
17096 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
17099 return false;
17102 /* The function returns true if the target storage location of
17103 out_insn is adjacent to the target storage location of in_insn */
17104 /* Return 1 if memory locations are adjacent. */
17106 static bool
17107 adjacent_mem_locations (rtx insn1, rtx insn2)
17110 rtx a = get_store_dest (PATTERN (insn1));
17111 rtx b = get_store_dest (PATTERN (insn2));
17113 if ((GET_CODE (XEXP (a, 0)) == REG
17114 || (GET_CODE (XEXP (a, 0)) == PLUS
17115 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
17116 && (GET_CODE (XEXP (b, 0)) == REG
17117 || (GET_CODE (XEXP (b, 0)) == PLUS
17118 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
17120 HOST_WIDE_INT val0 = 0, val1 = 0;
17121 rtx reg0, reg1;
17122 int val_diff;
17124 if (GET_CODE (XEXP (a, 0)) == PLUS)
17126 reg0 = XEXP (XEXP (a, 0), 0);
17127 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
17129 else
17130 reg0 = XEXP (a, 0);
17132 if (GET_CODE (XEXP (b, 0)) == PLUS)
17134 reg1 = XEXP (XEXP (b, 0), 0);
17135 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
17137 else
17138 reg1 = XEXP (b, 0);
17140 val_diff = val1 - val0;
17142 return ((REGNO (reg0) == REGNO (reg1))
17143 && (val_diff == INTVAL (MEM_SIZE (a))
17144 || val_diff == -INTVAL (MEM_SIZE (b))));
17147 return false;
17150 /* A C statement (sans semicolon) to update the integer scheduling
17151 priority INSN_PRIORITY (INSN). Increase the priority to execute the
17152 INSN earlier, reduce the priority to execute INSN later. Do not
17153 define this macro if you do not need to adjust the scheduling
17154 priorities of insns. */
17156 static int
17157 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
17159 /* On machines (like the 750) which have asymmetric integer units,
17160 where one integer unit can do multiply and divides and the other
17161 can't, reduce the priority of multiply/divide so it is scheduled
17162 before other integer operations. */
17164 #if 0
17165 if (! INSN_P (insn))
17166 return priority;
17168 if (GET_CODE (PATTERN (insn)) == USE)
17169 return priority;
17171 switch (rs6000_cpu_attr) {
17172 case CPU_PPC750:
17173 switch (get_attr_type (insn))
17175 default:
17176 break;
17178 case TYPE_IMUL:
17179 case TYPE_IDIV:
17180 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
17181 priority, priority);
17182 if (priority >= 0 && priority < 0x01000000)
17183 priority >>= 3;
17184 break;
17187 #endif
17189 if (insn_must_be_first_in_group (insn)
17190 && reload_completed
17191 && current_sched_info->sched_max_insns_priority
17192 && rs6000_sched_restricted_insns_priority)
17195 /* Prioritize insns that can be dispatched only in the first
17196 dispatch slot. */
17197 if (rs6000_sched_restricted_insns_priority == 1)
17198 /* Attach highest priority to insn. This means that in
17199 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
17200 precede 'priority' (critical path) considerations. */
17201 return current_sched_info->sched_max_insns_priority;
17202 else if (rs6000_sched_restricted_insns_priority == 2)
17203 /* Increase priority of insn by a minimal amount. This means that in
17204 haifa-sched.c:ready_sort(), only 'priority' (critical path)
17205 considerations precede dispatch-slot restriction considerations. */
17206 return (priority + 1);
17209 if (rs6000_cpu == PROCESSOR_POWER6
17210 && ((load_store_pendulum == -2 && is_load_insn (insn))
17211 || (load_store_pendulum == 2 && is_store_insn (insn))))
17212 /* Attach highest priority to insn if the scheduler has just issued two
17213 stores and this instruction is a load, or two loads and this instruction
17214 is a store. Power6 wants loads and stores scheduled alternately
17215 when possible */
17216 return current_sched_info->sched_max_insns_priority;
17218 return priority;
17221 /* Return true if the instruction is nonpipelined on the Cell. */
17222 static bool
17223 is_nonpipeline_insn (rtx insn)
17225 enum attr_type type;
17226 if (!insn || !INSN_P (insn)
17227 || GET_CODE (PATTERN (insn)) == USE
17228 || GET_CODE (PATTERN (insn)) == CLOBBER)
17229 return false;
17231 type = get_attr_type (insn);
17232 if (type == TYPE_IMUL
17233 || type == TYPE_IMUL2
17234 || type == TYPE_IMUL3
17235 || type == TYPE_LMUL
17236 || type == TYPE_IDIV
17237 || type == TYPE_LDIV
17238 || type == TYPE_SDIV
17239 || type == TYPE_DDIV
17240 || type == TYPE_SSQRT
17241 || type == TYPE_DSQRT
17242 || type == TYPE_MFCR
17243 || type == TYPE_MFCRF
17244 || type == TYPE_MFJMPR)
17246 return true;
17248 return false;
17252 /* Return how many instructions the machine can issue per cycle. */
17254 static int
17255 rs6000_issue_rate (void)
17257 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
17258 if (!reload_completed)
17259 return 1;
17261 switch (rs6000_cpu_attr) {
17262 case CPU_RIOS1: /* ? */
17263 case CPU_RS64A:
17264 case CPU_PPC601: /* ? */
17265 case CPU_PPC7450:
17266 return 3;
17267 case CPU_PPC440:
17268 case CPU_PPC603:
17269 case CPU_PPC750:
17270 case CPU_PPC7400:
17271 case CPU_PPC8540:
17272 case CPU_CELL:
17273 return 2;
17274 case CPU_RIOS2:
17275 case CPU_PPC604:
17276 case CPU_PPC604E:
17277 case CPU_PPC620:
17278 case CPU_PPC630:
17279 return 4;
17280 case CPU_POWER4:
17281 case CPU_POWER5:
17282 case CPU_POWER6:
17283 return 5;
17284 default:
17285 return 1;
17289 /* Return how many instructions to look ahead for better insn
17290 scheduling. */
17292 static int
17293 rs6000_use_sched_lookahead (void)
17295 if (rs6000_cpu_attr == CPU_PPC8540)
17296 return 4;
17297 if (rs6000_cpu_attr == CPU_CELL)
17298 return (reload_completed ? 8 : 0);
17299 return 0;
17302 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
17303 static int
17304 rs6000_use_sched_lookahead_guard (rtx insn)
17306 if (rs6000_cpu_attr != CPU_CELL)
17307 return 1;
17309 if (insn == NULL_RTX || !INSN_P (insn))
17310 abort ();
17312 if (!reload_completed
17313 || is_nonpipeline_insn (insn)
17314 || is_microcoded_insn (insn))
17315 return 0;
17317 return 1;
17320 /* Determine is PAT refers to memory. */
17322 static bool
17323 is_mem_ref (rtx pat)
17325 const char * fmt;
17326 int i, j;
17327 bool ret = false;
17329 if (GET_CODE (pat) == MEM)
17330 return true;
17332 /* Recursively process the pattern. */
17333 fmt = GET_RTX_FORMAT (GET_CODE (pat));
17335 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
17337 if (fmt[i] == 'e')
17338 ret |= is_mem_ref (XEXP (pat, i));
17339 else if (fmt[i] == 'E')
17340 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
17341 ret |= is_mem_ref (XVECEXP (pat, i, j));
17344 return ret;
17347 /* Determine if PAT is a PATTERN of a load insn. */
17349 static bool
17350 is_load_insn1 (rtx pat)
17352 if (!pat || pat == NULL_RTX)
17353 return false;
17355 if (GET_CODE (pat) == SET)
17356 return is_mem_ref (SET_SRC (pat));
17358 if (GET_CODE (pat) == PARALLEL)
17360 int i;
17362 for (i = 0; i < XVECLEN (pat, 0); i++)
17363 if (is_load_insn1 (XVECEXP (pat, 0, i)))
17364 return true;
17367 return false;
17370 /* Determine if INSN loads from memory. */
17372 static bool
17373 is_load_insn (rtx insn)
17375 if (!insn || !INSN_P (insn))
17376 return false;
17378 if (GET_CODE (insn) == CALL_INSN)
17379 return false;
17381 return is_load_insn1 (PATTERN (insn));
17384 /* Determine if PAT is a PATTERN of a store insn. */
17386 static bool
17387 is_store_insn1 (rtx pat)
17389 if (!pat || pat == NULL_RTX)
17390 return false;
17392 if (GET_CODE (pat) == SET)
17393 return is_mem_ref (SET_DEST (pat));
17395 if (GET_CODE (pat) == PARALLEL)
17397 int i;
17399 for (i = 0; i < XVECLEN (pat, 0); i++)
17400 if (is_store_insn1 (XVECEXP (pat, 0, i)))
17401 return true;
17404 return false;
17407 /* Determine if INSN stores to memory. */
17409 static bool
17410 is_store_insn (rtx insn)
17412 if (!insn || !INSN_P (insn))
17413 return false;
17415 return is_store_insn1 (PATTERN (insn));
17418 /* Return the dest of a store insn. */
17420 static rtx
17421 get_store_dest (rtx pat)
17423 gcc_assert (is_store_insn1 (pat));
17425 if (GET_CODE (pat) == SET)
17426 return SET_DEST (pat);
17427 else if (GET_CODE (pat) == PARALLEL)
17429 int i;
17431 for (i = 0; i < XVECLEN (pat, 0); i++)
17433 rtx inner_pat = XVECEXP (pat, 0, i);
17434 if (GET_CODE (inner_pat) == SET
17435 && is_mem_ref (SET_DEST (inner_pat)))
17436 return inner_pat;
17439 /* We shouldn't get here, because we should have either a simple
17440 store insn or a store with update which are covered above. */
17441 gcc_unreachable();
17444 /* Returns whether the dependence between INSN and NEXT is considered
17445 costly by the given target. */
17447 static bool
17448 rs6000_is_costly_dependence (rtx insn, rtx next, rtx link, int cost,
17449 int distance)
17451 /* If the flag is not enabled - no dependence is considered costly;
17452 allow all dependent insns in the same group.
17453 This is the most aggressive option. */
17454 if (rs6000_sched_costly_dep == no_dep_costly)
17455 return false;
17457 /* If the flag is set to 1 - a dependence is always considered costly;
17458 do not allow dependent instructions in the same group.
17459 This is the most conservative option. */
17460 if (rs6000_sched_costly_dep == all_deps_costly)
17461 return true;
17463 if (rs6000_sched_costly_dep == store_to_load_dep_costly
17464 && is_load_insn (next)
17465 && is_store_insn (insn))
17466 /* Prevent load after store in the same group. */
17467 return true;
17469 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
17470 && is_load_insn (next)
17471 && is_store_insn (insn)
17472 && (!link || (int) REG_NOTE_KIND (link) == 0))
17473 /* Prevent load after store in the same group if it is a true
17474 dependence. */
17475 return true;
17477 /* The flag is set to X; dependences with latency >= X are considered costly,
17478 and will not be scheduled in the same group. */
17479 if (rs6000_sched_costly_dep <= max_dep_latency
17480 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
17481 return true;
17483 return false;
17486 /* Return the next insn after INSN that is found before TAIL is reached,
17487 skipping any "non-active" insns - insns that will not actually occupy
17488 an issue slot. Return NULL_RTX if such an insn is not found. */
17490 static rtx
17491 get_next_active_insn (rtx insn, rtx tail)
17493 if (insn == NULL_RTX || insn == tail)
17494 return NULL_RTX;
17496 while (1)
17498 insn = NEXT_INSN (insn);
17499 if (insn == NULL_RTX || insn == tail)
17500 return NULL_RTX;
17502 if (CALL_P (insn)
17503 || JUMP_P (insn)
17504 || (NONJUMP_INSN_P (insn)
17505 && GET_CODE (PATTERN (insn)) != USE
17506 && GET_CODE (PATTERN (insn)) != CLOBBER
17507 && INSN_CODE (insn) != CODE_FOR_stack_tie))
17508 break;
17510 return insn;
17513 /* We are about to begin issuing insns for this clock cycle. */
17515 static int
17516 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
17517 rtx *ready ATTRIBUTE_UNUSED,
17518 int *pn_ready ATTRIBUTE_UNUSED,
17519 int clock_var ATTRIBUTE_UNUSED)
17521 int n_ready = *pn_ready;
17523 if (sched_verbose)
17524 fprintf (dump, "// rs6000_sched_reorder :\n");
17526 /* Reorder the ready list, if the second to last ready insn
17527 is a nonepipeline insn. */
17528 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
17530 if (is_nonpipeline_insn (ready[n_ready - 1])
17531 && (recog_memoized (ready[n_ready - 2]) > 0))
17532 /* Simply swap first two insns. */
17534 rtx tmp = ready[n_ready - 1];
17535 ready[n_ready - 1] = ready[n_ready - 2];
17536 ready[n_ready - 2] = tmp;
17540 if (rs6000_cpu == PROCESSOR_POWER6)
17541 load_store_pendulum = 0;
17543 return rs6000_issue_rate ();
17546 /* Like rs6000_sched_reorder, but called after issuing each insn. */
17548 static int
17549 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
17550 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
17552 if (sched_verbose)
17553 fprintf (dump, "// rs6000_sched_reorder2 :\n");
17555 /* For Power6, we need to handle some special cases to try and keep the
17556 store queue from overflowing and triggering expensive flushes.
17558 This code monitors how load and store instructions are being issued
17559 and skews the ready list one way or the other to increase the likelihood
17560 that a desired instruction is issued at the proper time.
17562 A couple of things are done. First, we maintain a "load_store_pendulum"
17563 to track the current state of load/store issue.
17565 - If the pendulum is at zero, then no loads or stores have been
17566 issued in the current cycle so we do nothing.
17568 - If the pendulum is 1, then a single load has been issued in this
17569 cycle and we attempt to locate another load in the ready list to
17570 issue with it.
17572 - If the pendulum is -2, then two stores have already been
17573 issued in this cycle, so we increase the priority of the first load
17574 in the ready list to increase it's likelihood of being chosen first
17575 in the next cycle.
17577 - If the pendulum is -1, then a single store has been issued in this
17578 cycle and we attempt to locate another store in the ready list to
17579 issue with it, preferring a store to an adjacent memory location to
17580 facilitate store pairing in the store queue.
17582 - If the pendulum is 2, then two loads have already been
17583 issued in this cycle, so we increase the priority of the first store
17584 in the ready list to increase it's likelihood of being chosen first
17585 in the next cycle.
17587 - If the pendulum < -2 or > 2, then do nothing.
17589 Note: This code covers the most common scenarios. There exist non
17590 load/store instructions which make use of the LSU and which
17591 would need to be accounted for to strictly model the behavior
17592 of the machine. Those instructions are currently unaccounted
17593 for to help minimize compile time overhead of this code.
17595 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
17597 int pos;
17598 int i;
17599 rtx tmp;
17601 if (is_store_insn (last_scheduled_insn))
17602 /* Issuing a store, swing the load_store_pendulum to the left */
17603 load_store_pendulum--;
17604 else if (is_load_insn (last_scheduled_insn))
17605 /* Issuing a load, swing the load_store_pendulum to the right */
17606 load_store_pendulum++;
17607 else
17608 return cached_can_issue_more;
17610 /* If the pendulum is balanced, or there is only one instruction on
17611 the ready list, then all is well, so return. */
17612 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
17613 return cached_can_issue_more;
17615 if (load_store_pendulum == 1)
17617 /* A load has been issued in this cycle. Scan the ready list
17618 for another load to issue with it */
17619 pos = *pn_ready-1;
17621 while (pos >= 0)
17623 if (is_load_insn (ready[pos]))
17625 /* Found a load. Move it to the head of the ready list,
17626 and adjust it's priority so that it is more likely to
17627 stay there */
17628 tmp = ready[pos];
17629 for (i=pos; i<*pn_ready-1; i++)
17630 ready[i] = ready[i + 1];
17631 ready[*pn_ready-1] = tmp;
17632 if INSN_PRIORITY_KNOWN (tmp)
17633 INSN_PRIORITY (tmp)++;
17634 break;
17636 pos--;
17639 else if (load_store_pendulum == -2)
17641 /* Two stores have been issued in this cycle. Increase the
17642 priority of the first load in the ready list to favor it for
17643 issuing in the next cycle. */
17644 pos = *pn_ready-1;
17646 while (pos >= 0)
17648 if (is_load_insn (ready[pos])
17649 && INSN_PRIORITY_KNOWN (ready[pos]))
17651 INSN_PRIORITY (ready[pos])++;
17653 /* Adjust the pendulum to account for the fact that a load
17654 was found and increased in priority. This is to prevent
17655 increasing the priority of multiple loads */
17656 load_store_pendulum--;
17658 break;
17660 pos--;
17663 else if (load_store_pendulum == -1)
17665 /* A store has been issued in this cycle. Scan the ready list for
17666 another store to issue with it, preferring a store to an adjacent
17667 memory location */
17668 int first_store_pos = -1;
17670 pos = *pn_ready-1;
17672 while (pos >= 0)
17674 if (is_store_insn (ready[pos]))
17676 /* Maintain the index of the first store found on the
17677 list */
17678 if (first_store_pos == -1)
17679 first_store_pos = pos;
17681 if (is_store_insn (last_scheduled_insn)
17682 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
17684 /* Found an adjacent store. Move it to the head of the
17685 ready list, and adjust it's priority so that it is
17686 more likely to stay there */
17687 tmp = ready[pos];
17688 for (i=pos; i<*pn_ready-1; i++)
17689 ready[i] = ready[i + 1];
17690 ready[*pn_ready-1] = tmp;
17691 if INSN_PRIORITY_KNOWN (tmp)
17692 INSN_PRIORITY (tmp)++;
17693 first_store_pos = -1;
17695 break;
17698 pos--;
17701 if (first_store_pos >= 0)
17703 /* An adjacent store wasn't found, but a non-adjacent store was,
17704 so move the non-adjacent store to the front of the ready
17705 list, and adjust its priority so that it is more likely to
17706 stay there. */
17707 tmp = ready[first_store_pos];
17708 for (i=first_store_pos; i<*pn_ready-1; i++)
17709 ready[i] = ready[i + 1];
17710 ready[*pn_ready-1] = tmp;
17711 if INSN_PRIORITY_KNOWN (tmp)
17712 INSN_PRIORITY (tmp)++;
17715 else if (load_store_pendulum == 2)
17717 /* Two loads have been issued in this cycle. Increase the priority
17718 of the first store in the ready list to favor it for issuing in
17719 the next cycle. */
17720 pos = *pn_ready-1;
17722 while (pos >= 0)
17724 if (is_store_insn (ready[pos])
17725 && INSN_PRIORITY_KNOWN (ready[pos]))
17727 INSN_PRIORITY (ready[pos])++;
17729 /* Adjust the pendulum to account for the fact that a store
17730 was found and increased in priority. This is to prevent
17731 increasing the priority of multiple stores */
17732 load_store_pendulum++;
17734 break;
17736 pos--;
17741 return cached_can_issue_more;
17744 /* Return whether the presence of INSN causes a dispatch group termination
17745 of group WHICH_GROUP.
17747 If WHICH_GROUP == current_group, this function will return true if INSN
17748 causes the termination of the current group (i.e, the dispatch group to
17749 which INSN belongs). This means that INSN will be the last insn in the
17750 group it belongs to.
17752 If WHICH_GROUP == previous_group, this function will return true if INSN
17753 causes the termination of the previous group (i.e, the dispatch group that
17754 precedes the group to which INSN belongs). This means that INSN will be
17755 the first insn in the group it belongs to). */
17757 static bool
17758 insn_terminates_group_p (rtx insn, enum group_termination which_group)
17760 bool first, last;
17762 if (! insn)
17763 return false;
17765 first = insn_must_be_first_in_group (insn);
17766 last = insn_must_be_last_in_group (insn);
17768 if (first && last)
17769 return true;
17771 if (which_group == current_group)
17772 return last;
17773 else if (which_group == previous_group)
17774 return first;
17776 return false;
17780 static bool
17781 insn_must_be_first_in_group (rtx insn)
17783 enum attr_type type;
17785 if (!insn
17786 || insn == NULL_RTX
17787 || GET_CODE (insn) == NOTE
17788 || GET_CODE (PATTERN (insn)) == USE
17789 || GET_CODE (PATTERN (insn)) == CLOBBER)
17790 return false;
17792 switch (rs6000_cpu)
17794 case PROCESSOR_POWER5:
17795 if (is_cracked_insn (insn))
17796 return true;
17797 case PROCESSOR_POWER4:
17798 if (is_microcoded_insn (insn))
17799 return true;
17801 if (!rs6000_sched_groups)
17802 return false;
17804 type = get_attr_type (insn);
17806 switch (type)
17808 case TYPE_MFCR:
17809 case TYPE_MFCRF:
17810 case TYPE_MTCR:
17811 case TYPE_DELAYED_CR:
17812 case TYPE_CR_LOGICAL:
17813 case TYPE_MTJMPR:
17814 case TYPE_MFJMPR:
17815 case TYPE_IDIV:
17816 case TYPE_LDIV:
17817 case TYPE_LOAD_L:
17818 case TYPE_STORE_C:
17819 case TYPE_ISYNC:
17820 case TYPE_SYNC:
17821 return true;
17822 default:
17823 break;
17825 break;
17826 case PROCESSOR_POWER6:
17827 type = get_attr_type (insn);
17829 switch (type)
17831 case TYPE_INSERT_DWORD:
17832 case TYPE_EXTS:
17833 case TYPE_CNTLZ:
17834 case TYPE_SHIFT:
17835 case TYPE_VAR_SHIFT_ROTATE:
17836 case TYPE_TRAP:
17837 case TYPE_IMUL:
17838 case TYPE_IMUL2:
17839 case TYPE_IMUL3:
17840 case TYPE_LMUL:
17841 case TYPE_IDIV:
17842 case TYPE_INSERT_WORD:
17843 case TYPE_DELAYED_COMPARE:
17844 case TYPE_IMUL_COMPARE:
17845 case TYPE_LMUL_COMPARE:
17846 case TYPE_FPCOMPARE:
17847 case TYPE_MFCR:
17848 case TYPE_MTCR:
17849 case TYPE_MFJMPR:
17850 case TYPE_MTJMPR:
17851 case TYPE_ISYNC:
17852 case TYPE_SYNC:
17853 case TYPE_LOAD_L:
17854 case TYPE_STORE_C:
17855 case TYPE_LOAD_U:
17856 case TYPE_LOAD_UX:
17857 case TYPE_LOAD_EXT_UX:
17858 case TYPE_STORE_U:
17859 case TYPE_STORE_UX:
17860 case TYPE_FPLOAD_U:
17861 case TYPE_FPLOAD_UX:
17862 case TYPE_FPSTORE_U:
17863 case TYPE_FPSTORE_UX:
17864 return true;
17865 default:
17866 break;
17868 break;
17869 default:
17870 break;
17873 return false;
17876 static bool
17877 insn_must_be_last_in_group (rtx insn)
17879 enum attr_type type;
17881 if (!insn
17882 || insn == NULL_RTX
17883 || GET_CODE (insn) == NOTE
17884 || GET_CODE (PATTERN (insn)) == USE
17885 || GET_CODE (PATTERN (insn)) == CLOBBER)
17886 return false;
17888 switch (rs6000_cpu) {
17889 case PROCESSOR_POWER4:
17890 case PROCESSOR_POWER5:
17891 if (is_microcoded_insn (insn))
17892 return true;
17894 if (is_branch_slot_insn (insn))
17895 return true;
17897 break;
17898 case PROCESSOR_POWER6:
17899 type = get_attr_type (insn);
17901 switch (type)
17903 case TYPE_EXTS:
17904 case TYPE_CNTLZ:
17905 case TYPE_SHIFT:
17906 case TYPE_VAR_SHIFT_ROTATE:
17907 case TYPE_TRAP:
17908 case TYPE_IMUL:
17909 case TYPE_IMUL2:
17910 case TYPE_IMUL3:
17911 case TYPE_LMUL:
17912 case TYPE_IDIV:
17913 case TYPE_DELAYED_COMPARE:
17914 case TYPE_IMUL_COMPARE:
17915 case TYPE_LMUL_COMPARE:
17916 case TYPE_FPCOMPARE:
17917 case TYPE_MFCR:
17918 case TYPE_MTCR:
17919 case TYPE_MFJMPR:
17920 case TYPE_MTJMPR:
17921 case TYPE_ISYNC:
17922 case TYPE_SYNC:
17923 case TYPE_LOAD_L:
17924 case TYPE_STORE_C:
17925 return true;
17926 default:
17927 break;
17929 break;
17930 default:
17931 break;
17934 return false;
17937 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
17938 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
17940 static bool
17941 is_costly_group (rtx *group_insns, rtx next_insn)
17943 int i;
17944 rtx link;
17945 int cost;
17946 int issue_rate = rs6000_issue_rate ();
17948 for (i = 0; i < issue_rate; i++)
17950 rtx insn = group_insns[i];
17951 if (!insn)
17952 continue;
17953 for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
17955 rtx next = XEXP (link, 0);
17956 if (next == next_insn)
17958 cost = insn_cost (insn, link, next_insn);
17959 if (rs6000_is_costly_dependence (insn, next_insn, link, cost, 0))
17960 return true;
17965 return false;
17968 /* Utility of the function redefine_groups.
17969 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
17970 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
17971 to keep it "far" (in a separate group) from GROUP_INSNS, following
17972 one of the following schemes, depending on the value of the flag
17973 -minsert_sched_nops = X:
17974 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
17975 in order to force NEXT_INSN into a separate group.
17976 (2) X < sched_finish_regroup_exact: insert exactly X nops.
17977 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
17978 insertion (has a group just ended, how many vacant issue slots remain in the
17979 last group, and how many dispatch groups were encountered so far). */
17981 static int
17982 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
17983 rtx next_insn, bool *group_end, int can_issue_more,
17984 int *group_count)
17986 rtx nop;
17987 bool force;
17988 int issue_rate = rs6000_issue_rate ();
17989 bool end = *group_end;
17990 int i;
17992 if (next_insn == NULL_RTX)
17993 return can_issue_more;
17995 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
17996 return can_issue_more;
17998 force = is_costly_group (group_insns, next_insn);
17999 if (!force)
18000 return can_issue_more;
18002 if (sched_verbose > 6)
18003 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
18004 *group_count ,can_issue_more);
18006 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
18008 if (*group_end)
18009 can_issue_more = 0;
18011 /* Since only a branch can be issued in the last issue_slot, it is
18012 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
18013 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
18014 in this case the last nop will start a new group and the branch
18015 will be forced to the new group. */
18016 if (can_issue_more && !is_branch_slot_insn (next_insn))
18017 can_issue_more--;
18019 while (can_issue_more > 0)
18021 nop = gen_nop ();
18022 emit_insn_before (nop, next_insn);
18023 can_issue_more--;
18026 *group_end = true;
18027 return 0;
18030 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
18032 int n_nops = rs6000_sched_insert_nops;
18034 /* Nops can't be issued from the branch slot, so the effective
18035 issue_rate for nops is 'issue_rate - 1'. */
18036 if (can_issue_more == 0)
18037 can_issue_more = issue_rate;
18038 can_issue_more--;
18039 if (can_issue_more == 0)
18041 can_issue_more = issue_rate - 1;
18042 (*group_count)++;
18043 end = true;
18044 for (i = 0; i < issue_rate; i++)
18046 group_insns[i] = 0;
18050 while (n_nops > 0)
18052 nop = gen_nop ();
18053 emit_insn_before (nop, next_insn);
18054 if (can_issue_more == issue_rate - 1) /* new group begins */
18055 end = false;
18056 can_issue_more--;
18057 if (can_issue_more == 0)
18059 can_issue_more = issue_rate - 1;
18060 (*group_count)++;
18061 end = true;
18062 for (i = 0; i < issue_rate; i++)
18064 group_insns[i] = 0;
18067 n_nops--;
18070 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
18071 can_issue_more++;
18073 /* Is next_insn going to start a new group? */
18074 *group_end
18075 = (end
18076 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
18077 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
18078 || (can_issue_more < issue_rate &&
18079 insn_terminates_group_p (next_insn, previous_group)));
18080 if (*group_end && end)
18081 (*group_count)--;
18083 if (sched_verbose > 6)
18084 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
18085 *group_count, can_issue_more);
18086 return can_issue_more;
18089 return can_issue_more;
18092 /* This function tries to synch the dispatch groups that the compiler "sees"
18093 with the dispatch groups that the processor dispatcher is expected to
18094 form in practice. It tries to achieve this synchronization by forcing the
18095 estimated processor grouping on the compiler (as opposed to the function
18096 'pad_goups' which tries to force the scheduler's grouping on the processor).
18098 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
18099 examines the (estimated) dispatch groups that will be formed by the processor
18100 dispatcher. It marks these group boundaries to reflect the estimated
18101 processor grouping, overriding the grouping that the scheduler had marked.
18102 Depending on the value of the flag '-minsert-sched-nops' this function can
18103 force certain insns into separate groups or force a certain distance between
18104 them by inserting nops, for example, if there exists a "costly dependence"
18105 between the insns.
18107 The function estimates the group boundaries that the processor will form as
18108 follows: It keeps track of how many vacant issue slots are available after
18109 each insn. A subsequent insn will start a new group if one of the following
18110 4 cases applies:
18111 - no more vacant issue slots remain in the current dispatch group.
18112 - only the last issue slot, which is the branch slot, is vacant, but the next
18113 insn is not a branch.
18114 - only the last 2 or less issue slots, including the branch slot, are vacant,
18115 which means that a cracked insn (which occupies two issue slots) can't be
18116 issued in this group.
18117 - less than 'issue_rate' slots are vacant, and the next insn always needs to
18118 start a new group. */
18120 static int
18121 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
18123 rtx insn, next_insn;
18124 int issue_rate;
18125 int can_issue_more;
18126 int slot, i;
18127 bool group_end;
18128 int group_count = 0;
18129 rtx *group_insns;
18131 /* Initialize. */
18132 issue_rate = rs6000_issue_rate ();
18133 group_insns = alloca (issue_rate * sizeof (rtx));
18134 for (i = 0; i < issue_rate; i++)
18136 group_insns[i] = 0;
18138 can_issue_more = issue_rate;
18139 slot = 0;
18140 insn = get_next_active_insn (prev_head_insn, tail);
18141 group_end = false;
18143 while (insn != NULL_RTX)
18145 slot = (issue_rate - can_issue_more);
18146 group_insns[slot] = insn;
18147 can_issue_more =
18148 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
18149 if (insn_terminates_group_p (insn, current_group))
18150 can_issue_more = 0;
18152 next_insn = get_next_active_insn (insn, tail);
18153 if (next_insn == NULL_RTX)
18154 return group_count + 1;
18156 /* Is next_insn going to start a new group? */
18157 group_end
18158 = (can_issue_more == 0
18159 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
18160 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
18161 || (can_issue_more < issue_rate &&
18162 insn_terminates_group_p (next_insn, previous_group)));
18164 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
18165 next_insn, &group_end, can_issue_more,
18166 &group_count);
18168 if (group_end)
18170 group_count++;
18171 can_issue_more = 0;
18172 for (i = 0; i < issue_rate; i++)
18174 group_insns[i] = 0;
18178 if (GET_MODE (next_insn) == TImode && can_issue_more)
18179 PUT_MODE (next_insn, VOIDmode);
18180 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
18181 PUT_MODE (next_insn, TImode);
18183 insn = next_insn;
18184 if (can_issue_more == 0)
18185 can_issue_more = issue_rate;
18186 } /* while */
18188 return group_count;
18191 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
18192 dispatch group boundaries that the scheduler had marked. Pad with nops
18193 any dispatch groups which have vacant issue slots, in order to force the
18194 scheduler's grouping on the processor dispatcher. The function
18195 returns the number of dispatch groups found. */
18197 static int
18198 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
18200 rtx insn, next_insn;
18201 rtx nop;
18202 int issue_rate;
18203 int can_issue_more;
18204 int group_end;
18205 int group_count = 0;
18207 /* Initialize issue_rate. */
18208 issue_rate = rs6000_issue_rate ();
18209 can_issue_more = issue_rate;
18211 insn = get_next_active_insn (prev_head_insn, tail);
18212 next_insn = get_next_active_insn (insn, tail);
18214 while (insn != NULL_RTX)
18216 can_issue_more =
18217 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
18219 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
18221 if (next_insn == NULL_RTX)
18222 break;
18224 if (group_end)
18226 /* If the scheduler had marked group termination at this location
18227 (between insn and next_indn), and neither insn nor next_insn will
18228 force group termination, pad the group with nops to force group
18229 termination. */
18230 if (can_issue_more
18231 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
18232 && !insn_terminates_group_p (insn, current_group)
18233 && !insn_terminates_group_p (next_insn, previous_group))
18235 if (!is_branch_slot_insn (next_insn))
18236 can_issue_more--;
18238 while (can_issue_more)
18240 nop = gen_nop ();
18241 emit_insn_before (nop, next_insn);
18242 can_issue_more--;
18246 can_issue_more = issue_rate;
18247 group_count++;
18250 insn = next_insn;
18251 next_insn = get_next_active_insn (insn, tail);
18254 return group_count;
18257 /* We're beginning a new block. Initialize data structures as necessary. */
18259 static void
18260 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
18261 int sched_verbose ATTRIBUTE_UNUSED,
18262 int max_ready ATTRIBUTE_UNUSED)
18264 last_scheduled_insn = NULL_RTX;
18265 load_store_pendulum = 0;
18268 /* The following function is called at the end of scheduling BB.
18269 After reload, it inserts nops at insn group bundling. */
18271 static void
18272 rs6000_sched_finish (FILE *dump, int sched_verbose)
18274 int n_groups;
18276 if (sched_verbose)
18277 fprintf (dump, "=== Finishing schedule.\n");
18279 if (reload_completed && rs6000_sched_groups)
18281 if (rs6000_sched_insert_nops == sched_finish_none)
18282 return;
18284 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
18285 n_groups = pad_groups (dump, sched_verbose,
18286 current_sched_info->prev_head,
18287 current_sched_info->next_tail);
18288 else
18289 n_groups = redefine_groups (dump, sched_verbose,
18290 current_sched_info->prev_head,
18291 current_sched_info->next_tail);
18293 if (sched_verbose >= 6)
18295 fprintf (dump, "ngroups = %d\n", n_groups);
18296 print_rtl (dump, current_sched_info->prev_head);
18297 fprintf (dump, "Done finish_sched\n");
18302 /* Length in units of the trampoline for entering a nested function. */
18305 rs6000_trampoline_size (void)
18307 int ret = 0;
18309 switch (DEFAULT_ABI)
18311 default:
18312 gcc_unreachable ();
18314 case ABI_AIX:
18315 ret = (TARGET_32BIT) ? 12 : 24;
18316 break;
18318 case ABI_DARWIN:
18319 case ABI_V4:
18320 ret = (TARGET_32BIT) ? 40 : 48;
18321 break;
18324 return ret;
18327 /* Emit RTL insns to initialize the variable parts of a trampoline.
18328 FNADDR is an RTX for the address of the function's pure code.
18329 CXT is an RTX for the static chain value for the function. */
18331 void
18332 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
18334 int regsize = (TARGET_32BIT) ? 4 : 8;
18335 rtx ctx_reg = force_reg (Pmode, cxt);
18337 switch (DEFAULT_ABI)
18339 default:
18340 gcc_unreachable ();
18342 /* Macros to shorten the code expansions below. */
18343 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
18344 #define MEM_PLUS(addr,offset) \
18345 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
18347 /* Under AIX, just build the 3 word function descriptor */
18348 case ABI_AIX:
18350 rtx fn_reg = gen_reg_rtx (Pmode);
18351 rtx toc_reg = gen_reg_rtx (Pmode);
18352 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
18353 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
18354 emit_move_insn (MEM_DEREF (addr), fn_reg);
18355 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
18356 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
18358 break;
18360 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
18361 case ABI_DARWIN:
18362 case ABI_V4:
18363 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
18364 FALSE, VOIDmode, 4,
18365 addr, Pmode,
18366 GEN_INT (rs6000_trampoline_size ()), SImode,
18367 fnaddr, Pmode,
18368 ctx_reg, Pmode);
18369 break;
18372 return;
18376 /* Table of valid machine attributes. */
18378 const struct attribute_spec rs6000_attribute_table[] =
18380 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
18381 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
18382 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
18383 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
18384 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
18385 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
18386 #ifdef SUBTARGET_ATTRIBUTE_TABLE
18387 SUBTARGET_ATTRIBUTE_TABLE,
18388 #endif
18389 { NULL, 0, 0, false, false, false, NULL }
18392 /* Handle the "altivec" attribute. The attribute may have
18393 arguments as follows:
18395 __attribute__((altivec(vector__)))
18396 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
18397 __attribute__((altivec(bool__))) (always followed by 'unsigned')
18399 and may appear more than once (e.g., 'vector bool char') in a
18400 given declaration. */
18402 static tree
18403 rs6000_handle_altivec_attribute (tree *node,
18404 tree name ATTRIBUTE_UNUSED,
18405 tree args,
18406 int flags ATTRIBUTE_UNUSED,
18407 bool *no_add_attrs)
18409 tree type = *node, result = NULL_TREE;
18410 enum machine_mode mode;
18411 int unsigned_p;
18412 char altivec_type
18413 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
18414 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
18415 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
18416 : '?');
18418 while (POINTER_TYPE_P (type)
18419 || TREE_CODE (type) == FUNCTION_TYPE
18420 || TREE_CODE (type) == METHOD_TYPE
18421 || TREE_CODE (type) == ARRAY_TYPE)
18422 type = TREE_TYPE (type);
18424 mode = TYPE_MODE (type);
18426 /* Check for invalid AltiVec type qualifiers. */
18427 if (type == long_unsigned_type_node || type == long_integer_type_node)
18429 if (TARGET_64BIT)
18430 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
18431 else if (rs6000_warn_altivec_long)
18432 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
18434 else if (type == long_long_unsigned_type_node
18435 || type == long_long_integer_type_node)
18436 error ("use of %<long long%> in AltiVec types is invalid");
18437 else if (type == double_type_node)
18438 error ("use of %<double%> in AltiVec types is invalid");
18439 else if (type == long_double_type_node)
18440 error ("use of %<long double%> in AltiVec types is invalid");
18441 else if (type == boolean_type_node)
18442 error ("use of boolean types in AltiVec types is invalid");
18443 else if (TREE_CODE (type) == COMPLEX_TYPE)
18444 error ("use of %<complex%> in AltiVec types is invalid");
18445 else if (DECIMAL_FLOAT_MODE_P (mode))
18446 error ("use of decimal floating point types in AltiVec types is invalid");
18448 switch (altivec_type)
18450 case 'v':
18451 unsigned_p = TYPE_UNSIGNED (type);
18452 switch (mode)
18454 case SImode:
18455 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
18456 break;
18457 case HImode:
18458 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
18459 break;
18460 case QImode:
18461 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
18462 break;
18463 case SFmode: result = V4SF_type_node; break;
18464 /* If the user says 'vector int bool', we may be handed the 'bool'
18465 attribute _before_ the 'vector' attribute, and so select the
18466 proper type in the 'b' case below. */
18467 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
18468 result = type;
18469 default: break;
18471 break;
18472 case 'b':
18473 switch (mode)
18475 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
18476 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
18477 case QImode: case V16QImode: result = bool_V16QI_type_node;
18478 default: break;
18480 break;
18481 case 'p':
18482 switch (mode)
18484 case V8HImode: result = pixel_V8HI_type_node;
18485 default: break;
18487 default: break;
18490 if (result && result != type && TYPE_READONLY (type))
18491 result = build_qualified_type (result, TYPE_QUAL_CONST);
18493 *no_add_attrs = true; /* No need to hang on to the attribute. */
18495 if (result)
18496 *node = reconstruct_complex_type (*node, result);
18498 return NULL_TREE;
18501 /* AltiVec defines four built-in scalar types that serve as vector
18502 elements; we must teach the compiler how to mangle them. */
18504 static const char *
18505 rs6000_mangle_fundamental_type (tree type)
18507 if (type == bool_char_type_node) return "U6__boolc";
18508 if (type == bool_short_type_node) return "U6__bools";
18509 if (type == pixel_type_node) return "u7__pixel";
18510 if (type == bool_int_type_node) return "U6__booli";
18512 /* Mangle IBM extended float long double as `g' (__float128) on
18513 powerpc*-linux where long-double-64 previously was the default. */
18514 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
18515 && TARGET_ELF
18516 && TARGET_LONG_DOUBLE_128
18517 && !TARGET_IEEEQUAD)
18518 return "g";
18520 /* For all other types, use normal C++ mangling. */
18521 return NULL;
18524 /* Handle a "longcall" or "shortcall" attribute; arguments as in
18525 struct attribute_spec.handler. */
18527 static tree
18528 rs6000_handle_longcall_attribute (tree *node, tree name,
18529 tree args ATTRIBUTE_UNUSED,
18530 int flags ATTRIBUTE_UNUSED,
18531 bool *no_add_attrs)
18533 if (TREE_CODE (*node) != FUNCTION_TYPE
18534 && TREE_CODE (*node) != FIELD_DECL
18535 && TREE_CODE (*node) != TYPE_DECL)
18537 warning (OPT_Wattributes, "%qs attribute only applies to functions",
18538 IDENTIFIER_POINTER (name));
18539 *no_add_attrs = true;
18542 return NULL_TREE;
18545 /* Set longcall attributes on all functions declared when
18546 rs6000_default_long_calls is true. */
18547 static void
18548 rs6000_set_default_type_attributes (tree type)
18550 if (rs6000_default_long_calls
18551 && (TREE_CODE (type) == FUNCTION_TYPE
18552 || TREE_CODE (type) == METHOD_TYPE))
18553 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
18554 NULL_TREE,
18555 TYPE_ATTRIBUTES (type));
18557 #if TARGET_MACHO
18558 darwin_set_default_type_attributes (type);
18559 #endif
18562 /* Return a reference suitable for calling a function with the
18563 longcall attribute. */
18566 rs6000_longcall_ref (rtx call_ref)
18568 const char *call_name;
18569 tree node;
18571 if (GET_CODE (call_ref) != SYMBOL_REF)
18572 return call_ref;
18574 /* System V adds '.' to the internal name, so skip them. */
18575 call_name = XSTR (call_ref, 0);
18576 if (*call_name == '.')
18578 while (*call_name == '.')
18579 call_name++;
18581 node = get_identifier (call_name);
18582 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
18585 return force_reg (Pmode, call_ref);
18588 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
18589 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
18590 #endif
18592 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
18593 struct attribute_spec.handler. */
18594 static tree
18595 rs6000_handle_struct_attribute (tree *node, tree name,
18596 tree args ATTRIBUTE_UNUSED,
18597 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
18599 tree *type = NULL;
18600 if (DECL_P (*node))
18602 if (TREE_CODE (*node) == TYPE_DECL)
18603 type = &TREE_TYPE (*node);
18605 else
18606 type = node;
18608 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
18609 || TREE_CODE (*type) == UNION_TYPE)))
18611 warning (OPT_Wattributes, "%qs attribute ignored", IDENTIFIER_POINTER (name));
18612 *no_add_attrs = true;
18615 else if ((is_attribute_p ("ms_struct", name)
18616 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
18617 || ((is_attribute_p ("gcc_struct", name)
18618 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
18620 warning (OPT_Wattributes, "%qs incompatible attribute ignored",
18621 IDENTIFIER_POINTER (name));
18622 *no_add_attrs = true;
18625 return NULL_TREE;
18628 static bool
18629 rs6000_ms_bitfield_layout_p (tree record_type)
18631 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
18632 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
18633 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
18636 #ifdef USING_ELFOS_H
18638 /* A get_unnamed_section callback, used for switching to toc_section. */
18640 static void
18641 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
18643 if (DEFAULT_ABI == ABI_AIX
18644 && TARGET_MINIMAL_TOC
18645 && !TARGET_RELOCATABLE)
18647 if (!toc_initialized)
18649 toc_initialized = 1;
18650 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
18651 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
18652 fprintf (asm_out_file, "\t.tc ");
18653 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
18654 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18655 fprintf (asm_out_file, "\n");
18657 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18658 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18659 fprintf (asm_out_file, " = .+32768\n");
18661 else
18662 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18664 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
18665 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
18666 else
18668 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18669 if (!toc_initialized)
18671 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18672 fprintf (asm_out_file, " = .+32768\n");
18673 toc_initialized = 1;
18678 /* Implement TARGET_ASM_INIT_SECTIONS. */
18680 static void
18681 rs6000_elf_asm_init_sections (void)
18683 toc_section
18684 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
18686 sdata2_section
18687 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
18688 SDATA2_SECTION_ASM_OP);
18691 /* Implement TARGET_SELECT_RTX_SECTION. */
18693 static section *
18694 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
18695 unsigned HOST_WIDE_INT align)
18697 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
18698 return toc_section;
18699 else
18700 return default_elf_select_rtx_section (mode, x, align);
18703 /* Implement TARGET_ASM_SELECT_SECTION for ELF targets. */
18705 static section *
18706 rs6000_elf_select_section (tree decl, int reloc,
18707 unsigned HOST_WIDE_INT align)
18709 /* Pretend that we're always building for a shared library when
18710 ABI_AIX, because otherwise we end up with dynamic relocations
18711 in read-only sections. This happens for function pointers,
18712 references to vtables in typeinfo, and probably other cases. */
18713 return default_elf_select_section_1 (decl, reloc, align,
18714 flag_pic || DEFAULT_ABI == ABI_AIX);
18717 /* A C statement to build up a unique section name, expressed as a
18718 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
18719 RELOC indicates whether the initial value of EXP requires
18720 link-time relocations. If you do not define this macro, GCC will use
18721 the symbol name prefixed by `.' as the section name. Note - this
18722 macro can now be called for uninitialized data items as well as
18723 initialized data and functions. */
18725 static void
18726 rs6000_elf_unique_section (tree decl, int reloc)
18728 /* As above, pretend that we're always building for a shared library
18729 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
18730 default_unique_section_1 (decl, reloc,
18731 flag_pic || DEFAULT_ABI == ABI_AIX);
18734 /* For a SYMBOL_REF, set generic flags and then perform some
18735 target-specific processing.
18737 When the AIX ABI is requested on a non-AIX system, replace the
18738 function name with the real name (with a leading .) rather than the
18739 function descriptor name. This saves a lot of overriding code to
18740 read the prefixes. */
18742 static void
18743 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
18745 default_encode_section_info (decl, rtl, first);
18747 if (first
18748 && TREE_CODE (decl) == FUNCTION_DECL
18749 && !TARGET_AIX
18750 && DEFAULT_ABI == ABI_AIX)
18752 rtx sym_ref = XEXP (rtl, 0);
18753 size_t len = strlen (XSTR (sym_ref, 0));
18754 char *str = alloca (len + 2);
18755 str[0] = '.';
18756 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
18757 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
18761 bool
18762 rs6000_elf_in_small_data_p (tree decl)
18764 if (rs6000_sdata == SDATA_NONE)
18765 return false;
18767 /* We want to merge strings, so we never consider them small data. */
18768 if (TREE_CODE (decl) == STRING_CST)
18769 return false;
18771 /* Functions are never in the small data area. */
18772 if (TREE_CODE (decl) == FUNCTION_DECL)
18773 return false;
18775 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
18777 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
18778 if (strcmp (section, ".sdata") == 0
18779 || strcmp (section, ".sdata2") == 0
18780 || strcmp (section, ".sbss") == 0
18781 || strcmp (section, ".sbss2") == 0
18782 || strcmp (section, ".PPC.EMB.sdata0") == 0
18783 || strcmp (section, ".PPC.EMB.sbss0") == 0)
18784 return true;
18786 else
18788 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
18790 if (size > 0
18791 && (unsigned HOST_WIDE_INT) size <= g_switch_value
18792 /* If it's not public, and we're not going to reference it there,
18793 there's no need to put it in the small data section. */
18794 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
18795 return true;
18798 return false;
18801 #endif /* USING_ELFOS_H */
18803 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
18805 static bool
18806 rs6000_use_blocks_for_constant_p (enum machine_mode mode, rtx x)
18808 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
18811 /* Return a REG that occurs in ADDR with coefficient 1.
18812 ADDR can be effectively incremented by incrementing REG.
18814 r0 is special and we must not select it as an address
18815 register by this routine since our caller will try to
18816 increment the returned register via an "la" instruction. */
18819 find_addr_reg (rtx addr)
18821 while (GET_CODE (addr) == PLUS)
18823 if (GET_CODE (XEXP (addr, 0)) == REG
18824 && REGNO (XEXP (addr, 0)) != 0)
18825 addr = XEXP (addr, 0);
18826 else if (GET_CODE (XEXP (addr, 1)) == REG
18827 && REGNO (XEXP (addr, 1)) != 0)
18828 addr = XEXP (addr, 1);
18829 else if (CONSTANT_P (XEXP (addr, 0)))
18830 addr = XEXP (addr, 1);
18831 else if (CONSTANT_P (XEXP (addr, 1)))
18832 addr = XEXP (addr, 0);
18833 else
18834 gcc_unreachable ();
18836 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
18837 return addr;
18840 void
18841 rs6000_fatal_bad_address (rtx op)
18843 fatal_insn ("bad address", op);
18846 #if TARGET_MACHO
18848 static tree branch_island_list = 0;
18850 /* Remember to generate a branch island for far calls to the given
18851 function. */
18853 static void
18854 add_compiler_branch_island (tree label_name, tree function_name,
18855 int line_number)
18857 tree branch_island = build_tree_list (function_name, label_name);
18858 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
18859 TREE_CHAIN (branch_island) = branch_island_list;
18860 branch_island_list = branch_island;
18863 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
18864 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
18865 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
18866 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
18868 /* Generate far-jump branch islands for everything on the
18869 branch_island_list. Invoked immediately after the last instruction
18870 of the epilogue has been emitted; the branch-islands must be
18871 appended to, and contiguous with, the function body. Mach-O stubs
18872 are generated in machopic_output_stub(). */
18874 static void
18875 macho_branch_islands (void)
18877 char tmp_buf[512];
18878 tree branch_island;
18880 for (branch_island = branch_island_list;
18881 branch_island;
18882 branch_island = TREE_CHAIN (branch_island))
18884 const char *label =
18885 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
18886 const char *name =
18887 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
18888 char name_buf[512];
18889 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
18890 if (name[0] == '*' || name[0] == '&')
18891 strcpy (name_buf, name+1);
18892 else
18894 name_buf[0] = '_';
18895 strcpy (name_buf+1, name);
18897 strcpy (tmp_buf, "\n");
18898 strcat (tmp_buf, label);
18899 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
18900 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
18901 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
18902 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
18903 if (flag_pic)
18905 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
18906 strcat (tmp_buf, label);
18907 strcat (tmp_buf, "_pic\n");
18908 strcat (tmp_buf, label);
18909 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
18911 strcat (tmp_buf, "\taddis r11,r11,ha16(");
18912 strcat (tmp_buf, name_buf);
18913 strcat (tmp_buf, " - ");
18914 strcat (tmp_buf, label);
18915 strcat (tmp_buf, "_pic)\n");
18917 strcat (tmp_buf, "\tmtlr r0\n");
18919 strcat (tmp_buf, "\taddi r12,r11,lo16(");
18920 strcat (tmp_buf, name_buf);
18921 strcat (tmp_buf, " - ");
18922 strcat (tmp_buf, label);
18923 strcat (tmp_buf, "_pic)\n");
18925 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
18927 else
18929 strcat (tmp_buf, ":\nlis r12,hi16(");
18930 strcat (tmp_buf, name_buf);
18931 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
18932 strcat (tmp_buf, name_buf);
18933 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
18935 output_asm_insn (tmp_buf, 0);
18936 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
18937 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
18938 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
18939 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
18942 branch_island_list = 0;
18945 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
18946 already there or not. */
18948 static int
18949 no_previous_def (tree function_name)
18951 tree branch_island;
18952 for (branch_island = branch_island_list;
18953 branch_island;
18954 branch_island = TREE_CHAIN (branch_island))
18955 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
18956 return 0;
18957 return 1;
18960 /* GET_PREV_LABEL gets the label name from the previous definition of
18961 the function. */
18963 static tree
18964 get_prev_label (tree function_name)
18966 tree branch_island;
18967 for (branch_island = branch_island_list;
18968 branch_island;
18969 branch_island = TREE_CHAIN (branch_island))
18970 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
18971 return BRANCH_ISLAND_LABEL_NAME (branch_island);
18972 return 0;
18975 /* INSN is either a function call or a millicode call. It may have an
18976 unconditional jump in its delay slot.
18978 CALL_DEST is the routine we are calling. */
18980 char *
18981 output_call (rtx insn, rtx *operands, int dest_operand_number,
18982 int cookie_operand_number)
18984 static char buf[256];
18985 if (GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
18986 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
18988 tree labelname;
18989 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
18991 if (no_previous_def (funname))
18993 int line_number = 0;
18994 rtx label_rtx = gen_label_rtx ();
18995 char *label_buf, temp_buf[256];
18996 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
18997 CODE_LABEL_NUMBER (label_rtx));
18998 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
18999 labelname = get_identifier (label_buf);
19000 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
19001 if (insn)
19002 line_number = NOTE_LINE_NUMBER (insn);
19003 add_compiler_branch_island (labelname, funname, line_number);
19005 else
19006 labelname = get_prev_label (funname);
19008 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
19009 instruction will reach 'foo', otherwise link as 'bl L42'".
19010 "L42" should be a 'branch island', that will do a far jump to
19011 'foo'. Branch islands are generated in
19012 macho_branch_islands(). */
19013 sprintf (buf, "jbsr %%z%d,%.246s",
19014 dest_operand_number, IDENTIFIER_POINTER (labelname));
19016 else
19017 sprintf (buf, "bl %%z%d", dest_operand_number);
19018 return buf;
19021 /* Generate PIC and indirect symbol stubs. */
19023 void
19024 machopic_output_stub (FILE *file, const char *symb, const char *stub)
19026 unsigned int length;
19027 char *symbol_name, *lazy_ptr_name;
19028 char *local_label_0;
19029 static int label = 0;
19031 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
19032 symb = (*targetm.strip_name_encoding) (symb);
19035 length = strlen (symb);
19036 symbol_name = alloca (length + 32);
19037 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
19039 lazy_ptr_name = alloca (length + 32);
19040 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
19042 if (flag_pic == 2)
19043 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
19044 else
19045 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
19047 if (flag_pic == 2)
19049 fprintf (file, "\t.align 5\n");
19051 fprintf (file, "%s:\n", stub);
19052 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19054 label++;
19055 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
19056 sprintf (local_label_0, "\"L%011d$spb\"", label);
19058 fprintf (file, "\tmflr r0\n");
19059 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
19060 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
19061 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
19062 lazy_ptr_name, local_label_0);
19063 fprintf (file, "\tmtlr r0\n");
19064 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
19065 (TARGET_64BIT ? "ldu" : "lwzu"),
19066 lazy_ptr_name, local_label_0);
19067 fprintf (file, "\tmtctr r12\n");
19068 fprintf (file, "\tbctr\n");
19070 else
19072 fprintf (file, "\t.align 4\n");
19074 fprintf (file, "%s:\n", stub);
19075 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19077 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
19078 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
19079 (TARGET_64BIT ? "ldu" : "lwzu"),
19080 lazy_ptr_name);
19081 fprintf (file, "\tmtctr r12\n");
19082 fprintf (file, "\tbctr\n");
19085 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
19086 fprintf (file, "%s:\n", lazy_ptr_name);
19087 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19088 fprintf (file, "%sdyld_stub_binding_helper\n",
19089 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
19092 /* Legitimize PIC addresses. If the address is already
19093 position-independent, we return ORIG. Newly generated
19094 position-independent addresses go into a reg. This is REG if non
19095 zero, otherwise we allocate register(s) as necessary. */
19097 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
19100 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
19101 rtx reg)
19103 rtx base, offset;
19105 if (reg == NULL && ! reload_in_progress && ! reload_completed)
19106 reg = gen_reg_rtx (Pmode);
19108 if (GET_CODE (orig) == CONST)
19110 rtx reg_temp;
19112 if (GET_CODE (XEXP (orig, 0)) == PLUS
19113 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
19114 return orig;
19116 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
19118 /* Use a different reg for the intermediate value, as
19119 it will be marked UNCHANGING. */
19120 reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
19121 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
19122 Pmode, reg_temp);
19123 offset =
19124 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
19125 Pmode, reg);
19127 if (GET_CODE (offset) == CONST_INT)
19129 if (SMALL_INT (offset))
19130 return plus_constant (base, INTVAL (offset));
19131 else if (! reload_in_progress && ! reload_completed)
19132 offset = force_reg (Pmode, offset);
19133 else
19135 rtx mem = force_const_mem (Pmode, orig);
19136 return machopic_legitimize_pic_address (mem, Pmode, reg);
19139 return gen_rtx_PLUS (Pmode, base, offset);
19142 /* Fall back on generic machopic code. */
19143 return machopic_legitimize_pic_address (orig, mode, reg);
19146 /* Output a .machine directive for the Darwin assembler, and call
19147 the generic start_file routine. */
19149 static void
19150 rs6000_darwin_file_start (void)
19152 static const struct
19154 const char *arg;
19155 const char *name;
19156 int if_set;
19157 } mapping[] = {
19158 { "ppc64", "ppc64", MASK_64BIT },
19159 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
19160 { "power4", "ppc970", 0 },
19161 { "G5", "ppc970", 0 },
19162 { "7450", "ppc7450", 0 },
19163 { "7400", "ppc7400", MASK_ALTIVEC },
19164 { "G4", "ppc7400", 0 },
19165 { "750", "ppc750", 0 },
19166 { "740", "ppc750", 0 },
19167 { "G3", "ppc750", 0 },
19168 { "604e", "ppc604e", 0 },
19169 { "604", "ppc604", 0 },
19170 { "603e", "ppc603", 0 },
19171 { "603", "ppc603", 0 },
19172 { "601", "ppc601", 0 },
19173 { NULL, "ppc", 0 } };
19174 const char *cpu_id = "";
19175 size_t i;
19177 rs6000_file_start ();
19178 darwin_file_start ();
19180 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
19181 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
19182 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
19183 && rs6000_select[i].string[0] != '\0')
19184 cpu_id = rs6000_select[i].string;
19186 /* Look through the mapping array. Pick the first name that either
19187 matches the argument, has a bit set in IF_SET that is also set
19188 in the target flags, or has a NULL name. */
19190 i = 0;
19191 while (mapping[i].arg != NULL
19192 && strcmp (mapping[i].arg, cpu_id) != 0
19193 && (mapping[i].if_set & target_flags) == 0)
19194 i++;
19196 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
19199 #endif /* TARGET_MACHO */
19201 #if TARGET_ELF
19202 static unsigned int
19203 rs6000_elf_section_type_flags (tree decl, const char *name, int reloc)
19205 return default_section_type_flags_1 (decl, name, reloc,
19206 flag_pic || DEFAULT_ABI == ABI_AIX);
19209 /* Record an element in the table of global constructors. SYMBOL is
19210 a SYMBOL_REF of the function to be called; PRIORITY is a number
19211 between 0 and MAX_INIT_PRIORITY.
19213 This differs from default_named_section_asm_out_constructor in
19214 that we have special handling for -mrelocatable. */
19216 static void
19217 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
19219 const char *section = ".ctors";
19220 char buf[16];
19222 if (priority != DEFAULT_INIT_PRIORITY)
19224 sprintf (buf, ".ctors.%.5u",
19225 /* Invert the numbering so the linker puts us in the proper
19226 order; constructors are run from right to left, and the
19227 linker sorts in increasing order. */
19228 MAX_INIT_PRIORITY - priority);
19229 section = buf;
19232 switch_to_section (get_section (section, SECTION_WRITE, NULL));
19233 assemble_align (POINTER_SIZE);
19235 if (TARGET_RELOCATABLE)
19237 fputs ("\t.long (", asm_out_file);
19238 output_addr_const (asm_out_file, symbol);
19239 fputs (")@fixup\n", asm_out_file);
19241 else
19242 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
19245 static void
19246 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
19248 const char *section = ".dtors";
19249 char buf[16];
19251 if (priority != DEFAULT_INIT_PRIORITY)
19253 sprintf (buf, ".dtors.%.5u",
19254 /* Invert the numbering so the linker puts us in the proper
19255 order; constructors are run from right to left, and the
19256 linker sorts in increasing order. */
19257 MAX_INIT_PRIORITY - priority);
19258 section = buf;
19261 switch_to_section (get_section (section, SECTION_WRITE, NULL));
19262 assemble_align (POINTER_SIZE);
19264 if (TARGET_RELOCATABLE)
19266 fputs ("\t.long (", asm_out_file);
19267 output_addr_const (asm_out_file, symbol);
19268 fputs (")@fixup\n", asm_out_file);
19270 else
19271 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
19274 void
19275 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
19277 if (TARGET_64BIT)
19279 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
19280 ASM_OUTPUT_LABEL (file, name);
19281 fputs (DOUBLE_INT_ASM_OP, file);
19282 rs6000_output_function_entry (file, name);
19283 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
19284 if (DOT_SYMBOLS)
19286 fputs ("\t.size\t", file);
19287 assemble_name (file, name);
19288 fputs (",24\n\t.type\t.", file);
19289 assemble_name (file, name);
19290 fputs (",@function\n", file);
19291 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
19293 fputs ("\t.globl\t.", file);
19294 assemble_name (file, name);
19295 putc ('\n', file);
19298 else
19299 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
19300 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
19301 rs6000_output_function_entry (file, name);
19302 fputs (":\n", file);
19303 return;
19306 if (TARGET_RELOCATABLE
19307 && !TARGET_SECURE_PLT
19308 && (get_pool_size () != 0 || current_function_profile)
19309 && uses_TOC ())
19311 char buf[256];
19313 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
19315 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19316 fprintf (file, "\t.long ");
19317 assemble_name (file, buf);
19318 putc ('-', file);
19319 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19320 assemble_name (file, buf);
19321 putc ('\n', file);
19324 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
19325 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
19327 if (DEFAULT_ABI == ABI_AIX)
19329 const char *desc_name, *orig_name;
19331 orig_name = (*targetm.strip_name_encoding) (name);
19332 desc_name = orig_name;
19333 while (*desc_name == '.')
19334 desc_name++;
19336 if (TREE_PUBLIC (decl))
19337 fprintf (file, "\t.globl %s\n", desc_name);
19339 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
19340 fprintf (file, "%s:\n", desc_name);
19341 fprintf (file, "\t.long %s\n", orig_name);
19342 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
19343 if (DEFAULT_ABI == ABI_AIX)
19344 fputs ("\t.long 0\n", file);
19345 fprintf (file, "\t.previous\n");
19347 ASM_OUTPUT_LABEL (file, name);
19350 static void
19351 rs6000_elf_end_indicate_exec_stack (void)
19353 if (TARGET_32BIT)
19354 file_end_indicate_exec_stack ();
19356 #endif
19358 #if TARGET_XCOFF
19359 static void
19360 rs6000_xcoff_asm_output_anchor (rtx symbol)
19362 char buffer[100];
19364 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
19365 SYMBOL_REF_BLOCK_OFFSET (symbol));
19366 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
19369 static void
19370 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
19372 fputs (GLOBAL_ASM_OP, stream);
19373 RS6000_OUTPUT_BASENAME (stream, name);
19374 putc ('\n', stream);
19377 /* A get_unnamed_decl callback, used for read-only sections. PTR
19378 points to the section string variable. */
19380 static void
19381 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
19383 fprintf (asm_out_file, "\t.csect %s[RO],3\n",
19384 *(const char *const *) directive);
19387 /* Likewise for read-write sections. */
19389 static void
19390 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
19392 fprintf (asm_out_file, "\t.csect %s[RW],3\n",
19393 *(const char *const *) directive);
19396 /* A get_unnamed_section callback, used for switching to toc_section. */
19398 static void
19399 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
19401 if (TARGET_MINIMAL_TOC)
19403 /* toc_section is always selected at least once from
19404 rs6000_xcoff_file_start, so this is guaranteed to
19405 always be defined once and only once in each file. */
19406 if (!toc_initialized)
19408 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
19409 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
19410 toc_initialized = 1;
19412 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
19413 (TARGET_32BIT ? "" : ",3"));
19415 else
19416 fputs ("\t.toc\n", asm_out_file);
19419 /* Implement TARGET_ASM_INIT_SECTIONS. */
19421 static void
19422 rs6000_xcoff_asm_init_sections (void)
19424 read_only_data_section
19425 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
19426 &xcoff_read_only_section_name);
19428 private_data_section
19429 = get_unnamed_section (SECTION_WRITE,
19430 rs6000_xcoff_output_readwrite_section_asm_op,
19431 &xcoff_private_data_section_name);
19433 read_only_private_data_section
19434 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
19435 &xcoff_private_data_section_name);
19437 toc_section
19438 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
19440 readonly_data_section = read_only_data_section;
19441 exception_section = data_section;
19444 static void
19445 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
19446 tree decl ATTRIBUTE_UNUSED)
19448 int smclass;
19449 static const char * const suffix[3] = { "PR", "RO", "RW" };
19451 if (flags & SECTION_CODE)
19452 smclass = 0;
19453 else if (flags & SECTION_WRITE)
19454 smclass = 2;
19455 else
19456 smclass = 1;
19458 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
19459 (flags & SECTION_CODE) ? "." : "",
19460 name, suffix[smclass], flags & SECTION_ENTSIZE);
19463 static section *
19464 rs6000_xcoff_select_section (tree decl, int reloc,
19465 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
19467 if (decl_readonly_section_1 (decl, reloc, 1))
19469 if (TREE_PUBLIC (decl))
19470 return read_only_data_section;
19471 else
19472 return read_only_private_data_section;
19474 else
19476 if (TREE_PUBLIC (decl))
19477 return data_section;
19478 else
19479 return private_data_section;
19483 static void
19484 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
19486 const char *name;
19488 /* Use select_section for private and uninitialized data. */
19489 if (!TREE_PUBLIC (decl)
19490 || DECL_COMMON (decl)
19491 || DECL_INITIAL (decl) == NULL_TREE
19492 || DECL_INITIAL (decl) == error_mark_node
19493 || (flag_zero_initialized_in_bss
19494 && initializer_zerop (DECL_INITIAL (decl))))
19495 return;
19497 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
19498 name = (*targetm.strip_name_encoding) (name);
19499 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
19502 /* Select section for constant in constant pool.
19504 On RS/6000, all constants are in the private read-only data area.
19505 However, if this is being placed in the TOC it must be output as a
19506 toc entry. */
19508 static section *
19509 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
19510 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
19512 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
19513 return toc_section;
19514 else
19515 return read_only_private_data_section;
19518 /* Remove any trailing [DS] or the like from the symbol name. */
19520 static const char *
19521 rs6000_xcoff_strip_name_encoding (const char *name)
19523 size_t len;
19524 if (*name == '*')
19525 name++;
19526 len = strlen (name);
19527 if (name[len - 1] == ']')
19528 return ggc_alloc_string (name, len - 4);
19529 else
19530 return name;
19533 /* Section attributes. AIX is always PIC. */
19535 static unsigned int
19536 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
19538 unsigned int align;
19539 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
19541 /* Align to at least UNIT size. */
19542 if (flags & SECTION_CODE)
19543 align = MIN_UNITS_PER_WORD;
19544 else
19545 /* Increase alignment of large objects if not already stricter. */
19546 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
19547 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
19548 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
19550 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
19553 /* Output at beginning of assembler file.
19555 Initialize the section names for the RS/6000 at this point.
19557 Specify filename, including full path, to assembler.
19559 We want to go into the TOC section so at least one .toc will be emitted.
19560 Also, in order to output proper .bs/.es pairs, we need at least one static
19561 [RW] section emitted.
19563 Finally, declare mcount when profiling to make the assembler happy. */
19565 static void
19566 rs6000_xcoff_file_start (void)
19568 rs6000_gen_section_name (&xcoff_bss_section_name,
19569 main_input_filename, ".bss_");
19570 rs6000_gen_section_name (&xcoff_private_data_section_name,
19571 main_input_filename, ".rw_");
19572 rs6000_gen_section_name (&xcoff_read_only_section_name,
19573 main_input_filename, ".ro_");
19575 fputs ("\t.file\t", asm_out_file);
19576 output_quoted_string (asm_out_file, main_input_filename);
19577 fputc ('\n', asm_out_file);
19578 if (write_symbols != NO_DEBUG)
19579 switch_to_section (private_data_section);
19580 switch_to_section (text_section);
19581 if (profile_flag)
19582 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
19583 rs6000_file_start ();
19586 /* Output at end of assembler file.
19587 On the RS/6000, referencing data should automatically pull in text. */
19589 static void
19590 rs6000_xcoff_file_end (void)
19592 switch_to_section (text_section);
19593 fputs ("_section_.text:\n", asm_out_file);
19594 switch_to_section (data_section);
19595 fputs (TARGET_32BIT
19596 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
19597 asm_out_file);
19599 #endif /* TARGET_XCOFF */
19601 /* Compute a (partial) cost for rtx X. Return true if the complete
19602 cost has been computed, and false if subexpressions should be
19603 scanned. In either case, *TOTAL contains the cost result. */
19605 static bool
19606 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
19608 enum machine_mode mode = GET_MODE (x);
19610 switch (code)
19612 /* On the RS/6000, if it is valid in the insn, it is free. */
19613 case CONST_INT:
19614 if (((outer_code == SET
19615 || outer_code == PLUS
19616 || outer_code == MINUS)
19617 && (satisfies_constraint_I (x)
19618 || satisfies_constraint_L (x)))
19619 || (outer_code == AND
19620 && (satisfies_constraint_K (x)
19621 || (mode == SImode
19622 ? satisfies_constraint_L (x)
19623 : satisfies_constraint_J (x))
19624 || mask_operand (x, mode)
19625 || (mode == DImode
19626 && mask64_operand (x, DImode))))
19627 || ((outer_code == IOR || outer_code == XOR)
19628 && (satisfies_constraint_K (x)
19629 || (mode == SImode
19630 ? satisfies_constraint_L (x)
19631 : satisfies_constraint_J (x))))
19632 || outer_code == ASHIFT
19633 || outer_code == ASHIFTRT
19634 || outer_code == LSHIFTRT
19635 || outer_code == ROTATE
19636 || outer_code == ROTATERT
19637 || outer_code == ZERO_EXTRACT
19638 || (outer_code == MULT
19639 && satisfies_constraint_I (x))
19640 || ((outer_code == DIV || outer_code == UDIV
19641 || outer_code == MOD || outer_code == UMOD)
19642 && exact_log2 (INTVAL (x)) >= 0)
19643 || (outer_code == COMPARE
19644 && (satisfies_constraint_I (x)
19645 || satisfies_constraint_K (x)))
19646 || (outer_code == EQ
19647 && (satisfies_constraint_I (x)
19648 || satisfies_constraint_K (x)
19649 || (mode == SImode
19650 ? satisfies_constraint_L (x)
19651 : satisfies_constraint_J (x))))
19652 || (outer_code == GTU
19653 && satisfies_constraint_I (x))
19654 || (outer_code == LTU
19655 && satisfies_constraint_P (x)))
19657 *total = 0;
19658 return true;
19660 else if ((outer_code == PLUS
19661 && reg_or_add_cint_operand (x, VOIDmode))
19662 || (outer_code == MINUS
19663 && reg_or_sub_cint_operand (x, VOIDmode))
19664 || ((outer_code == SET
19665 || outer_code == IOR
19666 || outer_code == XOR)
19667 && (INTVAL (x)
19668 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
19670 *total = COSTS_N_INSNS (1);
19671 return true;
19673 /* FALLTHRU */
19675 case CONST_DOUBLE:
19676 if (mode == DImode && code == CONST_DOUBLE)
19678 if ((outer_code == IOR || outer_code == XOR)
19679 && CONST_DOUBLE_HIGH (x) == 0
19680 && (CONST_DOUBLE_LOW (x)
19681 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
19683 *total = 0;
19684 return true;
19686 else if ((outer_code == AND && and64_2_operand (x, DImode))
19687 || ((outer_code == SET
19688 || outer_code == IOR
19689 || outer_code == XOR)
19690 && CONST_DOUBLE_HIGH (x) == 0))
19692 *total = COSTS_N_INSNS (1);
19693 return true;
19696 /* FALLTHRU */
19698 case CONST:
19699 case HIGH:
19700 case SYMBOL_REF:
19701 case MEM:
19702 /* When optimizing for size, MEM should be slightly more expensive
19703 than generating address, e.g., (plus (reg) (const)).
19704 L1 cache latency is about two instructions. */
19705 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
19706 return true;
19708 case LABEL_REF:
19709 *total = 0;
19710 return true;
19712 case PLUS:
19713 if (mode == DFmode)
19715 if (GET_CODE (XEXP (x, 0)) == MULT)
19717 /* FNMA accounted in outer NEG. */
19718 if (outer_code == NEG)
19719 *total = rs6000_cost->dmul - rs6000_cost->fp;
19720 else
19721 *total = rs6000_cost->dmul;
19723 else
19724 *total = rs6000_cost->fp;
19726 else if (mode == SFmode)
19728 /* FNMA accounted in outer NEG. */
19729 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
19730 *total = 0;
19731 else
19732 *total = rs6000_cost->fp;
19734 else
19735 *total = COSTS_N_INSNS (1);
19736 return false;
19738 case MINUS:
19739 if (mode == DFmode)
19741 if (GET_CODE (XEXP (x, 0)) == MULT)
19743 /* FNMA accounted in outer NEG. */
19744 if (outer_code == NEG)
19745 *total = 0;
19746 else
19747 *total = rs6000_cost->dmul;
19749 else
19750 *total = rs6000_cost->fp;
19752 else if (mode == SFmode)
19754 /* FNMA accounted in outer NEG. */
19755 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
19756 *total = 0;
19757 else
19758 *total = rs6000_cost->fp;
19760 else
19761 *total = COSTS_N_INSNS (1);
19762 return false;
19764 case MULT:
19765 if (GET_CODE (XEXP (x, 1)) == CONST_INT
19766 && satisfies_constraint_I (XEXP (x, 1)))
19768 if (INTVAL (XEXP (x, 1)) >= -256
19769 && INTVAL (XEXP (x, 1)) <= 255)
19770 *total = rs6000_cost->mulsi_const9;
19771 else
19772 *total = rs6000_cost->mulsi_const;
19774 /* FMA accounted in outer PLUS/MINUS. */
19775 else if ((mode == DFmode || mode == SFmode)
19776 && (outer_code == PLUS || outer_code == MINUS))
19777 *total = 0;
19778 else if (mode == DFmode)
19779 *total = rs6000_cost->dmul;
19780 else if (mode == SFmode)
19781 *total = rs6000_cost->fp;
19782 else if (mode == DImode)
19783 *total = rs6000_cost->muldi;
19784 else
19785 *total = rs6000_cost->mulsi;
19786 return false;
19788 case DIV:
19789 case MOD:
19790 if (FLOAT_MODE_P (mode))
19792 *total = mode == DFmode ? rs6000_cost->ddiv
19793 : rs6000_cost->sdiv;
19794 return false;
19796 /* FALLTHRU */
19798 case UDIV:
19799 case UMOD:
19800 if (GET_CODE (XEXP (x, 1)) == CONST_INT
19801 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
19803 if (code == DIV || code == MOD)
19804 /* Shift, addze */
19805 *total = COSTS_N_INSNS (2);
19806 else
19807 /* Shift */
19808 *total = COSTS_N_INSNS (1);
19810 else
19812 if (GET_MODE (XEXP (x, 1)) == DImode)
19813 *total = rs6000_cost->divdi;
19814 else
19815 *total = rs6000_cost->divsi;
19817 /* Add in shift and subtract for MOD. */
19818 if (code == MOD || code == UMOD)
19819 *total += COSTS_N_INSNS (2);
19820 return false;
19822 case FFS:
19823 *total = COSTS_N_INSNS (4);
19824 return false;
19826 case NOT:
19827 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
19829 *total = 0;
19830 return false;
19832 /* FALLTHRU */
19834 case AND:
19835 case IOR:
19836 case XOR:
19837 case ZERO_EXTRACT:
19838 *total = COSTS_N_INSNS (1);
19839 return false;
19841 case ASHIFT:
19842 case ASHIFTRT:
19843 case LSHIFTRT:
19844 case ROTATE:
19845 case ROTATERT:
19846 /* Handle mul_highpart. */
19847 if (outer_code == TRUNCATE
19848 && GET_CODE (XEXP (x, 0)) == MULT)
19850 if (mode == DImode)
19851 *total = rs6000_cost->muldi;
19852 else
19853 *total = rs6000_cost->mulsi;
19854 return true;
19856 else if (outer_code == AND)
19857 *total = 0;
19858 else
19859 *total = COSTS_N_INSNS (1);
19860 return false;
19862 case SIGN_EXTEND:
19863 case ZERO_EXTEND:
19864 if (GET_CODE (XEXP (x, 0)) == MEM)
19865 *total = 0;
19866 else
19867 *total = COSTS_N_INSNS (1);
19868 return false;
19870 case COMPARE:
19871 case NEG:
19872 case ABS:
19873 if (!FLOAT_MODE_P (mode))
19875 *total = COSTS_N_INSNS (1);
19876 return false;
19878 /* FALLTHRU */
19880 case FLOAT:
19881 case UNSIGNED_FLOAT:
19882 case FIX:
19883 case UNSIGNED_FIX:
19884 case FLOAT_TRUNCATE:
19885 *total = rs6000_cost->fp;
19886 return false;
19888 case FLOAT_EXTEND:
19889 if (mode == DFmode)
19890 *total = 0;
19891 else
19892 *total = rs6000_cost->fp;
19893 return false;
19895 case UNSPEC:
19896 switch (XINT (x, 1))
19898 case UNSPEC_FRSP:
19899 *total = rs6000_cost->fp;
19900 return true;
19902 default:
19903 break;
19905 break;
19907 case CALL:
19908 case IF_THEN_ELSE:
19909 if (optimize_size)
19911 *total = COSTS_N_INSNS (1);
19912 return true;
19914 else if (FLOAT_MODE_P (mode)
19915 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
19917 *total = rs6000_cost->fp;
19918 return false;
19920 break;
19922 case EQ:
19923 case GTU:
19924 case LTU:
19925 /* Carry bit requires mode == Pmode.
19926 NEG or PLUS already counted so only add one. */
19927 if (mode == Pmode
19928 && (outer_code == NEG || outer_code == PLUS))
19930 *total = COSTS_N_INSNS (1);
19931 return true;
19933 if (outer_code == SET)
19935 if (XEXP (x, 1) == const0_rtx)
19937 *total = COSTS_N_INSNS (2);
19938 return true;
19940 else if (mode == Pmode)
19942 *total = COSTS_N_INSNS (3);
19943 return false;
19946 /* FALLTHRU */
19948 case GT:
19949 case LT:
19950 case UNORDERED:
19951 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
19953 *total = COSTS_N_INSNS (2);
19954 return true;
19956 /* CC COMPARE. */
19957 if (outer_code == COMPARE)
19959 *total = 0;
19960 return true;
19962 break;
19964 default:
19965 break;
19968 return false;
19971 /* A C expression returning the cost of moving data from a register of class
19972 CLASS1 to one of CLASS2. */
19975 rs6000_register_move_cost (enum machine_mode mode,
19976 enum reg_class from, enum reg_class to)
19978 /* Moves from/to GENERAL_REGS. */
19979 if (reg_classes_intersect_p (to, GENERAL_REGS)
19980 || reg_classes_intersect_p (from, GENERAL_REGS))
19982 if (! reg_classes_intersect_p (to, GENERAL_REGS))
19983 from = to;
19985 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
19986 return (rs6000_memory_move_cost (mode, from, 0)
19987 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
19989 /* It's more expensive to move CR_REGS than CR0_REGS because of the
19990 shift. */
19991 else if (from == CR_REGS)
19992 return 4;
19994 else
19995 /* A move will cost one instruction per GPR moved. */
19996 return 2 * hard_regno_nregs[0][mode];
19999 /* Moving between two similar registers is just one instruction. */
20000 else if (reg_classes_intersect_p (to, from))
20001 return mode == TFmode ? 4 : 2;
20003 /* Everything else has to go through GENERAL_REGS. */
20004 else
20005 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
20006 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
20009 /* A C expressions returning the cost of moving data of MODE from a register to
20010 or from memory. */
20013 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
20014 int in ATTRIBUTE_UNUSED)
20016 if (reg_classes_intersect_p (class, GENERAL_REGS))
20017 return 4 * hard_regno_nregs[0][mode];
20018 else if (reg_classes_intersect_p (class, FLOAT_REGS))
20019 return 4 * hard_regno_nregs[32][mode];
20020 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
20021 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
20022 else
20023 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
20026 /* Newton-Raphson approximation of single-precision floating point divide n/d.
20027 Assumes no trapping math and finite arguments. */
20029 void
20030 rs6000_emit_swdivsf (rtx res, rtx n, rtx d)
20032 rtx x0, e0, e1, y1, u0, v0, one;
20034 x0 = gen_reg_rtx (SFmode);
20035 e0 = gen_reg_rtx (SFmode);
20036 e1 = gen_reg_rtx (SFmode);
20037 y1 = gen_reg_rtx (SFmode);
20038 u0 = gen_reg_rtx (SFmode);
20039 v0 = gen_reg_rtx (SFmode);
20040 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
20042 /* x0 = 1./d estimate */
20043 emit_insn (gen_rtx_SET (VOIDmode, x0,
20044 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
20045 UNSPEC_FRES)));
20046 /* e0 = 1. - d * x0 */
20047 emit_insn (gen_rtx_SET (VOIDmode, e0,
20048 gen_rtx_MINUS (SFmode, one,
20049 gen_rtx_MULT (SFmode, d, x0))));
20050 /* e1 = e0 + e0 * e0 */
20051 emit_insn (gen_rtx_SET (VOIDmode, e1,
20052 gen_rtx_PLUS (SFmode,
20053 gen_rtx_MULT (SFmode, e0, e0), e0)));
20054 /* y1 = x0 + e1 * x0 */
20055 emit_insn (gen_rtx_SET (VOIDmode, y1,
20056 gen_rtx_PLUS (SFmode,
20057 gen_rtx_MULT (SFmode, e1, x0), x0)));
20058 /* u0 = n * y1 */
20059 emit_insn (gen_rtx_SET (VOIDmode, u0,
20060 gen_rtx_MULT (SFmode, n, y1)));
20061 /* v0 = n - d * u0 */
20062 emit_insn (gen_rtx_SET (VOIDmode, v0,
20063 gen_rtx_MINUS (SFmode, n,
20064 gen_rtx_MULT (SFmode, d, u0))));
20065 /* res = u0 + v0 * y1 */
20066 emit_insn (gen_rtx_SET (VOIDmode, res,
20067 gen_rtx_PLUS (SFmode,
20068 gen_rtx_MULT (SFmode, v0, y1), u0)));
20071 /* Newton-Raphson approximation of double-precision floating point divide n/d.
20072 Assumes no trapping math and finite arguments. */
20074 void
20075 rs6000_emit_swdivdf (rtx res, rtx n, rtx d)
20077 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
20079 x0 = gen_reg_rtx (DFmode);
20080 e0 = gen_reg_rtx (DFmode);
20081 e1 = gen_reg_rtx (DFmode);
20082 e2 = gen_reg_rtx (DFmode);
20083 y1 = gen_reg_rtx (DFmode);
20084 y2 = gen_reg_rtx (DFmode);
20085 y3 = gen_reg_rtx (DFmode);
20086 u0 = gen_reg_rtx (DFmode);
20087 v0 = gen_reg_rtx (DFmode);
20088 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
20090 /* x0 = 1./d estimate */
20091 emit_insn (gen_rtx_SET (VOIDmode, x0,
20092 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
20093 UNSPEC_FRES)));
20094 /* e0 = 1. - d * x0 */
20095 emit_insn (gen_rtx_SET (VOIDmode, e0,
20096 gen_rtx_MINUS (DFmode, one,
20097 gen_rtx_MULT (SFmode, d, x0))));
20098 /* y1 = x0 + e0 * x0 */
20099 emit_insn (gen_rtx_SET (VOIDmode, y1,
20100 gen_rtx_PLUS (DFmode,
20101 gen_rtx_MULT (DFmode, e0, x0), x0)));
20102 /* e1 = e0 * e0 */
20103 emit_insn (gen_rtx_SET (VOIDmode, e1,
20104 gen_rtx_MULT (DFmode, e0, e0)));
20105 /* y2 = y1 + e1 * y1 */
20106 emit_insn (gen_rtx_SET (VOIDmode, y2,
20107 gen_rtx_PLUS (DFmode,
20108 gen_rtx_MULT (DFmode, e1, y1), y1)));
20109 /* e2 = e1 * e1 */
20110 emit_insn (gen_rtx_SET (VOIDmode, e2,
20111 gen_rtx_MULT (DFmode, e1, e1)));
20112 /* y3 = y2 + e2 * y2 */
20113 emit_insn (gen_rtx_SET (VOIDmode, y3,
20114 gen_rtx_PLUS (DFmode,
20115 gen_rtx_MULT (DFmode, e2, y2), y2)));
20116 /* u0 = n * y3 */
20117 emit_insn (gen_rtx_SET (VOIDmode, u0,
20118 gen_rtx_MULT (DFmode, n, y3)));
20119 /* v0 = n - d * u0 */
20120 emit_insn (gen_rtx_SET (VOIDmode, v0,
20121 gen_rtx_MINUS (DFmode, n,
20122 gen_rtx_MULT (DFmode, d, u0))));
20123 /* res = u0 + v0 * y3 */
20124 emit_insn (gen_rtx_SET (VOIDmode, res,
20125 gen_rtx_PLUS (DFmode,
20126 gen_rtx_MULT (DFmode, v0, y3), u0)));
20129 /* Return an RTX representing where to find the function value of a
20130 function returning MODE. */
20131 static rtx
20132 rs6000_complex_function_value (enum machine_mode mode)
20134 unsigned int regno;
20135 rtx r1, r2;
20136 enum machine_mode inner = GET_MODE_INNER (mode);
20137 unsigned int inner_bytes = GET_MODE_SIZE (inner);
20139 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
20140 regno = FP_ARG_RETURN;
20141 else
20143 regno = GP_ARG_RETURN;
20145 /* 32-bit is OK since it'll go in r3/r4. */
20146 if (TARGET_32BIT && inner_bytes >= 4)
20147 return gen_rtx_REG (mode, regno);
20150 if (inner_bytes >= 8)
20151 return gen_rtx_REG (mode, regno);
20153 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
20154 const0_rtx);
20155 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
20156 GEN_INT (inner_bytes));
20157 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
20160 /* Define how to find the value returned by a function.
20161 VALTYPE is the data type of the value (as a tree).
20162 If the precise function being called is known, FUNC is its FUNCTION_DECL;
20163 otherwise, FUNC is 0.
20165 On the SPE, both FPs and vectors are returned in r3.
20167 On RS/6000 an integer value is in r3 and a floating-point value is in
20168 fp1, unless -msoft-float. */
20171 rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
20173 enum machine_mode mode;
20174 unsigned int regno;
20176 /* Special handling for structs in darwin64. */
20177 if (rs6000_darwin64_abi
20178 && TYPE_MODE (valtype) == BLKmode
20179 && TREE_CODE (valtype) == RECORD_TYPE
20180 && int_size_in_bytes (valtype) > 0)
20182 CUMULATIVE_ARGS valcum;
20183 rtx valret;
20185 valcum.words = 0;
20186 valcum.fregno = FP_ARG_MIN_REG;
20187 valcum.vregno = ALTIVEC_ARG_MIN_REG;
20188 /* Do a trial code generation as if this were going to be passed as
20189 an argument; if any part goes in memory, we return NULL. */
20190 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
20191 if (valret)
20192 return valret;
20193 /* Otherwise fall through to standard ABI rules. */
20196 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
20198 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20199 return gen_rtx_PARALLEL (DImode,
20200 gen_rtvec (2,
20201 gen_rtx_EXPR_LIST (VOIDmode,
20202 gen_rtx_REG (SImode, GP_ARG_RETURN),
20203 const0_rtx),
20204 gen_rtx_EXPR_LIST (VOIDmode,
20205 gen_rtx_REG (SImode,
20206 GP_ARG_RETURN + 1),
20207 GEN_INT (4))));
20209 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
20211 return gen_rtx_PARALLEL (DCmode,
20212 gen_rtvec (4,
20213 gen_rtx_EXPR_LIST (VOIDmode,
20214 gen_rtx_REG (SImode, GP_ARG_RETURN),
20215 const0_rtx),
20216 gen_rtx_EXPR_LIST (VOIDmode,
20217 gen_rtx_REG (SImode,
20218 GP_ARG_RETURN + 1),
20219 GEN_INT (4)),
20220 gen_rtx_EXPR_LIST (VOIDmode,
20221 gen_rtx_REG (SImode,
20222 GP_ARG_RETURN + 2),
20223 GEN_INT (8)),
20224 gen_rtx_EXPR_LIST (VOIDmode,
20225 gen_rtx_REG (SImode,
20226 GP_ARG_RETURN + 3),
20227 GEN_INT (12))));
20230 if ((INTEGRAL_TYPE_P (valtype)
20231 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
20232 || POINTER_TYPE_P (valtype))
20233 mode = TARGET_32BIT ? SImode : DImode;
20234 else
20235 mode = TYPE_MODE (valtype);
20237 if (DECIMAL_FLOAT_MODE_P (mode))
20238 regno = GP_ARG_RETURN;
20239 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
20240 regno = FP_ARG_RETURN;
20241 else if (TREE_CODE (valtype) == COMPLEX_TYPE
20242 && targetm.calls.split_complex_arg)
20243 return rs6000_complex_function_value (mode);
20244 else if (TREE_CODE (valtype) == VECTOR_TYPE
20245 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
20246 && ALTIVEC_VECTOR_MODE (mode))
20247 regno = ALTIVEC_ARG_RETURN;
20248 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
20249 && (mode == DFmode || mode == DCmode))
20250 return spe_build_register_parallel (mode, GP_ARG_RETURN);
20251 else
20252 regno = GP_ARG_RETURN;
20254 return gen_rtx_REG (mode, regno);
20257 /* Define how to find the value returned by a library function
20258 assuming the value has mode MODE. */
20260 rs6000_libcall_value (enum machine_mode mode)
20262 unsigned int regno;
20264 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
20266 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20267 return gen_rtx_PARALLEL (DImode,
20268 gen_rtvec (2,
20269 gen_rtx_EXPR_LIST (VOIDmode,
20270 gen_rtx_REG (SImode, GP_ARG_RETURN),
20271 const0_rtx),
20272 gen_rtx_EXPR_LIST (VOIDmode,
20273 gen_rtx_REG (SImode,
20274 GP_ARG_RETURN + 1),
20275 GEN_INT (4))));
20278 if (DECIMAL_FLOAT_MODE_P (mode))
20279 regno = GP_ARG_RETURN;
20280 else if (SCALAR_FLOAT_MODE_P (mode)
20281 && TARGET_HARD_FLOAT && TARGET_FPRS)
20282 regno = FP_ARG_RETURN;
20283 else if (ALTIVEC_VECTOR_MODE (mode)
20284 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
20285 regno = ALTIVEC_ARG_RETURN;
20286 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
20287 return rs6000_complex_function_value (mode);
20288 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
20289 && (mode == DFmode || mode == DCmode))
20290 return spe_build_register_parallel (mode, GP_ARG_RETURN);
20291 else
20292 regno = GP_ARG_RETURN;
20294 return gen_rtx_REG (mode, regno);
20297 /* Define the offset between two registers, FROM to be eliminated and its
20298 replacement TO, at the start of a routine. */
20299 HOST_WIDE_INT
20300 rs6000_initial_elimination_offset (int from, int to)
20302 rs6000_stack_t *info = rs6000_stack_info ();
20303 HOST_WIDE_INT offset;
20305 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20306 offset = info->push_p ? 0 : -info->total_size;
20307 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20309 offset = info->push_p ? 0 : -info->total_size;
20310 if (FRAME_GROWS_DOWNWARD)
20311 offset += info->fixed_size + info->vars_size + info->parm_size;
20313 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
20314 offset = FRAME_GROWS_DOWNWARD
20315 ? info->fixed_size + info->vars_size + info->parm_size
20316 : 0;
20317 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
20318 offset = info->total_size;
20319 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20320 offset = info->push_p ? info->total_size : 0;
20321 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
20322 offset = 0;
20323 else
20324 gcc_unreachable ();
20326 return offset;
20329 /* Return true if TYPE is a SPE or AltiVec opaque type. */
20331 static bool
20332 rs6000_is_opaque_type (tree type)
20334 return (type == opaque_V2SI_type_node
20335 || type == opaque_V2SF_type_node
20336 || type == opaque_p_V2SI_type_node
20337 || type == opaque_V4SI_type_node);
20340 static rtx
20341 rs6000_dwarf_register_span (rtx reg)
20343 unsigned regno;
20345 if (TARGET_SPE
20346 && (SPE_VECTOR_MODE (GET_MODE (reg))
20347 || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
20349 else
20350 return NULL_RTX;
20352 regno = REGNO (reg);
20354 /* The duality of the SPE register size wreaks all kinds of havoc.
20355 This is a way of distinguishing r0 in 32-bits from r0 in
20356 64-bits. */
20357 return
20358 gen_rtx_PARALLEL (VOIDmode,
20359 BYTES_BIG_ENDIAN
20360 ? gen_rtvec (2,
20361 gen_rtx_REG (SImode, regno + 1200),
20362 gen_rtx_REG (SImode, regno))
20363 : gen_rtvec (2,
20364 gen_rtx_REG (SImode, regno),
20365 gen_rtx_REG (SImode, regno + 1200)));
20368 /* Map internal gcc register numbers to DWARF2 register numbers. */
20370 unsigned int
20371 rs6000_dbx_register_number (unsigned int regno)
20373 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
20374 return regno;
20375 if (regno == MQ_REGNO)
20376 return 100;
20377 if (regno == LINK_REGISTER_REGNUM)
20378 return 108;
20379 if (regno == COUNT_REGISTER_REGNUM)
20380 return 109;
20381 if (CR_REGNO_P (regno))
20382 return regno - CR0_REGNO + 86;
20383 if (regno == XER_REGNO)
20384 return 101;
20385 if (ALTIVEC_REGNO_P (regno))
20386 return regno - FIRST_ALTIVEC_REGNO + 1124;
20387 if (regno == VRSAVE_REGNO)
20388 return 356;
20389 if (regno == VSCR_REGNO)
20390 return 67;
20391 if (regno == SPE_ACC_REGNO)
20392 return 99;
20393 if (regno == SPEFSCR_REGNO)
20394 return 612;
20395 /* SPE high reg number. We get these values of regno from
20396 rs6000_dwarf_register_span. */
20397 gcc_assert (regno >= 1200 && regno < 1232);
20398 return regno;
20401 /* target hook eh_return_filter_mode */
20402 static enum machine_mode
20403 rs6000_eh_return_filter_mode (void)
20405 return TARGET_32BIT ? SImode : word_mode;
20408 /* Target hook for scalar_mode_supported_p. */
20409 static bool
20410 rs6000_scalar_mode_supported_p (enum machine_mode mode)
20412 if (DECIMAL_FLOAT_MODE_P (mode))
20413 return true;
20414 else
20415 return default_scalar_mode_supported_p (mode);
20418 /* Target hook for vector_mode_supported_p. */
20419 static bool
20420 rs6000_vector_mode_supported_p (enum machine_mode mode)
20423 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
20424 return true;
20426 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
20427 return true;
20429 else
20430 return false;
20433 /* Target hook for invalid_arg_for_unprototyped_fn. */
20434 static const char *
20435 invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
20437 return (!rs6000_darwin64_abi
20438 && typelist == 0
20439 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
20440 && (funcdecl == NULL_TREE
20441 || (TREE_CODE (funcdecl) == FUNCTION_DECL
20442 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
20443 ? N_("AltiVec argument passed to unprototyped function")
20444 : NULL;
20447 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
20448 setup by using __stack_chk_fail_local hidden function instead of
20449 calling __stack_chk_fail directly. Otherwise it is better to call
20450 __stack_chk_fail directly. */
20452 static tree
20453 rs6000_stack_protect_fail (void)
20455 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
20456 ? default_hidden_stack_protect_fail ()
20457 : default_external_stack_protect_fail ();
20460 #include "gt-rs6000.h"