Makefile.in: Rebuilt.
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blobdbb1f550f9727f3e475497b473b1c79261744876
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;
1469 /* Detect invalid option combinations with E500. */
1470 CHECK_E500_OPTIONS;
1472 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
1473 && rs6000_cpu != PROCESSOR_POWER5
1474 && rs6000_cpu != PROCESSOR_POWER6
1475 && rs6000_cpu != PROCESSOR_CELL);
1476 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
1477 || rs6000_cpu == PROCESSOR_POWER5);
1478 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
1479 || rs6000_cpu == PROCESSOR_POWER5
1480 || rs6000_cpu == PROCESSOR_POWER6);
1482 rs6000_sched_restricted_insns_priority
1483 = (rs6000_sched_groups ? 1 : 0);
1485 /* Handle -msched-costly-dep option. */
1486 rs6000_sched_costly_dep
1487 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
1489 if (rs6000_sched_costly_dep_str)
1491 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
1492 rs6000_sched_costly_dep = no_dep_costly;
1493 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
1494 rs6000_sched_costly_dep = all_deps_costly;
1495 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
1496 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
1497 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
1498 rs6000_sched_costly_dep = store_to_load_dep_costly;
1499 else
1500 rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
1503 /* Handle -minsert-sched-nops option. */
1504 rs6000_sched_insert_nops
1505 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
1507 if (rs6000_sched_insert_nops_str)
1509 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
1510 rs6000_sched_insert_nops = sched_finish_none;
1511 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
1512 rs6000_sched_insert_nops = sched_finish_pad_groups;
1513 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
1514 rs6000_sched_insert_nops = sched_finish_regroup_exact;
1515 else
1516 rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
1519 #ifdef TARGET_REGNAMES
1520 /* If the user desires alternate register names, copy in the
1521 alternate names now. */
1522 if (TARGET_REGNAMES)
1523 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
1524 #endif
1526 /* Set aix_struct_return last, after the ABI is determined.
1527 If -maix-struct-return or -msvr4-struct-return was explicitly
1528 used, don't override with the ABI default. */
1529 if (!rs6000_explicit_options.aix_struct_ret)
1530 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
1532 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
1533 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
1535 if (TARGET_TOC)
1536 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
1538 /* We can only guarantee the availability of DI pseudo-ops when
1539 assembling for 64-bit targets. */
1540 if (!TARGET_64BIT)
1542 targetm.asm_out.aligned_op.di = NULL;
1543 targetm.asm_out.unaligned_op.di = NULL;
1546 /* Set branch target alignment, if not optimizing for size. */
1547 if (!optimize_size)
1549 /* Cell wants to be aligned 8byte for dual issue. */
1550 if (rs6000_cpu == PROCESSOR_CELL)
1552 if (align_functions <= 0)
1553 align_functions = 8;
1554 if (align_jumps <= 0)
1555 align_jumps = 8;
1556 if (align_loops <= 0)
1557 align_loops = 8;
1559 if (rs6000_align_branch_targets)
1561 if (align_functions <= 0)
1562 align_functions = 16;
1563 if (align_jumps <= 0)
1564 align_jumps = 16;
1565 if (align_loops <= 0)
1566 align_loops = 16;
1568 if (align_jumps_max_skip <= 0)
1569 align_jumps_max_skip = 15;
1570 if (align_loops_max_skip <= 0)
1571 align_loops_max_skip = 15;
1574 /* Arrange to save and restore machine status around nested functions. */
1575 init_machine_status = rs6000_init_machine_status;
1577 /* We should always be splitting complex arguments, but we can't break
1578 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1579 if (DEFAULT_ABI != ABI_AIX)
1580 targetm.calls.split_complex_arg = NULL;
1582 /* Initialize rs6000_cost with the appropriate target costs. */
1583 if (optimize_size)
1584 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
1585 else
1586 switch (rs6000_cpu)
1588 case PROCESSOR_RIOS1:
1589 rs6000_cost = &rios1_cost;
1590 break;
1592 case PROCESSOR_RIOS2:
1593 rs6000_cost = &rios2_cost;
1594 break;
1596 case PROCESSOR_RS64A:
1597 rs6000_cost = &rs64a_cost;
1598 break;
1600 case PROCESSOR_MPCCORE:
1601 rs6000_cost = &mpccore_cost;
1602 break;
1604 case PROCESSOR_PPC403:
1605 rs6000_cost = &ppc403_cost;
1606 break;
1608 case PROCESSOR_PPC405:
1609 rs6000_cost = &ppc405_cost;
1610 break;
1612 case PROCESSOR_PPC440:
1613 rs6000_cost = &ppc440_cost;
1614 break;
1616 case PROCESSOR_PPC601:
1617 rs6000_cost = &ppc601_cost;
1618 break;
1620 case PROCESSOR_PPC603:
1621 rs6000_cost = &ppc603_cost;
1622 break;
1624 case PROCESSOR_PPC604:
1625 rs6000_cost = &ppc604_cost;
1626 break;
1628 case PROCESSOR_PPC604e:
1629 rs6000_cost = &ppc604e_cost;
1630 break;
1632 case PROCESSOR_PPC620:
1633 rs6000_cost = &ppc620_cost;
1634 break;
1636 case PROCESSOR_PPC630:
1637 rs6000_cost = &ppc630_cost;
1638 break;
1640 case PROCESSOR_CELL:
1641 rs6000_cost = &ppccell_cost;
1642 break;
1644 case PROCESSOR_PPC750:
1645 case PROCESSOR_PPC7400:
1646 rs6000_cost = &ppc750_cost;
1647 break;
1649 case PROCESSOR_PPC7450:
1650 rs6000_cost = &ppc7450_cost;
1651 break;
1653 case PROCESSOR_PPC8540:
1654 rs6000_cost = &ppc8540_cost;
1655 break;
1657 case PROCESSOR_POWER4:
1658 case PROCESSOR_POWER5:
1659 rs6000_cost = &power4_cost;
1660 break;
1662 case PROCESSOR_POWER6:
1663 rs6000_cost = &power6_cost;
1664 break;
1666 default:
1667 gcc_unreachable ();
1671 /* Implement targetm.vectorize.builtin_mask_for_load. */
1672 static tree
1673 rs6000_builtin_mask_for_load (void)
1675 if (TARGET_ALTIVEC)
1676 return altivec_builtin_mask_for_load;
1677 else
1678 return 0;
1681 /* Implement targetm.vectorize.builtin_mul_widen_even. */
1682 static tree
1683 rs6000_builtin_mul_widen_even (tree type)
1685 if (!TARGET_ALTIVEC)
1686 return NULL_TREE;
1688 switch (TYPE_MODE (type))
1690 case V8HImode:
1691 return TYPE_UNSIGNED (type) ?
1692 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH] :
1693 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
1695 case V16QImode:
1696 return TYPE_UNSIGNED (type) ?
1697 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB] :
1698 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
1699 default:
1700 return NULL_TREE;
1704 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
1705 static tree
1706 rs6000_builtin_mul_widen_odd (tree type)
1708 if (!TARGET_ALTIVEC)
1709 return NULL_TREE;
1711 switch (TYPE_MODE (type))
1713 case V8HImode:
1714 return TYPE_UNSIGNED (type) ?
1715 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH] :
1716 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
1718 case V16QImode:
1719 return TYPE_UNSIGNED (type) ?
1720 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB] :
1721 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
1722 default:
1723 return NULL_TREE;
1727 /* Handle generic options of the form -mfoo=yes/no.
1728 NAME is the option name.
1729 VALUE is the option value.
1730 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1731 whether the option value is 'yes' or 'no' respectively. */
1732 static void
1733 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
1735 if (value == 0)
1736 return;
1737 else if (!strcmp (value, "yes"))
1738 *flag = 1;
1739 else if (!strcmp (value, "no"))
1740 *flag = 0;
1741 else
1742 error ("unknown -m%s= option specified: '%s'", name, value);
1745 /* Validate and record the size specified with the -mtls-size option. */
1747 static void
1748 rs6000_parse_tls_size_option (void)
1750 if (rs6000_tls_size_string == 0)
1751 return;
1752 else if (strcmp (rs6000_tls_size_string, "16") == 0)
1753 rs6000_tls_size = 16;
1754 else if (strcmp (rs6000_tls_size_string, "32") == 0)
1755 rs6000_tls_size = 32;
1756 else if (strcmp (rs6000_tls_size_string, "64") == 0)
1757 rs6000_tls_size = 64;
1758 else
1759 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
1762 void
1763 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1765 if (DEFAULT_ABI == ABI_DARWIN)
1766 /* The Darwin libraries never set errno, so we might as well
1767 avoid calling them when that's the only reason we would. */
1768 flag_errno_math = 0;
1770 /* Double growth factor to counter reduced min jump length. */
1771 set_param_value ("max-grow-copy-bb-insns", 16);
1773 /* Enable section anchors by default.
1774 Skip section anchors for Objective C and Objective C++
1775 until front-ends fixed. */
1776 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
1777 flag_section_anchors = 1;
1780 /* Implement TARGET_HANDLE_OPTION. */
1782 static bool
1783 rs6000_handle_option (size_t code, const char *arg, int value)
1785 switch (code)
1787 case OPT_mno_power:
1788 target_flags &= ~(MASK_POWER | MASK_POWER2
1789 | MASK_MULTIPLE | MASK_STRING);
1790 target_flags_explicit |= (MASK_POWER | MASK_POWER2
1791 | MASK_MULTIPLE | MASK_STRING);
1792 break;
1793 case OPT_mno_powerpc:
1794 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
1795 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1796 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
1797 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1798 break;
1799 case OPT_mfull_toc:
1800 target_flags &= ~MASK_MINIMAL_TOC;
1801 TARGET_NO_FP_IN_TOC = 0;
1802 TARGET_NO_SUM_IN_TOC = 0;
1803 target_flags_explicit |= MASK_MINIMAL_TOC;
1804 #ifdef TARGET_USES_SYSV4_OPT
1805 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1806 just the same as -mminimal-toc. */
1807 target_flags |= MASK_MINIMAL_TOC;
1808 target_flags_explicit |= MASK_MINIMAL_TOC;
1809 #endif
1810 break;
1812 #ifdef TARGET_USES_SYSV4_OPT
1813 case OPT_mtoc:
1814 /* Make -mtoc behave like -mminimal-toc. */
1815 target_flags |= MASK_MINIMAL_TOC;
1816 target_flags_explicit |= MASK_MINIMAL_TOC;
1817 break;
1818 #endif
1820 #ifdef TARGET_USES_AIX64_OPT
1821 case OPT_maix64:
1822 #else
1823 case OPT_m64:
1824 #endif
1825 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
1826 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
1827 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
1828 break;
1830 #ifdef TARGET_USES_AIX64_OPT
1831 case OPT_maix32:
1832 #else
1833 case OPT_m32:
1834 #endif
1835 target_flags &= ~MASK_POWERPC64;
1836 target_flags_explicit |= MASK_POWERPC64;
1837 break;
1839 case OPT_minsert_sched_nops_:
1840 rs6000_sched_insert_nops_str = arg;
1841 break;
1843 case OPT_mminimal_toc:
1844 if (value == 1)
1846 TARGET_NO_FP_IN_TOC = 0;
1847 TARGET_NO_SUM_IN_TOC = 0;
1849 break;
1851 case OPT_mpower:
1852 if (value == 1)
1854 target_flags |= (MASK_MULTIPLE | MASK_STRING);
1855 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
1857 break;
1859 case OPT_mpower2:
1860 if (value == 1)
1862 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1863 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1865 break;
1867 case OPT_mpowerpc_gpopt:
1868 case OPT_mpowerpc_gfxopt:
1869 if (value == 1)
1871 target_flags |= MASK_POWERPC;
1872 target_flags_explicit |= MASK_POWERPC;
1874 break;
1876 case OPT_maix_struct_return:
1877 case OPT_msvr4_struct_return:
1878 rs6000_explicit_options.aix_struct_ret = true;
1879 break;
1881 case OPT_mvrsave_:
1882 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
1883 break;
1885 case OPT_misel_:
1886 rs6000_explicit_options.isel = true;
1887 rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
1888 break;
1890 case OPT_mspe_:
1891 rs6000_explicit_options.spe = true;
1892 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
1893 break;
1895 case OPT_mdebug_:
1896 rs6000_debug_name = arg;
1897 break;
1899 #ifdef TARGET_USES_SYSV4_OPT
1900 case OPT_mcall_:
1901 rs6000_abi_name = arg;
1902 break;
1904 case OPT_msdata_:
1905 rs6000_sdata_name = arg;
1906 break;
1908 case OPT_mtls_size_:
1909 rs6000_tls_size_string = arg;
1910 break;
1912 case OPT_mrelocatable:
1913 if (value == 1)
1915 target_flags |= MASK_MINIMAL_TOC;
1916 target_flags_explicit |= MASK_MINIMAL_TOC;
1917 TARGET_NO_FP_IN_TOC = 1;
1919 break;
1921 case OPT_mrelocatable_lib:
1922 if (value == 1)
1924 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
1925 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
1926 TARGET_NO_FP_IN_TOC = 1;
1928 else
1930 target_flags &= ~MASK_RELOCATABLE;
1931 target_flags_explicit |= MASK_RELOCATABLE;
1933 break;
1934 #endif
1936 case OPT_mabi_:
1937 if (!strcmp (arg, "altivec"))
1939 rs6000_explicit_options.abi = true;
1940 rs6000_altivec_abi = 1;
1941 rs6000_spe_abi = 0;
1943 else if (! strcmp (arg, "no-altivec"))
1945 /* ??? Don't set rs6000_explicit_options.abi here, to allow
1946 the default for rs6000_spe_abi to be chosen later. */
1947 rs6000_altivec_abi = 0;
1949 else if (! strcmp (arg, "spe"))
1951 rs6000_explicit_options.abi = true;
1952 rs6000_spe_abi = 1;
1953 rs6000_altivec_abi = 0;
1954 if (!TARGET_SPE_ABI)
1955 error ("not configured for ABI: '%s'", arg);
1957 else if (! strcmp (arg, "no-spe"))
1959 rs6000_explicit_options.abi = true;
1960 rs6000_spe_abi = 0;
1963 /* These are here for testing during development only, do not
1964 document in the manual please. */
1965 else if (! strcmp (arg, "d64"))
1967 rs6000_darwin64_abi = 1;
1968 warning (0, "Using darwin64 ABI");
1970 else if (! strcmp (arg, "d32"))
1972 rs6000_darwin64_abi = 0;
1973 warning (0, "Using old darwin ABI");
1976 else if (! strcmp (arg, "ibmlongdouble"))
1978 rs6000_explicit_options.ieee = true;
1979 rs6000_ieeequad = 0;
1980 warning (0, "Using IBM extended precision long double");
1982 else if (! strcmp (arg, "ieeelongdouble"))
1984 rs6000_explicit_options.ieee = true;
1985 rs6000_ieeequad = 1;
1986 warning (0, "Using IEEE extended precision long double");
1989 else
1991 error ("unknown ABI specified: '%s'", arg);
1992 return false;
1994 break;
1996 case OPT_mcpu_:
1997 rs6000_select[1].string = arg;
1998 break;
2000 case OPT_mtune_:
2001 rs6000_select[2].string = arg;
2002 break;
2004 case OPT_mtraceback_:
2005 rs6000_traceback_name = arg;
2006 break;
2008 case OPT_mfloat_gprs_:
2009 rs6000_explicit_options.float_gprs = true;
2010 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
2011 rs6000_float_gprs = 1;
2012 else if (! strcmp (arg, "double"))
2013 rs6000_float_gprs = 2;
2014 else if (! strcmp (arg, "no"))
2015 rs6000_float_gprs = 0;
2016 else
2018 error ("invalid option for -mfloat-gprs: '%s'", arg);
2019 return false;
2021 break;
2023 case OPT_mlong_double_:
2024 rs6000_explicit_options.long_double = true;
2025 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2026 if (value != 64 && value != 128)
2028 error ("Unknown switch -mlong-double-%s", arg);
2029 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2030 return false;
2032 else
2033 rs6000_long_double_type_size = value;
2034 break;
2036 case OPT_msched_costly_dep_:
2037 rs6000_sched_costly_dep_str = arg;
2038 break;
2040 case OPT_malign_:
2041 rs6000_explicit_options.alignment = true;
2042 if (! strcmp (arg, "power"))
2044 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2045 some C library functions, so warn about it. The flag may be
2046 useful for performance studies from time to time though, so
2047 don't disable it entirely. */
2048 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2049 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2050 " it is incompatible with the installed C and C++ libraries");
2051 rs6000_alignment_flags = MASK_ALIGN_POWER;
2053 else if (! strcmp (arg, "natural"))
2054 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2055 else
2057 error ("unknown -malign-XXXXX option specified: '%s'", arg);
2058 return false;
2060 break;
2062 return true;
2065 /* Do anything needed at the start of the asm file. */
2067 static void
2068 rs6000_file_start (void)
2070 size_t i;
2071 char buffer[80];
2072 const char *start = buffer;
2073 struct rs6000_cpu_select *ptr;
2074 const char *default_cpu = TARGET_CPU_DEFAULT;
2075 FILE *file = asm_out_file;
2077 default_file_start ();
2079 #ifdef TARGET_BI_ARCH
2080 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
2081 default_cpu = 0;
2082 #endif
2084 if (flag_verbose_asm)
2086 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
2087 rs6000_select[0].string = default_cpu;
2089 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2091 ptr = &rs6000_select[i];
2092 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2094 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
2095 start = "";
2099 if (PPC405_ERRATUM77)
2101 fprintf (file, "%s PPC405CR_ERRATUM77", start);
2102 start = "";
2105 #ifdef USING_ELFOS_H
2106 switch (rs6000_sdata)
2108 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
2109 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
2110 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
2111 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
2114 if (rs6000_sdata && g_switch_value)
2116 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
2117 g_switch_value);
2118 start = "";
2120 #endif
2122 if (*start == '\0')
2123 putc ('\n', file);
2126 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
2128 switch_to_section (toc_section);
2129 switch_to_section (text_section);
2134 /* Return nonzero if this function is known to have a null epilogue. */
2137 direct_return (void)
2139 if (reload_completed)
2141 rs6000_stack_t *info = rs6000_stack_info ();
2143 if (info->first_gp_reg_save == 32
2144 && info->first_fp_reg_save == 64
2145 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
2146 && ! info->lr_save_p
2147 && ! info->cr_save_p
2148 && info->vrsave_mask == 0
2149 && ! info->push_p)
2150 return 1;
2153 return 0;
2156 /* Return the number of instructions it takes to form a constant in an
2157 integer register. */
2160 num_insns_constant_wide (HOST_WIDE_INT value)
2162 /* signed constant loadable with {cal|addi} */
2163 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
2164 return 1;
2166 /* constant loadable with {cau|addis} */
2167 else if ((value & 0xffff) == 0
2168 && (value >> 31 == -1 || value >> 31 == 0))
2169 return 1;
2171 #if HOST_BITS_PER_WIDE_INT == 64
2172 else if (TARGET_POWERPC64)
2174 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
2175 HOST_WIDE_INT high = value >> 31;
2177 if (high == 0 || high == -1)
2178 return 2;
2180 high >>= 1;
2182 if (low == 0)
2183 return num_insns_constant_wide (high) + 1;
2184 else
2185 return (num_insns_constant_wide (high)
2186 + num_insns_constant_wide (low) + 1);
2188 #endif
2190 else
2191 return 2;
2195 num_insns_constant (rtx op, enum machine_mode mode)
2197 HOST_WIDE_INT low, high;
2199 switch (GET_CODE (op))
2201 case CONST_INT:
2202 #if HOST_BITS_PER_WIDE_INT == 64
2203 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
2204 && mask64_operand (op, mode))
2205 return 2;
2206 else
2207 #endif
2208 return num_insns_constant_wide (INTVAL (op));
2210 case CONST_DOUBLE:
2211 if (mode == SFmode)
2213 long l;
2214 REAL_VALUE_TYPE rv;
2216 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2217 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
2218 return num_insns_constant_wide ((HOST_WIDE_INT) l);
2221 if (mode == VOIDmode || mode == DImode)
2223 high = CONST_DOUBLE_HIGH (op);
2224 low = CONST_DOUBLE_LOW (op);
2226 else
2228 long l[2];
2229 REAL_VALUE_TYPE rv;
2231 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2232 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
2233 high = l[WORDS_BIG_ENDIAN == 0];
2234 low = l[WORDS_BIG_ENDIAN != 0];
2237 if (TARGET_32BIT)
2238 return (num_insns_constant_wide (low)
2239 + num_insns_constant_wide (high));
2240 else
2242 if ((high == 0 && low >= 0)
2243 || (high == -1 && low < 0))
2244 return num_insns_constant_wide (low);
2246 else if (mask64_operand (op, mode))
2247 return 2;
2249 else if (low == 0)
2250 return num_insns_constant_wide (high) + 1;
2252 else
2253 return (num_insns_constant_wide (high)
2254 + num_insns_constant_wide (low) + 1);
2257 default:
2258 gcc_unreachable ();
2262 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2263 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2264 corresponding element of the vector, but for V4SFmode and V2SFmode,
2265 the corresponding "float" is interpreted as an SImode integer. */
2267 static HOST_WIDE_INT
2268 const_vector_elt_as_int (rtx op, unsigned int elt)
2270 rtx tmp = CONST_VECTOR_ELT (op, elt);
2271 if (GET_MODE (op) == V4SFmode
2272 || GET_MODE (op) == V2SFmode)
2273 tmp = gen_lowpart (SImode, tmp);
2274 return INTVAL (tmp);
2277 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2278 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2279 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2280 all items are set to the same value and contain COPIES replicas of the
2281 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2282 operand and the others are set to the value of the operand's msb. */
2284 static bool
2285 vspltis_constant (rtx op, unsigned step, unsigned copies)
2287 enum machine_mode mode = GET_MODE (op);
2288 enum machine_mode inner = GET_MODE_INNER (mode);
2290 unsigned i;
2291 unsigned nunits = GET_MODE_NUNITS (mode);
2292 unsigned bitsize = GET_MODE_BITSIZE (inner);
2293 unsigned mask = GET_MODE_MASK (inner);
2295 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
2296 HOST_WIDE_INT splat_val = val;
2297 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
2299 /* Construct the value to be splatted, if possible. If not, return 0. */
2300 for (i = 2; i <= copies; i *= 2)
2302 HOST_WIDE_INT small_val;
2303 bitsize /= 2;
2304 small_val = splat_val >> bitsize;
2305 mask >>= bitsize;
2306 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
2307 return false;
2308 splat_val = small_val;
2311 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2312 if (EASY_VECTOR_15 (splat_val))
2315 /* Also check if we can splat, and then add the result to itself. Do so if
2316 the value is positive, of if the splat instruction is using OP's mode;
2317 for splat_val < 0, the splat and the add should use the same mode. */
2318 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
2319 && (splat_val >= 0 || (step == 1 && copies == 1)))
2322 else
2323 return false;
2325 /* Check if VAL is present in every STEP-th element, and the
2326 other elements are filled with its most significant bit. */
2327 for (i = 0; i < nunits - 1; ++i)
2329 HOST_WIDE_INT desired_val;
2330 if (((i + 1) & (step - 1)) == 0)
2331 desired_val = val;
2332 else
2333 desired_val = msb_val;
2335 if (desired_val != const_vector_elt_as_int (op, i))
2336 return false;
2339 return true;
2343 /* Return true if OP is of the given MODE and can be synthesized
2344 with a vspltisb, vspltish or vspltisw. */
2346 bool
2347 easy_altivec_constant (rtx op, enum machine_mode mode)
2349 unsigned step, copies;
2351 if (mode == VOIDmode)
2352 mode = GET_MODE (op);
2353 else if (mode != GET_MODE (op))
2354 return false;
2356 /* Start with a vspltisw. */
2357 step = GET_MODE_NUNITS (mode) / 4;
2358 copies = 1;
2360 if (vspltis_constant (op, step, copies))
2361 return true;
2363 /* Then try with a vspltish. */
2364 if (step == 1)
2365 copies <<= 1;
2366 else
2367 step >>= 1;
2369 if (vspltis_constant (op, step, copies))
2370 return true;
2372 /* And finally a vspltisb. */
2373 if (step == 1)
2374 copies <<= 1;
2375 else
2376 step >>= 1;
2378 if (vspltis_constant (op, step, copies))
2379 return true;
2381 return false;
2384 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2385 result is OP. Abort if it is not possible. */
2388 gen_easy_altivec_constant (rtx op)
2390 enum machine_mode mode = GET_MODE (op);
2391 int nunits = GET_MODE_NUNITS (mode);
2392 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
2393 unsigned step = nunits / 4;
2394 unsigned copies = 1;
2396 /* Start with a vspltisw. */
2397 if (vspltis_constant (op, step, copies))
2398 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
2400 /* Then try with a vspltish. */
2401 if (step == 1)
2402 copies <<= 1;
2403 else
2404 step >>= 1;
2406 if (vspltis_constant (op, step, copies))
2407 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
2409 /* And finally a vspltisb. */
2410 if (step == 1)
2411 copies <<= 1;
2412 else
2413 step >>= 1;
2415 if (vspltis_constant (op, step, copies))
2416 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
2418 gcc_unreachable ();
2421 const char *
2422 output_vec_const_move (rtx *operands)
2424 int cst, cst2;
2425 enum machine_mode mode;
2426 rtx dest, vec;
2428 dest = operands[0];
2429 vec = operands[1];
2430 mode = GET_MODE (dest);
2432 if (TARGET_ALTIVEC)
2434 rtx splat_vec;
2435 if (zero_constant (vec, mode))
2436 return "vxor %0,%0,%0";
2438 splat_vec = gen_easy_altivec_constant (vec);
2439 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
2440 operands[1] = XEXP (splat_vec, 0);
2441 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
2442 return "#";
2444 switch (GET_MODE (splat_vec))
2446 case V4SImode:
2447 return "vspltisw %0,%1";
2449 case V8HImode:
2450 return "vspltish %0,%1";
2452 case V16QImode:
2453 return "vspltisb %0,%1";
2455 default:
2456 gcc_unreachable ();
2460 gcc_assert (TARGET_SPE);
2462 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2463 pattern of V1DI, V4HI, and V2SF.
2465 FIXME: We should probably return # and add post reload
2466 splitters for these, but this way is so easy ;-). */
2467 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
2468 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
2469 operands[1] = CONST_VECTOR_ELT (vec, 0);
2470 operands[2] = CONST_VECTOR_ELT (vec, 1);
2471 if (cst == cst2)
2472 return "li %0,%1\n\tevmergelo %0,%0,%0";
2473 else
2474 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2477 /* Initialize vector TARGET to VALS. */
2479 void
2480 rs6000_expand_vector_init (rtx target, rtx vals)
2482 enum machine_mode mode = GET_MODE (target);
2483 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2484 int n_elts = GET_MODE_NUNITS (mode);
2485 int n_var = 0, one_var = -1;
2486 bool all_same = true, all_const_zero = true;
2487 rtx x, mem;
2488 int i;
2490 for (i = 0; i < n_elts; ++i)
2492 x = XVECEXP (vals, 0, i);
2493 if (!CONSTANT_P (x))
2494 ++n_var, one_var = i;
2495 else if (x != CONST0_RTX (inner_mode))
2496 all_const_zero = false;
2498 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
2499 all_same = false;
2502 if (n_var == 0)
2504 if (mode != V4SFmode && all_const_zero)
2506 /* Zero register. */
2507 emit_insn (gen_rtx_SET (VOIDmode, target,
2508 gen_rtx_XOR (mode, target, target)));
2509 return;
2511 else if (mode != V4SFmode && easy_vector_constant (vals, mode))
2513 /* Splat immediate. */
2514 emit_insn (gen_rtx_SET (VOIDmode, target, vals));
2515 return;
2517 else if (all_same)
2518 ; /* Splat vector element. */
2519 else
2521 /* Load from constant pool. */
2522 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
2523 return;
2527 /* Store value to stack temp. Load vector element. Splat. */
2528 if (all_same)
2530 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2531 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
2532 XVECEXP (vals, 0, 0));
2533 x = gen_rtx_UNSPEC (VOIDmode,
2534 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2535 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2536 gen_rtvec (2,
2537 gen_rtx_SET (VOIDmode,
2538 target, mem),
2539 x)));
2540 x = gen_rtx_VEC_SELECT (inner_mode, target,
2541 gen_rtx_PARALLEL (VOIDmode,
2542 gen_rtvec (1, const0_rtx)));
2543 emit_insn (gen_rtx_SET (VOIDmode, target,
2544 gen_rtx_VEC_DUPLICATE (mode, x)));
2545 return;
2548 /* One field is non-constant. Load constant then overwrite
2549 varying field. */
2550 if (n_var == 1)
2552 rtx copy = copy_rtx (vals);
2554 /* Load constant part of vector, substitute neighboring value for
2555 varying element. */
2556 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
2557 rs6000_expand_vector_init (target, copy);
2559 /* Insert variable. */
2560 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
2561 return;
2564 /* Construct the vector in memory one field at a time
2565 and load the whole vector. */
2566 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2567 for (i = 0; i < n_elts; i++)
2568 emit_move_insn (adjust_address_nv (mem, inner_mode,
2569 i * GET_MODE_SIZE (inner_mode)),
2570 XVECEXP (vals, 0, i));
2571 emit_move_insn (target, mem);
2574 /* Set field ELT of TARGET to VAL. */
2576 void
2577 rs6000_expand_vector_set (rtx target, rtx val, int elt)
2579 enum machine_mode mode = GET_MODE (target);
2580 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2581 rtx reg = gen_reg_rtx (mode);
2582 rtx mask, mem, x;
2583 int width = GET_MODE_SIZE (inner_mode);
2584 int i;
2586 /* Load single variable value. */
2587 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2588 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
2589 x = gen_rtx_UNSPEC (VOIDmode,
2590 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2591 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2592 gen_rtvec (2,
2593 gen_rtx_SET (VOIDmode,
2594 reg, mem),
2595 x)));
2597 /* Linear sequence. */
2598 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
2599 for (i = 0; i < 16; ++i)
2600 XVECEXP (mask, 0, i) = GEN_INT (i);
2602 /* Set permute mask to insert element into target. */
2603 for (i = 0; i < width; ++i)
2604 XVECEXP (mask, 0, elt*width + i)
2605 = GEN_INT (i + 0x10);
2606 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
2607 x = gen_rtx_UNSPEC (mode,
2608 gen_rtvec (3, target, reg,
2609 force_reg (V16QImode, x)),
2610 UNSPEC_VPERM);
2611 emit_insn (gen_rtx_SET (VOIDmode, target, x));
2614 /* Extract field ELT from VEC into TARGET. */
2616 void
2617 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
2619 enum machine_mode mode = GET_MODE (vec);
2620 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2621 rtx mem, x;
2623 /* Allocate mode-sized buffer. */
2624 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2626 /* Add offset to field within buffer matching vector element. */
2627 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
2629 /* Store single field into mode-sized buffer. */
2630 x = gen_rtx_UNSPEC (VOIDmode,
2631 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
2632 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2633 gen_rtvec (2,
2634 gen_rtx_SET (VOIDmode,
2635 mem, vec),
2636 x)));
2637 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
2640 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2641 implement ANDing by the mask IN. */
2642 void
2643 build_mask64_2_operands (rtx in, rtx *out)
2645 #if HOST_BITS_PER_WIDE_INT >= 64
2646 unsigned HOST_WIDE_INT c, lsb, m1, m2;
2647 int shift;
2649 gcc_assert (GET_CODE (in) == CONST_INT);
2651 c = INTVAL (in);
2652 if (c & 1)
2654 /* Assume c initially something like 0x00fff000000fffff. The idea
2655 is to rotate the word so that the middle ^^^^^^ group of zeros
2656 is at the MS end and can be cleared with an rldicl mask. We then
2657 rotate back and clear off the MS ^^ group of zeros with a
2658 second rldicl. */
2659 c = ~c; /* c == 0xff000ffffff00000 */
2660 lsb = c & -c; /* lsb == 0x0000000000100000 */
2661 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
2662 c = ~c; /* c == 0x00fff000000fffff */
2663 c &= -lsb; /* c == 0x00fff00000000000 */
2664 lsb = c & -c; /* lsb == 0x0000100000000000 */
2665 c = ~c; /* c == 0xff000fffffffffff */
2666 c &= -lsb; /* c == 0xff00000000000000 */
2667 shift = 0;
2668 while ((lsb >>= 1) != 0)
2669 shift++; /* shift == 44 on exit from loop */
2670 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
2671 m1 = ~m1; /* m1 == 0x000000ffffffffff */
2672 m2 = ~c; /* m2 == 0x00ffffffffffffff */
2674 else
2676 /* Assume c initially something like 0xff000f0000000000. The idea
2677 is to rotate the word so that the ^^^ middle group of zeros
2678 is at the LS end and can be cleared with an rldicr mask. We then
2679 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2680 a second rldicr. */
2681 lsb = c & -c; /* lsb == 0x0000010000000000 */
2682 m2 = -lsb; /* m2 == 0xffffff0000000000 */
2683 c = ~c; /* c == 0x00fff0ffffffffff */
2684 c &= -lsb; /* c == 0x00fff00000000000 */
2685 lsb = c & -c; /* lsb == 0x0000100000000000 */
2686 c = ~c; /* c == 0xff000fffffffffff */
2687 c &= -lsb; /* c == 0xff00000000000000 */
2688 shift = 0;
2689 while ((lsb >>= 1) != 0)
2690 shift++; /* shift == 44 on exit from loop */
2691 m1 = ~c; /* m1 == 0x00ffffffffffffff */
2692 m1 >>= shift; /* m1 == 0x0000000000000fff */
2693 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
2696 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2697 masks will be all 1's. We are guaranteed more than one transition. */
2698 out[0] = GEN_INT (64 - shift);
2699 out[1] = GEN_INT (m1);
2700 out[2] = GEN_INT (shift);
2701 out[3] = GEN_INT (m2);
2702 #else
2703 (void)in;
2704 (void)out;
2705 gcc_unreachable ();
2706 #endif
2709 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2711 bool
2712 invalid_e500_subreg (rtx op, enum machine_mode mode)
2714 if (TARGET_E500_DOUBLE)
2716 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
2717 subreg:TI and reg:TF. */
2718 if (GET_CODE (op) == SUBREG
2719 && (mode == SImode || mode == DImode || mode == TImode)
2720 && REG_P (SUBREG_REG (op))
2721 && (GET_MODE (SUBREG_REG (op)) == DFmode
2722 || GET_MODE (SUBREG_REG (op)) == TFmode))
2723 return true;
2725 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
2726 reg:TI. */
2727 if (GET_CODE (op) == SUBREG
2728 && (mode == DFmode || mode == TFmode)
2729 && REG_P (SUBREG_REG (op))
2730 && (GET_MODE (SUBREG_REG (op)) == DImode
2731 || GET_MODE (SUBREG_REG (op)) == TImode))
2732 return true;
2735 if (TARGET_SPE
2736 && GET_CODE (op) == SUBREG
2737 && mode == SImode
2738 && REG_P (SUBREG_REG (op))
2739 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
2740 return true;
2742 return false;
2745 /* AIX increases natural record alignment to doubleword if the first
2746 field is an FP double while the FP fields remain word aligned. */
2748 unsigned int
2749 rs6000_special_round_type_align (tree type, unsigned int computed,
2750 unsigned int specified)
2752 unsigned int align = MAX (computed, specified);
2753 tree field = TYPE_FIELDS (type);
2755 /* Skip all non field decls */
2756 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
2757 field = TREE_CHAIN (field);
2759 if (field != NULL && field != type)
2761 type = TREE_TYPE (field);
2762 while (TREE_CODE (type) == ARRAY_TYPE)
2763 type = TREE_TYPE (type);
2765 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
2766 align = MAX (align, 64);
2769 return align;
2772 /* Darwin increases record alignment to the natural alignment of
2773 the first field. */
2775 unsigned int
2776 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
2777 unsigned int specified)
2779 unsigned int align = MAX (computed, specified);
2781 if (TYPE_PACKED (type))
2782 return align;
2784 /* Find the first field, looking down into aggregates. */
2785 do {
2786 tree field = TYPE_FIELDS (type);
2787 /* Skip all non field decls */
2788 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
2789 field = TREE_CHAIN (field);
2790 if (! field)
2791 break;
2792 type = TREE_TYPE (field);
2793 while (TREE_CODE (type) == ARRAY_TYPE)
2794 type = TREE_TYPE (type);
2795 } while (AGGREGATE_TYPE_P (type));
2797 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
2798 align = MAX (align, TYPE_ALIGN (type));
2800 return align;
2803 /* Return 1 for an operand in small memory on V.4/eabi. */
2806 small_data_operand (rtx op ATTRIBUTE_UNUSED,
2807 enum machine_mode mode ATTRIBUTE_UNUSED)
2809 #if TARGET_ELF
2810 rtx sym_ref;
2812 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
2813 return 0;
2815 if (DEFAULT_ABI != ABI_V4)
2816 return 0;
2818 if (GET_CODE (op) == SYMBOL_REF)
2819 sym_ref = op;
2821 else if (GET_CODE (op) != CONST
2822 || GET_CODE (XEXP (op, 0)) != PLUS
2823 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2824 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
2825 return 0;
2827 else
2829 rtx sum = XEXP (op, 0);
2830 HOST_WIDE_INT summand;
2832 /* We have to be careful here, because it is the referenced address
2833 that must be 32k from _SDA_BASE_, not just the symbol. */
2834 summand = INTVAL (XEXP (sum, 1));
2835 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
2836 return 0;
2838 sym_ref = XEXP (sum, 0);
2841 return SYMBOL_REF_SMALL_P (sym_ref);
2842 #else
2843 return 0;
2844 #endif
2847 /* Return true if either operand is a general purpose register. */
2849 bool
2850 gpr_or_gpr_p (rtx op0, rtx op1)
2852 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
2853 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
2857 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2859 static int
2860 constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
2862 switch (GET_CODE (op))
2864 case SYMBOL_REF:
2865 if (RS6000_SYMBOL_REF_TLS_P (op))
2866 return 0;
2867 else if (CONSTANT_POOL_ADDRESS_P (op))
2869 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2871 *have_sym = 1;
2872 return 1;
2874 else
2875 return 0;
2877 else if (! strcmp (XSTR (op, 0), toc_label_name))
2879 *have_toc = 1;
2880 return 1;
2882 else
2883 return 0;
2884 case PLUS:
2885 case MINUS:
2886 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2887 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
2888 case CONST:
2889 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
2890 case CONST_INT:
2891 return 1;
2892 default:
2893 return 0;
2897 static bool
2898 constant_pool_expr_p (rtx op)
2900 int have_sym = 0;
2901 int have_toc = 0;
2902 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2905 bool
2906 toc_relative_expr_p (rtx op)
2908 int have_sym = 0;
2909 int have_toc = 0;
2910 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2913 bool
2914 legitimate_constant_pool_address_p (rtx x)
2916 return (TARGET_TOC
2917 && GET_CODE (x) == PLUS
2918 && GET_CODE (XEXP (x, 0)) == REG
2919 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
2920 && constant_pool_expr_p (XEXP (x, 1)));
2923 static bool
2924 legitimate_small_data_p (enum machine_mode mode, rtx x)
2926 return (DEFAULT_ABI == ABI_V4
2927 && !flag_pic && !TARGET_TOC
2928 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
2929 && small_data_operand (x, mode));
2932 /* SPE offset addressing is limited to 5-bits worth of double words. */
2933 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2935 bool
2936 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
2938 unsigned HOST_WIDE_INT offset, extra;
2940 if (GET_CODE (x) != PLUS)
2941 return false;
2942 if (GET_CODE (XEXP (x, 0)) != REG)
2943 return false;
2944 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2945 return false;
2946 if (legitimate_constant_pool_address_p (x))
2947 return true;
2948 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2949 return false;
2951 offset = INTVAL (XEXP (x, 1));
2952 extra = 0;
2953 switch (mode)
2955 case V16QImode:
2956 case V8HImode:
2957 case V4SFmode:
2958 case V4SImode:
2959 /* AltiVec vector modes. Only reg+reg addressing is valid and
2960 constant offset zero should not occur due to canonicalization.
2961 Allow any offset when not strict before reload. */
2962 return !strict;
2964 case V4HImode:
2965 case V2SImode:
2966 case V1DImode:
2967 case V2SFmode:
2968 /* SPE vector modes. */
2969 return SPE_CONST_OFFSET_OK (offset);
2971 case DFmode:
2972 if (TARGET_E500_DOUBLE)
2973 return SPE_CONST_OFFSET_OK (offset);
2975 case DImode:
2976 /* On e500v2, we may have:
2978 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
2980 Which gets addressed with evldd instructions. */
2981 if (TARGET_E500_DOUBLE)
2982 return SPE_CONST_OFFSET_OK (offset);
2984 if (mode == DFmode || !TARGET_POWERPC64)
2985 extra = 4;
2986 else if (offset & 3)
2987 return false;
2988 break;
2990 case TFmode:
2991 if (TARGET_E500_DOUBLE)
2992 return (SPE_CONST_OFFSET_OK (offset)
2993 && SPE_CONST_OFFSET_OK (offset + 8));
2995 case TImode:
2996 if (mode == TFmode || !TARGET_POWERPC64)
2997 extra = 12;
2998 else if (offset & 3)
2999 return false;
3000 else
3001 extra = 8;
3002 break;
3004 default:
3005 break;
3008 offset += 0x8000;
3009 return (offset < 0x10000) && (offset + extra < 0x10000);
3012 static bool
3013 legitimate_indexed_address_p (rtx x, int strict)
3015 rtx op0, op1;
3017 if (GET_CODE (x) != PLUS)
3018 return false;
3020 op0 = XEXP (x, 0);
3021 op1 = XEXP (x, 1);
3023 /* Recognize the rtl generated by reload which we know will later be
3024 replaced with proper base and index regs. */
3025 if (!strict
3026 && reload_in_progress
3027 && (REG_P (op0) || GET_CODE (op0) == PLUS)
3028 && REG_P (op1))
3029 return true;
3031 return (REG_P (op0) && REG_P (op1)
3032 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
3033 && INT_REG_OK_FOR_INDEX_P (op1, strict))
3034 || (INT_REG_OK_FOR_BASE_P (op1, strict)
3035 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
3038 inline bool
3039 legitimate_indirect_address_p (rtx x, int strict)
3041 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
3044 bool
3045 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
3047 if (!TARGET_MACHO || !flag_pic
3048 || mode != SImode || GET_CODE (x) != MEM)
3049 return false;
3050 x = XEXP (x, 0);
3052 if (GET_CODE (x) != LO_SUM)
3053 return false;
3054 if (GET_CODE (XEXP (x, 0)) != REG)
3055 return false;
3056 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
3057 return false;
3058 x = XEXP (x, 1);
3060 return CONSTANT_P (x);
3063 static bool
3064 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
3066 if (GET_CODE (x) != LO_SUM)
3067 return false;
3068 if (GET_CODE (XEXP (x, 0)) != REG)
3069 return false;
3070 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
3071 return false;
3072 /* Restrict addressing for DI because of our SUBREG hackery. */
3073 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3074 || mode == DImode))
3075 return false;
3076 x = XEXP (x, 1);
3078 if (TARGET_ELF || TARGET_MACHO)
3080 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
3081 return false;
3082 if (TARGET_TOC)
3083 return false;
3084 if (GET_MODE_NUNITS (mode) != 1)
3085 return false;
3086 if (GET_MODE_BITSIZE (mode) > 64
3087 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
3088 && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode)))
3089 return false;
3091 return CONSTANT_P (x);
3094 return false;
3098 /* Try machine-dependent ways of modifying an illegitimate address
3099 to be legitimate. If we find one, return the new, valid address.
3100 This is used from only one place: `memory_address' in explow.c.
3102 OLDX is the address as it was before break_out_memory_refs was
3103 called. In some cases it is useful to look at this to decide what
3104 needs to be done.
3106 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3108 It is always safe for this function to do nothing. It exists to
3109 recognize opportunities to optimize the output.
3111 On RS/6000, first check for the sum of a register with a constant
3112 integer that is out of range. If so, generate code to add the
3113 constant with the low-order 16 bits masked to the register and force
3114 this result into another register (this can be done with `cau').
3115 Then generate an address of REG+(CONST&0xffff), allowing for the
3116 possibility of bit 16 being a one.
3118 Then check for the sum of a register and something not constant, try to
3119 load the other things into a register and return the sum. */
3122 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3123 enum machine_mode mode)
3125 if (GET_CODE (x) == SYMBOL_REF)
3127 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
3128 if (model != 0)
3129 return rs6000_legitimize_tls_address (x, model);
3132 if (GET_CODE (x) == PLUS
3133 && GET_CODE (XEXP (x, 0)) == REG
3134 && GET_CODE (XEXP (x, 1)) == CONST_INT
3135 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
3137 HOST_WIDE_INT high_int, low_int;
3138 rtx sum;
3139 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3140 high_int = INTVAL (XEXP (x, 1)) - low_int;
3141 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
3142 GEN_INT (high_int)), 0);
3143 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
3145 else if (GET_CODE (x) == PLUS
3146 && GET_CODE (XEXP (x, 0)) == REG
3147 && GET_CODE (XEXP (x, 1)) != CONST_INT
3148 && GET_MODE_NUNITS (mode) == 1
3149 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3150 || TARGET_POWERPC64
3151 || (((mode != DImode && mode != DFmode) || TARGET_E500_DOUBLE)
3152 && mode != TFmode))
3153 && (TARGET_POWERPC64 || mode != DImode)
3154 && mode != TImode)
3156 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
3157 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
3159 else if (ALTIVEC_VECTOR_MODE (mode))
3161 rtx reg;
3163 /* Make sure both operands are registers. */
3164 if (GET_CODE (x) == PLUS)
3165 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
3166 force_reg (Pmode, XEXP (x, 1)));
3168 reg = force_reg (Pmode, x);
3169 return reg;
3171 else if (SPE_VECTOR_MODE (mode)
3172 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3173 || mode == DImode)))
3175 if (mode == DImode)
3176 return NULL_RTX;
3177 /* We accept [reg + reg] and [reg + OFFSET]. */
3179 if (GET_CODE (x) == PLUS)
3181 rtx op1 = XEXP (x, 0);
3182 rtx op2 = XEXP (x, 1);
3184 op1 = force_reg (Pmode, op1);
3186 if (GET_CODE (op2) != REG
3187 && (GET_CODE (op2) != CONST_INT
3188 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
3189 op2 = force_reg (Pmode, op2);
3191 return gen_rtx_PLUS (Pmode, op1, op2);
3194 return force_reg (Pmode, x);
3196 else if (TARGET_ELF
3197 && TARGET_32BIT
3198 && TARGET_NO_TOC
3199 && ! flag_pic
3200 && GET_CODE (x) != CONST_INT
3201 && GET_CODE (x) != CONST_DOUBLE
3202 && CONSTANT_P (x)
3203 && GET_MODE_NUNITS (mode) == 1
3204 && (GET_MODE_BITSIZE (mode) <= 32
3205 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
3207 rtx reg = gen_reg_rtx (Pmode);
3208 emit_insn (gen_elf_high (reg, x));
3209 return gen_rtx_LO_SUM (Pmode, reg, x);
3211 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
3212 && ! flag_pic
3213 #if TARGET_MACHO
3214 && ! MACHO_DYNAMIC_NO_PIC_P
3215 #endif
3216 && GET_CODE (x) != CONST_INT
3217 && GET_CODE (x) != CONST_DOUBLE
3218 && CONSTANT_P (x)
3219 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
3220 && mode != DImode
3221 && mode != TImode)
3223 rtx reg = gen_reg_rtx (Pmode);
3224 emit_insn (gen_macho_high (reg, x));
3225 return gen_rtx_LO_SUM (Pmode, reg, x);
3227 else if (TARGET_TOC
3228 && constant_pool_expr_p (x)
3229 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
3231 return create_TOC_reference (x);
3233 else
3234 return NULL_RTX;
3237 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3238 We need to emit DTP-relative relocations. */
3240 static void
3241 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
3243 switch (size)
3245 case 4:
3246 fputs ("\t.long\t", file);
3247 break;
3248 case 8:
3249 fputs (DOUBLE_INT_ASM_OP, file);
3250 break;
3251 default:
3252 gcc_unreachable ();
3254 output_addr_const (file, x);
3255 fputs ("@dtprel+0x8000", file);
3258 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3260 static GTY(()) rtx rs6000_tls_symbol;
3261 static rtx
3262 rs6000_tls_get_addr (void)
3264 if (!rs6000_tls_symbol)
3265 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
3267 return rs6000_tls_symbol;
3270 /* Construct the SYMBOL_REF for TLS GOT references. */
3272 static GTY(()) rtx rs6000_got_symbol;
3273 static rtx
3274 rs6000_got_sym (void)
3276 if (!rs6000_got_symbol)
3278 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
3279 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
3280 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
3283 return rs6000_got_symbol;
3286 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3287 this (thread-local) address. */
3289 static rtx
3290 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
3292 rtx dest, insn;
3294 dest = gen_reg_rtx (Pmode);
3295 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
3297 rtx tlsreg;
3299 if (TARGET_64BIT)
3301 tlsreg = gen_rtx_REG (Pmode, 13);
3302 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
3304 else
3306 tlsreg = gen_rtx_REG (Pmode, 2);
3307 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
3309 emit_insn (insn);
3311 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
3313 rtx tlsreg, tmp;
3315 tmp = gen_reg_rtx (Pmode);
3316 if (TARGET_64BIT)
3318 tlsreg = gen_rtx_REG (Pmode, 13);
3319 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
3321 else
3323 tlsreg = gen_rtx_REG (Pmode, 2);
3324 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
3326 emit_insn (insn);
3327 if (TARGET_64BIT)
3328 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
3329 else
3330 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
3331 emit_insn (insn);
3333 else
3335 rtx r3, got, tga, tmp1, tmp2, eqv;
3337 /* We currently use relocations like @got@tlsgd for tls, which
3338 means the linker will handle allocation of tls entries, placing
3339 them in the .got section. So use a pointer to the .got section,
3340 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3341 or to secondary GOT sections used by 32-bit -fPIC. */
3342 if (TARGET_64BIT)
3343 got = gen_rtx_REG (Pmode, 2);
3344 else
3346 if (flag_pic == 1)
3347 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
3348 else
3350 rtx gsym = rs6000_got_sym ();
3351 got = gen_reg_rtx (Pmode);
3352 if (flag_pic == 0)
3353 rs6000_emit_move (got, gsym, Pmode);
3354 else
3356 rtx tempLR, tmp3, mem;
3357 rtx first, last;
3359 tempLR = gen_reg_rtx (Pmode);
3360 tmp1 = gen_reg_rtx (Pmode);
3361 tmp2 = gen_reg_rtx (Pmode);
3362 tmp3 = gen_reg_rtx (Pmode);
3363 mem = gen_const_mem (Pmode, tmp1);
3365 first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, gsym));
3366 emit_move_insn (tmp1, tempLR);
3367 emit_move_insn (tmp2, mem);
3368 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
3369 last = emit_move_insn (got, tmp3);
3370 set_unique_reg_note (last, REG_EQUAL, gsym);
3371 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3372 REG_NOTES (first));
3373 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3374 REG_NOTES (last));
3379 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
3381 r3 = gen_rtx_REG (Pmode, 3);
3382 if (TARGET_64BIT)
3383 insn = gen_tls_gd_64 (r3, got, addr);
3384 else
3385 insn = gen_tls_gd_32 (r3, got, addr);
3386 start_sequence ();
3387 emit_insn (insn);
3388 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3389 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3390 insn = emit_call_insn (insn);
3391 CONST_OR_PURE_CALL_P (insn) = 1;
3392 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3393 insn = get_insns ();
3394 end_sequence ();
3395 emit_libcall_block (insn, dest, r3, addr);
3397 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3399 r3 = gen_rtx_REG (Pmode, 3);
3400 if (TARGET_64BIT)
3401 insn = gen_tls_ld_64 (r3, got);
3402 else
3403 insn = gen_tls_ld_32 (r3, got);
3404 start_sequence ();
3405 emit_insn (insn);
3406 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3407 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3408 insn = emit_call_insn (insn);
3409 CONST_OR_PURE_CALL_P (insn) = 1;
3410 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3411 insn = get_insns ();
3412 end_sequence ();
3413 tmp1 = gen_reg_rtx (Pmode);
3414 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3415 UNSPEC_TLSLD);
3416 emit_libcall_block (insn, tmp1, r3, eqv);
3417 if (rs6000_tls_size == 16)
3419 if (TARGET_64BIT)
3420 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3421 else
3422 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3424 else if (rs6000_tls_size == 32)
3426 tmp2 = gen_reg_rtx (Pmode);
3427 if (TARGET_64BIT)
3428 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3429 else
3430 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3431 emit_insn (insn);
3432 if (TARGET_64BIT)
3433 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3434 else
3435 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3437 else
3439 tmp2 = gen_reg_rtx (Pmode);
3440 if (TARGET_64BIT)
3441 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3442 else
3443 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3444 emit_insn (insn);
3445 insn = gen_rtx_SET (Pmode, dest,
3446 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3448 emit_insn (insn);
3450 else
3452 /* IE, or 64 bit offset LE. */
3453 tmp2 = gen_reg_rtx (Pmode);
3454 if (TARGET_64BIT)
3455 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3456 else
3457 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3458 emit_insn (insn);
3459 if (TARGET_64BIT)
3460 insn = gen_tls_tls_64 (dest, tmp2, addr);
3461 else
3462 insn = gen_tls_tls_32 (dest, tmp2, addr);
3463 emit_insn (insn);
3467 return dest;
3470 /* Return 1 if X contains a thread-local symbol. */
3472 bool
3473 rs6000_tls_referenced_p (rtx x)
3475 if (! TARGET_HAVE_TLS)
3476 return false;
3478 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
3481 /* Return 1 if *X is a thread-local symbol. This is the same as
3482 rs6000_tls_symbol_ref except for the type of the unused argument. */
3484 static int
3485 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
3487 return RS6000_SYMBOL_REF_TLS_P (*x);
3490 /* The convention appears to be to define this wherever it is used.
3491 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3492 is now used here. */
3493 #ifndef REG_MODE_OK_FOR_BASE_P
3494 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3495 #endif
3497 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3498 replace the input X, or the original X if no replacement is called for.
3499 The output parameter *WIN is 1 if the calling macro should goto WIN,
3500 0 if it should not.
3502 For RS/6000, we wish to handle large displacements off a base
3503 register by splitting the addend across an addiu/addis and the mem insn.
3504 This cuts number of extra insns needed from 3 to 1.
3506 On Darwin, we use this to generate code for floating point constants.
3507 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3508 The Darwin code is inside #if TARGET_MACHO because only then is
3509 machopic_function_base_name() defined. */
3511 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
3512 int opnum, int type,
3513 int ind_levels ATTRIBUTE_UNUSED, int *win)
3515 /* We must recognize output that we have already generated ourselves. */
3516 if (GET_CODE (x) == PLUS
3517 && GET_CODE (XEXP (x, 0)) == PLUS
3518 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3519 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3520 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3522 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3523 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3524 opnum, (enum reload_type)type);
3525 *win = 1;
3526 return x;
3529 #if TARGET_MACHO
3530 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
3531 && GET_CODE (x) == LO_SUM
3532 && GET_CODE (XEXP (x, 0)) == PLUS
3533 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
3534 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
3535 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
3536 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
3537 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
3538 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
3539 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
3541 /* Result of previous invocation of this function on Darwin
3542 floating point constant. */
3543 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3544 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3545 opnum, (enum reload_type)type);
3546 *win = 1;
3547 return x;
3549 #endif
3551 /* Force ld/std non-word aligned offset into base register by wrapping
3552 in offset 0. */
3553 if (GET_CODE (x) == PLUS
3554 && GET_CODE (XEXP (x, 0)) == REG
3555 && REGNO (XEXP (x, 0)) < 32
3556 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3557 && GET_CODE (XEXP (x, 1)) == CONST_INT
3558 && (INTVAL (XEXP (x, 1)) & 3) != 0
3559 && !ALTIVEC_VECTOR_MODE (mode)
3560 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
3561 && TARGET_POWERPC64)
3563 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
3564 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3565 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3566 opnum, (enum reload_type) type);
3567 *win = 1;
3568 return x;
3571 if (GET_CODE (x) == PLUS
3572 && GET_CODE (XEXP (x, 0)) == REG
3573 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
3574 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3575 && GET_CODE (XEXP (x, 1)) == CONST_INT
3576 && !SPE_VECTOR_MODE (mode)
3577 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3578 || mode == DImode))
3579 && !ALTIVEC_VECTOR_MODE (mode))
3581 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3582 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
3583 HOST_WIDE_INT high
3584 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3586 /* Check for 32-bit overflow. */
3587 if (high + low != val)
3589 *win = 0;
3590 return x;
3593 /* Reload the high part into a base reg; leave the low part
3594 in the mem directly. */
3596 x = gen_rtx_PLUS (GET_MODE (x),
3597 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
3598 GEN_INT (high)),
3599 GEN_INT (low));
3601 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3602 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3603 opnum, (enum reload_type)type);
3604 *win = 1;
3605 return x;
3608 if (GET_CODE (x) == SYMBOL_REF
3609 && !ALTIVEC_VECTOR_MODE (mode)
3610 && !SPE_VECTOR_MODE (mode)
3611 #if TARGET_MACHO
3612 && DEFAULT_ABI == ABI_DARWIN
3613 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
3614 #else
3615 && DEFAULT_ABI == ABI_V4
3616 && !flag_pic
3617 #endif
3618 /* Don't do this for TFmode, since the result isn't offsettable.
3619 The same goes for DImode without 64-bit gprs and DFmode
3620 without fprs. */
3621 && mode != TFmode
3622 && (mode != DImode || TARGET_POWERPC64)
3623 && (mode != DFmode || TARGET_POWERPC64
3624 || (TARGET_FPRS && TARGET_HARD_FLOAT)))
3626 #if TARGET_MACHO
3627 if (flag_pic)
3629 rtx offset = gen_rtx_CONST (Pmode,
3630 gen_rtx_MINUS (Pmode, x,
3631 machopic_function_base_sym ()));
3632 x = gen_rtx_LO_SUM (GET_MODE (x),
3633 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
3634 gen_rtx_HIGH (Pmode, offset)), offset);
3636 else
3637 #endif
3638 x = gen_rtx_LO_SUM (GET_MODE (x),
3639 gen_rtx_HIGH (Pmode, x), x);
3641 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3642 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3643 opnum, (enum reload_type)type);
3644 *win = 1;
3645 return x;
3648 /* Reload an offset address wrapped by an AND that represents the
3649 masking of the lower bits. Strip the outer AND and let reload
3650 convert the offset address into an indirect address. */
3651 if (TARGET_ALTIVEC
3652 && ALTIVEC_VECTOR_MODE (mode)
3653 && GET_CODE (x) == AND
3654 && GET_CODE (XEXP (x, 0)) == PLUS
3655 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3656 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3657 && GET_CODE (XEXP (x, 1)) == CONST_INT
3658 && INTVAL (XEXP (x, 1)) == -16)
3660 x = XEXP (x, 0);
3661 *win = 1;
3662 return x;
3665 if (TARGET_TOC
3666 && constant_pool_expr_p (x)
3667 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
3669 x = create_TOC_reference (x);
3670 *win = 1;
3671 return x;
3673 *win = 0;
3674 return x;
3677 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3678 that is a valid memory address for an instruction.
3679 The MODE argument is the machine mode for the MEM expression
3680 that wants to use this address.
3682 On the RS/6000, there are four valid address: a SYMBOL_REF that
3683 refers to a constant pool entry of an address (or the sum of it
3684 plus a constant), a short (16-bit signed) constant plus a register,
3685 the sum of two registers, or a register indirect, possibly with an
3686 auto-increment. For DFmode and DImode with a constant plus register,
3687 we must ensure that both words are addressable or PowerPC64 with offset
3688 word aligned.
3690 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3691 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3692 adjacent memory cells are accessed by adding word-sized offsets
3693 during assembly output. */
3695 rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
3697 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3698 if (TARGET_ALTIVEC
3699 && ALTIVEC_VECTOR_MODE (mode)
3700 && GET_CODE (x) == AND
3701 && GET_CODE (XEXP (x, 1)) == CONST_INT
3702 && INTVAL (XEXP (x, 1)) == -16)
3703 x = XEXP (x, 0);
3705 if (RS6000_SYMBOL_REF_TLS_P (x))
3706 return 0;
3707 if (legitimate_indirect_address_p (x, reg_ok_strict))
3708 return 1;
3709 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
3710 && !ALTIVEC_VECTOR_MODE (mode)
3711 && !SPE_VECTOR_MODE (mode)
3712 && mode != TFmode
3713 /* Restrict addressing for DI because of our SUBREG hackery. */
3714 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3715 || mode == DImode))
3716 && TARGET_UPDATE
3717 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
3718 return 1;
3719 if (legitimate_small_data_p (mode, x))
3720 return 1;
3721 if (legitimate_constant_pool_address_p (x))
3722 return 1;
3723 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3724 if (! reg_ok_strict
3725 && GET_CODE (x) == PLUS
3726 && GET_CODE (XEXP (x, 0)) == REG
3727 && (XEXP (x, 0) == virtual_stack_vars_rtx
3728 || XEXP (x, 0) == arg_pointer_rtx)
3729 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3730 return 1;
3731 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
3732 return 1;
3733 if (mode != TImode
3734 && mode != TFmode
3735 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3736 || TARGET_POWERPC64
3737 || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
3738 && (TARGET_POWERPC64 || mode != DImode)
3739 && legitimate_indexed_address_p (x, reg_ok_strict))
3740 return 1;
3741 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
3742 return 1;
3743 return 0;
3746 /* Go to LABEL if ADDR (a legitimate address expression)
3747 has an effect that depends on the machine mode it is used for.
3749 On the RS/6000 this is true of all integral offsets (since AltiVec
3750 modes don't allow them) or is a pre-increment or decrement.
3752 ??? Except that due to conceptual problems in offsettable_address_p
3753 we can't really report the problems of integral offsets. So leave
3754 this assuming that the adjustable offset must be valid for the
3755 sub-words of a TFmode operand, which is what we had before. */
3757 bool
3758 rs6000_mode_dependent_address (rtx addr)
3760 switch (GET_CODE (addr))
3762 case PLUS:
3763 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
3765 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
3766 return val + 12 + 0x8000 >= 0x10000;
3768 break;
3770 case LO_SUM:
3771 return true;
3773 /* Auto-increment cases are now treated generically in recog.c. */
3775 default:
3776 break;
3779 return false;
3782 /* More elaborate version of recog's offsettable_memref_p predicate
3783 that works around the ??? note of rs6000_mode_dependent_address.
3784 In particular it accepts
3786 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
3788 in 32-bit mode, that the recog predicate rejects. */
3790 bool
3791 rs6000_offsettable_memref_p (rtx op)
3793 if (!MEM_P (op))
3794 return false;
3796 /* First mimic offsettable_memref_p. */
3797 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
3798 return true;
3800 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
3801 the latter predicate knows nothing about the mode of the memory
3802 reference and, therefore, assumes that it is the largest supported
3803 mode (TFmode). As a consequence, legitimate offsettable memory
3804 references are rejected. rs6000_legitimate_offset_address_p contains
3805 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
3806 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
3809 /* Return number of consecutive hard regs needed starting at reg REGNO
3810 to hold something of mode MODE.
3811 This is ordinarily the length in words of a value of mode MODE
3812 but can be less for certain modes in special long registers.
3814 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3815 scalar instructions. The upper 32 bits are only available to the
3816 SIMD instructions.
3818 POWER and PowerPC GPRs hold 32 bits worth;
3819 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3822 rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
3824 if (FP_REGNO_P (regno))
3825 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3827 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
3828 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
3830 if (ALTIVEC_REGNO_P (regno))
3831 return
3832 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
3834 /* The value returned for SCmode in the E500 double case is 2 for
3835 ABI compatibility; storing an SCmode value in a single register
3836 would require function_arg and rs6000_spe_function_arg to handle
3837 SCmode so as to pass the value correctly in a pair of
3838 registers. */
3839 if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode)
3840 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3842 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3845 /* Change register usage conditional on target flags. */
3846 void
3847 rs6000_conditional_register_usage (void)
3849 int i;
3851 /* Set MQ register fixed (already call_used) if not POWER
3852 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3853 be allocated. */
3854 if (! TARGET_POWER)
3855 fixed_regs[64] = 1;
3857 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3858 if (TARGET_64BIT)
3859 fixed_regs[13] = call_used_regs[13]
3860 = call_really_used_regs[13] = 1;
3862 /* Conditionally disable FPRs. */
3863 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
3864 for (i = 32; i < 64; i++)
3865 fixed_regs[i] = call_used_regs[i]
3866 = call_really_used_regs[i] = 1;
3868 /* The TOC register is not killed across calls in a way that is
3869 visible to the compiler. */
3870 if (DEFAULT_ABI == ABI_AIX)
3871 call_really_used_regs[2] = 0;
3873 if (DEFAULT_ABI == ABI_V4
3874 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3875 && flag_pic == 2)
3876 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3878 if (DEFAULT_ABI == ABI_V4
3879 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3880 && flag_pic == 1)
3881 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3882 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3883 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3885 if (DEFAULT_ABI == ABI_DARWIN
3886 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
3887 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3888 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3889 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3891 if (TARGET_TOC && TARGET_MINIMAL_TOC)
3892 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3893 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3895 if (TARGET_ALTIVEC)
3896 global_regs[VSCR_REGNO] = 1;
3898 if (TARGET_SPE)
3900 global_regs[SPEFSCR_REGNO] = 1;
3901 fixed_regs[FIXED_SCRATCH]
3902 = call_used_regs[FIXED_SCRATCH]
3903 = call_really_used_regs[FIXED_SCRATCH] = 1;
3906 if (! TARGET_ALTIVEC)
3908 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
3909 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
3910 call_really_used_regs[VRSAVE_REGNO] = 1;
3913 if (TARGET_ALTIVEC_ABI)
3914 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
3915 call_used_regs[i] = call_really_used_regs[i] = 1;
3918 /* Try to output insns to set TARGET equal to the constant C if it can
3919 be done in less than N insns. Do all computations in MODE.
3920 Returns the place where the output has been placed if it can be
3921 done and the insns have been emitted. If it would take more than N
3922 insns, zero is returned and no insns and emitted. */
3925 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
3926 rtx source, int n ATTRIBUTE_UNUSED)
3928 rtx result, insn, set;
3929 HOST_WIDE_INT c0, c1;
3931 switch (mode)
3933 case QImode:
3934 case HImode:
3935 if (dest == NULL)
3936 dest = gen_reg_rtx (mode);
3937 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
3938 return dest;
3940 case SImode:
3941 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
3943 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
3944 GEN_INT (INTVAL (source)
3945 & (~ (HOST_WIDE_INT) 0xffff))));
3946 emit_insn (gen_rtx_SET (VOIDmode, dest,
3947 gen_rtx_IOR (SImode, copy_rtx (result),
3948 GEN_INT (INTVAL (source) & 0xffff))));
3949 result = dest;
3950 break;
3952 case DImode:
3953 switch (GET_CODE (source))
3955 case CONST_INT:
3956 c0 = INTVAL (source);
3957 c1 = -(c0 < 0);
3958 break;
3960 case CONST_DOUBLE:
3961 #if HOST_BITS_PER_WIDE_INT >= 64
3962 c0 = CONST_DOUBLE_LOW (source);
3963 c1 = -(c0 < 0);
3964 #else
3965 c0 = CONST_DOUBLE_LOW (source);
3966 c1 = CONST_DOUBLE_HIGH (source);
3967 #endif
3968 break;
3970 default:
3971 gcc_unreachable ();
3974 result = rs6000_emit_set_long_const (dest, c0, c1);
3975 break;
3977 default:
3978 gcc_unreachable ();
3981 insn = get_last_insn ();
3982 set = single_set (insn);
3983 if (! CONSTANT_P (SET_SRC (set)))
3984 set_unique_reg_note (insn, REG_EQUAL, source);
3986 return result;
3989 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
3990 fall back to a straight forward decomposition. We do this to avoid
3991 exponential run times encountered when looking for longer sequences
3992 with rs6000_emit_set_const. */
3993 static rtx
3994 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
3996 if (!TARGET_POWERPC64)
3998 rtx operand1, operand2;
4000 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
4001 DImode);
4002 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
4003 DImode);
4004 emit_move_insn (operand1, GEN_INT (c1));
4005 emit_move_insn (operand2, GEN_INT (c2));
4007 else
4009 HOST_WIDE_INT ud1, ud2, ud3, ud4;
4011 ud1 = c1 & 0xffff;
4012 ud2 = (c1 & 0xffff0000) >> 16;
4013 #if HOST_BITS_PER_WIDE_INT >= 64
4014 c2 = c1 >> 32;
4015 #endif
4016 ud3 = c2 & 0xffff;
4017 ud4 = (c2 & 0xffff0000) >> 16;
4019 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
4020 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
4022 if (ud1 & 0x8000)
4023 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
4024 else
4025 emit_move_insn (dest, GEN_INT (ud1));
4028 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
4029 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
4031 if (ud2 & 0x8000)
4032 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
4033 - 0x80000000));
4034 else
4035 emit_move_insn (dest, GEN_INT (ud2 << 16));
4036 if (ud1 != 0)
4037 emit_move_insn (copy_rtx (dest),
4038 gen_rtx_IOR (DImode, copy_rtx (dest),
4039 GEN_INT (ud1)));
4041 else if ((ud4 == 0xffff && (ud3 & 0x8000))
4042 || (ud4 == 0 && ! (ud3 & 0x8000)))
4044 if (ud3 & 0x8000)
4045 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
4046 - 0x80000000));
4047 else
4048 emit_move_insn (dest, GEN_INT (ud3 << 16));
4050 if (ud2 != 0)
4051 emit_move_insn (copy_rtx (dest),
4052 gen_rtx_IOR (DImode, copy_rtx (dest),
4053 GEN_INT (ud2)));
4054 emit_move_insn (copy_rtx (dest),
4055 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4056 GEN_INT (16)));
4057 if (ud1 != 0)
4058 emit_move_insn (copy_rtx (dest),
4059 gen_rtx_IOR (DImode, copy_rtx (dest),
4060 GEN_INT (ud1)));
4062 else
4064 if (ud4 & 0x8000)
4065 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
4066 - 0x80000000));
4067 else
4068 emit_move_insn (dest, GEN_INT (ud4 << 16));
4070 if (ud3 != 0)
4071 emit_move_insn (copy_rtx (dest),
4072 gen_rtx_IOR (DImode, copy_rtx (dest),
4073 GEN_INT (ud3)));
4075 emit_move_insn (copy_rtx (dest),
4076 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4077 GEN_INT (32)));
4078 if (ud2 != 0)
4079 emit_move_insn (copy_rtx (dest),
4080 gen_rtx_IOR (DImode, copy_rtx (dest),
4081 GEN_INT (ud2 << 16)));
4082 if (ud1 != 0)
4083 emit_move_insn (copy_rtx (dest),
4084 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
4087 return dest;
4090 /* Helper for the following. Get rid of [r+r] memory refs
4091 in cases where it won't work (TImode, TFmode). */
4093 static void
4094 rs6000_eliminate_indexed_memrefs (rtx operands[2])
4096 if (GET_CODE (operands[0]) == MEM
4097 && GET_CODE (XEXP (operands[0], 0)) != REG
4098 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
4099 && ! reload_in_progress)
4100 operands[0]
4101 = replace_equiv_address (operands[0],
4102 copy_addr_to_reg (XEXP (operands[0], 0)));
4104 if (GET_CODE (operands[1]) == MEM
4105 && GET_CODE (XEXP (operands[1], 0)) != REG
4106 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
4107 && ! reload_in_progress)
4108 operands[1]
4109 = replace_equiv_address (operands[1],
4110 copy_addr_to_reg (XEXP (operands[1], 0)));
4113 /* Emit a move from SOURCE to DEST in mode MODE. */
4114 void
4115 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
4117 rtx operands[2];
4118 operands[0] = dest;
4119 operands[1] = source;
4121 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4122 if (GET_CODE (operands[1]) == CONST_DOUBLE
4123 && ! FLOAT_MODE_P (mode)
4124 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
4126 /* FIXME. This should never happen. */
4127 /* Since it seems that it does, do the safe thing and convert
4128 to a CONST_INT. */
4129 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
4131 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
4132 || FLOAT_MODE_P (mode)
4133 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
4134 || CONST_DOUBLE_LOW (operands[1]) < 0)
4135 && (CONST_DOUBLE_HIGH (operands[1]) != -1
4136 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
4138 /* Check if GCC is setting up a block move that will end up using FP
4139 registers as temporaries. We must make sure this is acceptable. */
4140 if (GET_CODE (operands[0]) == MEM
4141 && GET_CODE (operands[1]) == MEM
4142 && mode == DImode
4143 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
4144 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
4145 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
4146 ? 32 : MEM_ALIGN (operands[0])))
4147 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
4148 ? 32
4149 : MEM_ALIGN (operands[1]))))
4150 && ! MEM_VOLATILE_P (operands [0])
4151 && ! MEM_VOLATILE_P (operands [1]))
4153 emit_move_insn (adjust_address (operands[0], SImode, 0),
4154 adjust_address (operands[1], SImode, 0));
4155 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
4156 adjust_address (copy_rtx (operands[1]), SImode, 4));
4157 return;
4160 if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
4161 && !gpc_reg_operand (operands[1], mode))
4162 operands[1] = force_reg (mode, operands[1]);
4164 if (mode == SFmode && ! TARGET_POWERPC
4165 && TARGET_HARD_FLOAT && TARGET_FPRS
4166 && GET_CODE (operands[0]) == MEM)
4168 int regnum;
4170 if (reload_in_progress || reload_completed)
4171 regnum = true_regnum (operands[1]);
4172 else if (GET_CODE (operands[1]) == REG)
4173 regnum = REGNO (operands[1]);
4174 else
4175 regnum = -1;
4177 /* If operands[1] is a register, on POWER it may have
4178 double-precision data in it, so truncate it to single
4179 precision. */
4180 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
4182 rtx newreg;
4183 newreg = (no_new_pseudos ? copy_rtx (operands[1])
4184 : gen_reg_rtx (mode));
4185 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
4186 operands[1] = newreg;
4190 /* Recognize the case where operand[1] is a reference to thread-local
4191 data and load its address to a register. */
4192 if (rs6000_tls_referenced_p (operands[1]))
4194 enum tls_model model;
4195 rtx tmp = operands[1];
4196 rtx addend = NULL;
4198 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
4200 addend = XEXP (XEXP (tmp, 0), 1);
4201 tmp = XEXP (XEXP (tmp, 0), 0);
4204 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
4205 model = SYMBOL_REF_TLS_MODEL (tmp);
4206 gcc_assert (model != 0);
4208 tmp = rs6000_legitimize_tls_address (tmp, model);
4209 if (addend)
4211 tmp = gen_rtx_PLUS (mode, tmp, addend);
4212 tmp = force_operand (tmp, operands[0]);
4214 operands[1] = tmp;
4217 /* Handle the case where reload calls us with an invalid address. */
4218 if (reload_in_progress && mode == Pmode
4219 && (! general_operand (operands[1], mode)
4220 || ! nonimmediate_operand (operands[0], mode)))
4221 goto emit_set;
4223 /* 128-bit constant floating-point values on Darwin should really be
4224 loaded as two parts. */
4225 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
4226 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
4228 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4229 know how to get a DFmode SUBREG of a TFmode. */
4230 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
4231 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
4232 simplify_gen_subreg (imode, operands[1], mode, 0),
4233 imode);
4234 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
4235 GET_MODE_SIZE (imode)),
4236 simplify_gen_subreg (imode, operands[1], mode,
4237 GET_MODE_SIZE (imode)),
4238 imode);
4239 return;
4242 /* FIXME: In the long term, this switch statement should go away
4243 and be replaced by a sequence of tests based on things like
4244 mode == Pmode. */
4245 switch (mode)
4247 case HImode:
4248 case QImode:
4249 if (CONSTANT_P (operands[1])
4250 && GET_CODE (operands[1]) != CONST_INT)
4251 operands[1] = force_const_mem (mode, operands[1]);
4252 break;
4254 case TFmode:
4255 rs6000_eliminate_indexed_memrefs (operands);
4256 /* fall through */
4258 case DFmode:
4259 case SFmode:
4260 if (CONSTANT_P (operands[1])
4261 && ! easy_fp_constant (operands[1], mode))
4262 operands[1] = force_const_mem (mode, operands[1]);
4263 break;
4265 case V16QImode:
4266 case V8HImode:
4267 case V4SFmode:
4268 case V4SImode:
4269 case V4HImode:
4270 case V2SFmode:
4271 case V2SImode:
4272 case V1DImode:
4273 if (CONSTANT_P (operands[1])
4274 && !easy_vector_constant (operands[1], mode))
4275 operands[1] = force_const_mem (mode, operands[1]);
4276 break;
4278 case SImode:
4279 case DImode:
4280 /* Use default pattern for address of ELF small data */
4281 if (TARGET_ELF
4282 && mode == Pmode
4283 && DEFAULT_ABI == ABI_V4
4284 && (GET_CODE (operands[1]) == SYMBOL_REF
4285 || GET_CODE (operands[1]) == CONST)
4286 && small_data_operand (operands[1], mode))
4288 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4289 return;
4292 if (DEFAULT_ABI == ABI_V4
4293 && mode == Pmode && mode == SImode
4294 && flag_pic == 1 && got_operand (operands[1], mode))
4296 emit_insn (gen_movsi_got (operands[0], operands[1]));
4297 return;
4300 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
4301 && TARGET_NO_TOC
4302 && ! flag_pic
4303 && mode == Pmode
4304 && CONSTANT_P (operands[1])
4305 && GET_CODE (operands[1]) != HIGH
4306 && GET_CODE (operands[1]) != CONST_INT)
4308 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
4310 /* If this is a function address on -mcall-aixdesc,
4311 convert it to the address of the descriptor. */
4312 if (DEFAULT_ABI == ABI_AIX
4313 && GET_CODE (operands[1]) == SYMBOL_REF
4314 && XSTR (operands[1], 0)[0] == '.')
4316 const char *name = XSTR (operands[1], 0);
4317 rtx new_ref;
4318 while (*name == '.')
4319 name++;
4320 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
4321 CONSTANT_POOL_ADDRESS_P (new_ref)
4322 = CONSTANT_POOL_ADDRESS_P (operands[1]);
4323 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
4324 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4325 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
4326 operands[1] = new_ref;
4329 if (DEFAULT_ABI == ABI_DARWIN)
4331 #if TARGET_MACHO
4332 if (MACHO_DYNAMIC_NO_PIC_P)
4334 /* Take care of any required data indirection. */
4335 operands[1] = rs6000_machopic_legitimize_pic_address (
4336 operands[1], mode, operands[0]);
4337 if (operands[0] != operands[1])
4338 emit_insn (gen_rtx_SET (VOIDmode,
4339 operands[0], operands[1]));
4340 return;
4342 #endif
4343 emit_insn (gen_macho_high (target, operands[1]));
4344 emit_insn (gen_macho_low (operands[0], target, operands[1]));
4345 return;
4348 emit_insn (gen_elf_high (target, operands[1]));
4349 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4350 return;
4353 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4354 and we have put it in the TOC, we just need to make a TOC-relative
4355 reference to it. */
4356 if (TARGET_TOC
4357 && GET_CODE (operands[1]) == SYMBOL_REF
4358 && constant_pool_expr_p (operands[1])
4359 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
4360 get_pool_mode (operands[1])))
4362 operands[1] = create_TOC_reference (operands[1]);
4364 else if (mode == Pmode
4365 && CONSTANT_P (operands[1])
4366 && ((GET_CODE (operands[1]) != CONST_INT
4367 && ! easy_fp_constant (operands[1], mode))
4368 || (GET_CODE (operands[1]) == CONST_INT
4369 && num_insns_constant (operands[1], mode) > 2)
4370 || (GET_CODE (operands[0]) == REG
4371 && FP_REGNO_P (REGNO (operands[0]))))
4372 && GET_CODE (operands[1]) != HIGH
4373 && ! legitimate_constant_pool_address_p (operands[1])
4374 && ! toc_relative_expr_p (operands[1]))
4376 /* Emit a USE operation so that the constant isn't deleted if
4377 expensive optimizations are turned on because nobody
4378 references it. This should only be done for operands that
4379 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4380 This should not be done for operands that contain LABEL_REFs.
4381 For now, we just handle the obvious case. */
4382 if (GET_CODE (operands[1]) != LABEL_REF)
4383 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
4385 #if TARGET_MACHO
4386 /* Darwin uses a special PIC legitimizer. */
4387 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
4389 operands[1] =
4390 rs6000_machopic_legitimize_pic_address (operands[1], mode,
4391 operands[0]);
4392 if (operands[0] != operands[1])
4393 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4394 return;
4396 #endif
4398 /* If we are to limit the number of things we put in the TOC and
4399 this is a symbol plus a constant we can add in one insn,
4400 just put the symbol in the TOC and add the constant. Don't do
4401 this if reload is in progress. */
4402 if (GET_CODE (operands[1]) == CONST
4403 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4404 && GET_CODE (XEXP (operands[1], 0)) == PLUS
4405 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
4406 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4407 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4408 && ! side_effects_p (operands[0]))
4410 rtx sym =
4411 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
4412 rtx other = XEXP (XEXP (operands[1], 0), 1);
4414 sym = force_reg (mode, sym);
4415 if (mode == SImode)
4416 emit_insn (gen_addsi3 (operands[0], sym, other));
4417 else
4418 emit_insn (gen_adddi3 (operands[0], sym, other));
4419 return;
4422 operands[1] = force_const_mem (mode, operands[1]);
4424 if (TARGET_TOC
4425 && constant_pool_expr_p (XEXP (operands[1], 0))
4426 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4427 get_pool_constant (XEXP (operands[1], 0)),
4428 get_pool_mode (XEXP (operands[1], 0))))
4430 operands[1]
4431 = gen_const_mem (mode,
4432 create_TOC_reference (XEXP (operands[1], 0)));
4433 set_mem_alias_set (operands[1], get_TOC_alias_set ());
4436 break;
4438 case TImode:
4439 rs6000_eliminate_indexed_memrefs (operands);
4441 if (TARGET_POWER)
4443 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4444 gen_rtvec (2,
4445 gen_rtx_SET (VOIDmode,
4446 operands[0], operands[1]),
4447 gen_rtx_CLOBBER (VOIDmode,
4448 gen_rtx_SCRATCH (SImode)))));
4449 return;
4451 break;
4453 default:
4454 gcc_unreachable ();
4457 /* Above, we may have called force_const_mem which may have returned
4458 an invalid address. If we can, fix this up; otherwise, reload will
4459 have to deal with it. */
4460 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
4461 operands[1] = validize_mem (operands[1]);
4463 emit_set:
4464 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4467 /* Nonzero if we can use a floating-point register to pass this arg. */
4468 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4469 (SCALAR_FLOAT_MODE_P (MODE) \
4470 && !DECIMAL_FLOAT_MODE_P (MODE) \
4471 && (CUM)->fregno <= FP_ARG_MAX_REG \
4472 && TARGET_HARD_FLOAT && TARGET_FPRS)
4474 /* Nonzero if we can use an AltiVec register to pass this arg. */
4475 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4476 (ALTIVEC_VECTOR_MODE (MODE) \
4477 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4478 && TARGET_ALTIVEC_ABI \
4479 && (NAMED))
4481 /* Return a nonzero value to say to return the function value in
4482 memory, just as large structures are always returned. TYPE will be
4483 the data type of the value, and FNTYPE will be the type of the
4484 function doing the returning, or @code{NULL} for libcalls.
4486 The AIX ABI for the RS/6000 specifies that all structures are
4487 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4488 specifies that structures <= 8 bytes are returned in r3/r4, but a
4489 draft put them in memory, and GCC used to implement the draft
4490 instead of the final standard. Therefore, aix_struct_return
4491 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4492 compatibility can change DRAFT_V4_STRUCT_RET to override the
4493 default, and -m switches get the final word. See
4494 rs6000_override_options for more details.
4496 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4497 long double support is enabled. These values are returned in memory.
4499 int_size_in_bytes returns -1 for variable size objects, which go in
4500 memory always. The cast to unsigned makes -1 > 8. */
4502 static bool
4503 rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
4505 /* In the darwin64 abi, try to use registers for larger structs
4506 if possible. */
4507 if (rs6000_darwin64_abi
4508 && TREE_CODE (type) == RECORD_TYPE
4509 && int_size_in_bytes (type) > 0)
4511 CUMULATIVE_ARGS valcum;
4512 rtx valret;
4514 valcum.words = 0;
4515 valcum.fregno = FP_ARG_MIN_REG;
4516 valcum.vregno = ALTIVEC_ARG_MIN_REG;
4517 /* Do a trial code generation as if this were going to be passed
4518 as an argument; if any part goes in memory, we return NULL. */
4519 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
4520 if (valret)
4521 return false;
4522 /* Otherwise fall through to more conventional ABI rules. */
4525 if (AGGREGATE_TYPE_P (type)
4526 && (aix_struct_return
4527 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
4528 return true;
4530 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4531 modes only exist for GCC vector types if -maltivec. */
4532 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
4533 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
4534 return false;
4536 /* Return synthetic vectors in memory. */
4537 if (TREE_CODE (type) == VECTOR_TYPE
4538 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
4540 static bool warned_for_return_big_vectors = false;
4541 if (!warned_for_return_big_vectors)
4543 warning (0, "GCC vector returned by reference: "
4544 "non-standard ABI extension with no compatibility guarantee");
4545 warned_for_return_big_vectors = true;
4547 return true;
4550 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
4551 return true;
4553 return false;
4556 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4557 for a call to a function whose data type is FNTYPE.
4558 For a library call, FNTYPE is 0.
4560 For incoming args we set the number of arguments in the prototype large
4561 so we never return a PARALLEL. */
4563 void
4564 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
4565 rtx libname ATTRIBUTE_UNUSED, int incoming,
4566 int libcall, int n_named_args)
4568 static CUMULATIVE_ARGS zero_cumulative;
4570 *cum = zero_cumulative;
4571 cum->words = 0;
4572 cum->fregno = FP_ARG_MIN_REG;
4573 cum->vregno = ALTIVEC_ARG_MIN_REG;
4574 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
4575 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
4576 ? CALL_LIBCALL : CALL_NORMAL);
4577 cum->sysv_gregno = GP_ARG_MIN_REG;
4578 cum->stdarg = fntype
4579 && (TYPE_ARG_TYPES (fntype) != 0
4580 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4581 != void_type_node));
4583 cum->nargs_prototype = 0;
4584 if (incoming || cum->prototype)
4585 cum->nargs_prototype = n_named_args;
4587 /* Check for a longcall attribute. */
4588 if ((!fntype && rs6000_default_long_calls)
4589 || (fntype
4590 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
4591 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
4592 cum->call_cookie |= CALL_LONG;
4594 if (TARGET_DEBUG_ARG)
4596 fprintf (stderr, "\ninit_cumulative_args:");
4597 if (fntype)
4599 tree ret_type = TREE_TYPE (fntype);
4600 fprintf (stderr, " ret code = %s,",
4601 tree_code_name[ (int)TREE_CODE (ret_type) ]);
4604 if (cum->call_cookie & CALL_LONG)
4605 fprintf (stderr, " longcall,");
4607 fprintf (stderr, " proto = %d, nargs = %d\n",
4608 cum->prototype, cum->nargs_prototype);
4611 if (fntype
4612 && !TARGET_ALTIVEC
4613 && TARGET_ALTIVEC_ABI
4614 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
4616 error ("cannot return value in vector register because"
4617 " altivec instructions are disabled, use -maltivec"
4618 " to enable them");
4622 /* Return true if TYPE must be passed on the stack and not in registers. */
4624 static bool
4625 rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
4627 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
4628 return must_pass_in_stack_var_size (mode, type);
4629 else
4630 return must_pass_in_stack_var_size_or_pad (mode, type);
4633 /* If defined, a C expression which determines whether, and in which
4634 direction, to pad out an argument with extra space. The value
4635 should be of type `enum direction': either `upward' to pad above
4636 the argument, `downward' to pad below, or `none' to inhibit
4637 padding.
4639 For the AIX ABI structs are always stored left shifted in their
4640 argument slot. */
4642 enum direction
4643 function_arg_padding (enum machine_mode mode, tree type)
4645 #ifndef AGGREGATE_PADDING_FIXED
4646 #define AGGREGATE_PADDING_FIXED 0
4647 #endif
4648 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4649 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4650 #endif
4652 if (!AGGREGATE_PADDING_FIXED)
4654 /* GCC used to pass structures of the same size as integer types as
4655 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4656 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4657 passed padded downward, except that -mstrict-align further
4658 muddied the water in that multi-component structures of 2 and 4
4659 bytes in size were passed padded upward.
4661 The following arranges for best compatibility with previous
4662 versions of gcc, but removes the -mstrict-align dependency. */
4663 if (BYTES_BIG_ENDIAN)
4665 HOST_WIDE_INT size = 0;
4667 if (mode == BLKmode)
4669 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
4670 size = int_size_in_bytes (type);
4672 else
4673 size = GET_MODE_SIZE (mode);
4675 if (size == 1 || size == 2 || size == 4)
4676 return downward;
4678 return upward;
4681 if (AGGREGATES_PAD_UPWARD_ALWAYS)
4683 if (type != 0 && AGGREGATE_TYPE_P (type))
4684 return upward;
4687 /* Fall back to the default. */
4688 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
4691 /* If defined, a C expression that gives the alignment boundary, in bits,
4692 of an argument with the specified mode and type. If it is not defined,
4693 PARM_BOUNDARY is used for all arguments.
4695 V.4 wants long longs and doubles to be double word aligned. Just
4696 testing the mode size is a boneheaded way to do this as it means
4697 that other types such as complex int are also double word aligned.
4698 However, we're stuck with this because changing the ABI might break
4699 existing library interfaces.
4701 Doubleword align SPE vectors.
4702 Quadword align Altivec vectors.
4703 Quadword align large synthetic vector types. */
4706 function_arg_boundary (enum machine_mode mode, tree type)
4708 if (DEFAULT_ABI == ABI_V4
4709 && (GET_MODE_SIZE (mode) == 8
4710 || (TARGET_HARD_FLOAT
4711 && TARGET_FPRS
4712 && mode == TFmode)))
4713 return 64;
4714 else if (SPE_VECTOR_MODE (mode)
4715 || (type && TREE_CODE (type) == VECTOR_TYPE
4716 && int_size_in_bytes (type) >= 8
4717 && int_size_in_bytes (type) < 16))
4718 return 64;
4719 else if (ALTIVEC_VECTOR_MODE (mode)
4720 || (type && TREE_CODE (type) == VECTOR_TYPE
4721 && int_size_in_bytes (type) >= 16))
4722 return 128;
4723 else if (rs6000_darwin64_abi && mode == BLKmode
4724 && type && TYPE_ALIGN (type) > 64)
4725 return 128;
4726 else
4727 return PARM_BOUNDARY;
4730 /* For a function parm of MODE and TYPE, return the starting word in
4731 the parameter area. NWORDS of the parameter area are already used. */
4733 static unsigned int
4734 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
4736 unsigned int align;
4737 unsigned int parm_offset;
4739 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
4740 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
4741 return nwords + (-(parm_offset + nwords) & align);
4744 /* Compute the size (in words) of a function argument. */
4746 static unsigned long
4747 rs6000_arg_size (enum machine_mode mode, tree type)
4749 unsigned long size;
4751 if (mode != BLKmode)
4752 size = GET_MODE_SIZE (mode);
4753 else
4754 size = int_size_in_bytes (type);
4756 if (TARGET_32BIT)
4757 return (size + 3) >> 2;
4758 else
4759 return (size + 7) >> 3;
4762 /* Use this to flush pending int fields. */
4764 static void
4765 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
4766 HOST_WIDE_INT bitpos)
4768 unsigned int startbit, endbit;
4769 int intregs, intoffset;
4770 enum machine_mode mode;
4772 if (cum->intoffset == -1)
4773 return;
4775 intoffset = cum->intoffset;
4776 cum->intoffset = -1;
4778 if (intoffset % BITS_PER_WORD != 0)
4780 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4781 MODE_INT, 0);
4782 if (mode == BLKmode)
4784 /* We couldn't find an appropriate mode, which happens,
4785 e.g., in packed structs when there are 3 bytes to load.
4786 Back intoffset back to the beginning of the word in this
4787 case. */
4788 intoffset = intoffset & -BITS_PER_WORD;
4792 startbit = intoffset & -BITS_PER_WORD;
4793 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4794 intregs = (endbit - startbit) / BITS_PER_WORD;
4795 cum->words += intregs;
4798 /* The darwin64 ABI calls for us to recurse down through structs,
4799 looking for elements passed in registers. Unfortunately, we have
4800 to track int register count here also because of misalignments
4801 in powerpc alignment mode. */
4803 static void
4804 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
4805 tree type,
4806 HOST_WIDE_INT startbitpos)
4808 tree f;
4810 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4811 if (TREE_CODE (f) == FIELD_DECL)
4813 HOST_WIDE_INT bitpos = startbitpos;
4814 tree ftype = TREE_TYPE (f);
4815 enum machine_mode mode;
4816 if (ftype == error_mark_node)
4817 continue;
4818 mode = TYPE_MODE (ftype);
4820 if (DECL_SIZE (f) != 0
4821 && host_integerp (bit_position (f), 1))
4822 bitpos += int_bit_position (f);
4824 /* ??? FIXME: else assume zero offset. */
4826 if (TREE_CODE (ftype) == RECORD_TYPE)
4827 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
4828 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
4830 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4831 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4832 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
4834 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
4836 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4837 cum->vregno++;
4838 cum->words += 2;
4840 else if (cum->intoffset == -1)
4841 cum->intoffset = bitpos;
4845 /* Update the data in CUM to advance over an argument
4846 of mode MODE and data type TYPE.
4847 (TYPE is null for libcalls where that information may not be available.)
4849 Note that for args passed by reference, function_arg will be called
4850 with MODE and TYPE set to that of the pointer to the arg, not the arg
4851 itself. */
4853 void
4854 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4855 tree type, int named, int depth)
4857 int size;
4859 /* Only tick off an argument if we're not recursing. */
4860 if (depth == 0)
4861 cum->nargs_prototype--;
4863 if (TARGET_ALTIVEC_ABI
4864 && (ALTIVEC_VECTOR_MODE (mode)
4865 || (type && TREE_CODE (type) == VECTOR_TYPE
4866 && int_size_in_bytes (type) == 16)))
4868 bool stack = false;
4870 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
4872 cum->vregno++;
4873 if (!TARGET_ALTIVEC)
4874 error ("cannot pass argument in vector register because"
4875 " altivec instructions are disabled, use -maltivec"
4876 " to enable them");
4878 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4879 even if it is going to be passed in a vector register.
4880 Darwin does the same for variable-argument functions. */
4881 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
4882 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
4883 stack = true;
4885 else
4886 stack = true;
4888 if (stack)
4890 int align;
4892 /* Vector parameters must be 16-byte aligned. This places
4893 them at 2 mod 4 in terms of words in 32-bit mode, since
4894 the parameter save area starts at offset 24 from the
4895 stack. In 64-bit mode, they just have to start on an
4896 even word, since the parameter save area is 16-byte
4897 aligned. Space for GPRs is reserved even if the argument
4898 will be passed in memory. */
4899 if (TARGET_32BIT)
4900 align = (2 - cum->words) & 3;
4901 else
4902 align = cum->words & 1;
4903 cum->words += align + rs6000_arg_size (mode, type);
4905 if (TARGET_DEBUG_ARG)
4907 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
4908 cum->words, align);
4909 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
4910 cum->nargs_prototype, cum->prototype,
4911 GET_MODE_NAME (mode));
4915 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
4916 && !cum->stdarg
4917 && cum->sysv_gregno <= GP_ARG_MAX_REG)
4918 cum->sysv_gregno++;
4920 else if (rs6000_darwin64_abi
4921 && mode == BLKmode
4922 && TREE_CODE (type) == RECORD_TYPE
4923 && (size = int_size_in_bytes (type)) > 0)
4925 /* Variable sized types have size == -1 and are
4926 treated as if consisting entirely of ints.
4927 Pad to 16 byte boundary if needed. */
4928 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4929 && (cum->words % 2) != 0)
4930 cum->words++;
4931 /* For varargs, we can just go up by the size of the struct. */
4932 if (!named)
4933 cum->words += (size + 7) / 8;
4934 else
4936 /* It is tempting to say int register count just goes up by
4937 sizeof(type)/8, but this is wrong in a case such as
4938 { int; double; int; } [powerpc alignment]. We have to
4939 grovel through the fields for these too. */
4940 cum->intoffset = 0;
4941 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
4942 rs6000_darwin64_record_arg_advance_flush (cum,
4943 size * BITS_PER_UNIT);
4946 else if (DEFAULT_ABI == ABI_V4)
4948 if (TARGET_HARD_FLOAT && TARGET_FPRS
4949 && (mode == SFmode || mode == DFmode
4950 || (mode == TFmode && !TARGET_IEEEQUAD)))
4952 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
4953 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4954 else
4956 cum->fregno = FP_ARG_V4_MAX_REG + 1;
4957 if (mode == DFmode || mode == TFmode)
4958 cum->words += cum->words & 1;
4959 cum->words += rs6000_arg_size (mode, type);
4962 else
4964 int n_words = rs6000_arg_size (mode, type);
4965 int gregno = cum->sysv_gregno;
4967 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4968 (r7,r8) or (r9,r10). As does any other 2 word item such
4969 as complex int due to a historical mistake. */
4970 if (n_words == 2)
4971 gregno += (1 - gregno) & 1;
4973 /* Multi-reg args are not split between registers and stack. */
4974 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
4976 /* Long long and SPE vectors are aligned on the stack.
4977 So are other 2 word items such as complex int due to
4978 a historical mistake. */
4979 if (n_words == 2)
4980 cum->words += cum->words & 1;
4981 cum->words += n_words;
4984 /* Note: continuing to accumulate gregno past when we've started
4985 spilling to the stack indicates the fact that we've started
4986 spilling to the stack to expand_builtin_saveregs. */
4987 cum->sysv_gregno = gregno + n_words;
4990 if (TARGET_DEBUG_ARG)
4992 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
4993 cum->words, cum->fregno);
4994 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
4995 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
4996 fprintf (stderr, "mode = %4s, named = %d\n",
4997 GET_MODE_NAME (mode), named);
5000 else
5002 int n_words = rs6000_arg_size (mode, type);
5003 int start_words = cum->words;
5004 int align_words = rs6000_parm_start (mode, type, start_words);
5006 cum->words = align_words + n_words;
5008 if (SCALAR_FLOAT_MODE_P (mode)
5009 && !DECIMAL_FLOAT_MODE_P (mode)
5010 && TARGET_HARD_FLOAT && TARGET_FPRS)
5011 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5013 if (TARGET_DEBUG_ARG)
5015 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5016 cum->words, cum->fregno);
5017 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
5018 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
5019 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
5020 named, align_words - start_words, depth);
5025 static rtx
5026 spe_build_register_parallel (enum machine_mode mode, int gregno)
5028 rtx r1, r3, r5, r7;
5030 switch (mode)
5032 case DFmode:
5033 r1 = gen_rtx_REG (DImode, gregno);
5034 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5035 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
5037 case DCmode:
5038 case TFmode:
5039 r1 = gen_rtx_REG (DImode, gregno);
5040 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5041 r3 = gen_rtx_REG (DImode, gregno + 2);
5042 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5043 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
5045 case TCmode:
5046 r1 = gen_rtx_REG (DImode, gregno);
5047 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5048 r3 = gen_rtx_REG (DImode, gregno + 2);
5049 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5050 r5 = gen_rtx_REG (DImode, gregno + 4);
5051 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
5052 r7 = gen_rtx_REG (DImode, gregno + 6);
5053 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
5054 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
5056 default:
5057 gcc_unreachable ();
5061 /* Determine where to put a SIMD argument on the SPE. */
5062 static rtx
5063 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5064 tree type)
5066 int gregno = cum->sysv_gregno;
5068 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5069 are passed and returned in a pair of GPRs for ABI compatibility. */
5070 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode
5071 || mode == TFmode || mode == TCmode))
5073 int n_words = rs6000_arg_size (mode, type);
5075 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5076 if (mode == DFmode)
5077 gregno += (1 - gregno) & 1;
5079 /* Multi-reg args are not split between registers and stack. */
5080 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5081 return NULL_RTX;
5083 return spe_build_register_parallel (mode, gregno);
5085 if (cum->stdarg)
5087 int n_words = rs6000_arg_size (mode, type);
5089 /* SPE vectors are put in odd registers. */
5090 if (n_words == 2 && (gregno & 1) == 0)
5091 gregno += 1;
5093 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
5095 rtx r1, r2;
5096 enum machine_mode m = SImode;
5098 r1 = gen_rtx_REG (m, gregno);
5099 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
5100 r2 = gen_rtx_REG (m, gregno + 1);
5101 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
5102 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
5104 else
5105 return NULL_RTX;
5107 else
5109 if (gregno <= GP_ARG_MAX_REG)
5110 return gen_rtx_REG (mode, gregno);
5111 else
5112 return NULL_RTX;
5116 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5117 structure between cum->intoffset and bitpos to integer registers. */
5119 static void
5120 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
5121 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
5123 enum machine_mode mode;
5124 unsigned int regno;
5125 unsigned int startbit, endbit;
5126 int this_regno, intregs, intoffset;
5127 rtx reg;
5129 if (cum->intoffset == -1)
5130 return;
5132 intoffset = cum->intoffset;
5133 cum->intoffset = -1;
5135 /* If this is the trailing part of a word, try to only load that
5136 much into the register. Otherwise load the whole register. Note
5137 that in the latter case we may pick up unwanted bits. It's not a
5138 problem at the moment but may wish to revisit. */
5140 if (intoffset % BITS_PER_WORD != 0)
5142 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5143 MODE_INT, 0);
5144 if (mode == BLKmode)
5146 /* We couldn't find an appropriate mode, which happens,
5147 e.g., in packed structs when there are 3 bytes to load.
5148 Back intoffset back to the beginning of the word in this
5149 case. */
5150 intoffset = intoffset & -BITS_PER_WORD;
5151 mode = word_mode;
5154 else
5155 mode = word_mode;
5157 startbit = intoffset & -BITS_PER_WORD;
5158 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5159 intregs = (endbit - startbit) / BITS_PER_WORD;
5160 this_regno = cum->words + intoffset / BITS_PER_WORD;
5162 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
5163 cum->use_stack = 1;
5165 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
5166 if (intregs <= 0)
5167 return;
5169 intoffset /= BITS_PER_UNIT;
5172 regno = GP_ARG_MIN_REG + this_regno;
5173 reg = gen_rtx_REG (mode, regno);
5174 rvec[(*k)++] =
5175 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
5177 this_regno += 1;
5178 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
5179 mode = word_mode;
5180 intregs -= 1;
5182 while (intregs > 0);
5185 /* Recursive workhorse for the following. */
5187 static void
5188 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
5189 HOST_WIDE_INT startbitpos, rtx rvec[],
5190 int *k)
5192 tree f;
5194 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5195 if (TREE_CODE (f) == FIELD_DECL)
5197 HOST_WIDE_INT bitpos = startbitpos;
5198 tree ftype = TREE_TYPE (f);
5199 enum machine_mode mode;
5200 if (ftype == error_mark_node)
5201 continue;
5202 mode = TYPE_MODE (ftype);
5204 if (DECL_SIZE (f) != 0
5205 && host_integerp (bit_position (f), 1))
5206 bitpos += int_bit_position (f);
5208 /* ??? FIXME: else assume zero offset. */
5210 if (TREE_CODE (ftype) == RECORD_TYPE)
5211 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
5212 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
5214 #if 0
5215 switch (mode)
5217 case SCmode: mode = SFmode; break;
5218 case DCmode: mode = DFmode; break;
5219 case TCmode: mode = TFmode; break;
5220 default: break;
5222 #endif
5223 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5224 rvec[(*k)++]
5225 = gen_rtx_EXPR_LIST (VOIDmode,
5226 gen_rtx_REG (mode, cum->fregno++),
5227 GEN_INT (bitpos / BITS_PER_UNIT));
5228 if (mode == TFmode)
5229 cum->fregno++;
5231 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
5233 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5234 rvec[(*k)++]
5235 = gen_rtx_EXPR_LIST (VOIDmode,
5236 gen_rtx_REG (mode, cum->vregno++),
5237 GEN_INT (bitpos / BITS_PER_UNIT));
5239 else if (cum->intoffset == -1)
5240 cum->intoffset = bitpos;
5244 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5245 the register(s) to be used for each field and subfield of a struct
5246 being passed by value, along with the offset of where the
5247 register's value may be found in the block. FP fields go in FP
5248 register, vector fields go in vector registers, and everything
5249 else goes in int registers, packed as in memory.
5251 This code is also used for function return values. RETVAL indicates
5252 whether this is the case.
5254 Much of this is taken from the SPARC V9 port, which has a similar
5255 calling convention. */
5257 static rtx
5258 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, tree type,
5259 int named, bool retval)
5261 rtx rvec[FIRST_PSEUDO_REGISTER];
5262 int k = 1, kbase = 1;
5263 HOST_WIDE_INT typesize = int_size_in_bytes (type);
5264 /* This is a copy; modifications are not visible to our caller. */
5265 CUMULATIVE_ARGS copy_cum = *orig_cum;
5266 CUMULATIVE_ARGS *cum = &copy_cum;
5268 /* Pad to 16 byte boundary if needed. */
5269 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5270 && (cum->words % 2) != 0)
5271 cum->words++;
5273 cum->intoffset = 0;
5274 cum->use_stack = 0;
5275 cum->named = named;
5277 /* Put entries into rvec[] for individual FP and vector fields, and
5278 for the chunks of memory that go in int regs. Note we start at
5279 element 1; 0 is reserved for an indication of using memory, and
5280 may or may not be filled in below. */
5281 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
5282 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
5284 /* If any part of the struct went on the stack put all of it there.
5285 This hack is because the generic code for
5286 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5287 parts of the struct are not at the beginning. */
5288 if (cum->use_stack)
5290 if (retval)
5291 return NULL_RTX; /* doesn't go in registers at all */
5292 kbase = 0;
5293 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5295 if (k > 1 || cum->use_stack)
5296 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
5297 else
5298 return NULL_RTX;
5301 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5303 static rtx
5304 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
5306 int n_units;
5307 int i, k;
5308 rtx rvec[GP_ARG_NUM_REG + 1];
5310 if (align_words >= GP_ARG_NUM_REG)
5311 return NULL_RTX;
5313 n_units = rs6000_arg_size (mode, type);
5315 /* Optimize the simple case where the arg fits in one gpr, except in
5316 the case of BLKmode due to assign_parms assuming that registers are
5317 BITS_PER_WORD wide. */
5318 if (n_units == 0
5319 || (n_units == 1 && mode != BLKmode))
5320 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5322 k = 0;
5323 if (align_words + n_units > GP_ARG_NUM_REG)
5324 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5325 using a magic NULL_RTX component.
5326 This is not strictly correct. Only some of the arg belongs in
5327 memory, not all of it. However, the normal scheme using
5328 function_arg_partial_nregs can result in unusual subregs, eg.
5329 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5330 store the whole arg to memory is often more efficient than code
5331 to store pieces, and we know that space is available in the right
5332 place for the whole arg. */
5333 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5335 i = 0;
5338 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
5339 rtx off = GEN_INT (i++ * 4);
5340 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5342 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
5344 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5347 /* Determine where to put an argument to a function.
5348 Value is zero to push the argument on the stack,
5349 or a hard register in which to store the argument.
5351 MODE is the argument's machine mode.
5352 TYPE is the data type of the argument (as a tree).
5353 This is null for libcalls where that information may
5354 not be available.
5355 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5356 the preceding args and about the function being called. It is
5357 not modified in this routine.
5358 NAMED is nonzero if this argument is a named parameter
5359 (otherwise it is an extra parameter matching an ellipsis).
5361 On RS/6000 the first eight words of non-FP are normally in registers
5362 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5363 Under V.4, the first 8 FP args are in registers.
5365 If this is floating-point and no prototype is specified, we use
5366 both an FP and integer register (or possibly FP reg and stack). Library
5367 functions (when CALL_LIBCALL is set) always have the proper types for args,
5368 so we can pass the FP value just in one register. emit_library_function
5369 doesn't support PARALLEL anyway.
5371 Note that for args passed by reference, function_arg will be called
5372 with MODE and TYPE set to that of the pointer to the arg, not the arg
5373 itself. */
5376 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5377 tree type, int named)
5379 enum rs6000_abi abi = DEFAULT_ABI;
5381 /* Return a marker to indicate whether CR1 needs to set or clear the
5382 bit that V.4 uses to say fp args were passed in registers.
5383 Assume that we don't need the marker for software floating point,
5384 or compiler generated library calls. */
5385 if (mode == VOIDmode)
5387 if (abi == ABI_V4
5388 && (cum->call_cookie & CALL_LIBCALL) == 0
5389 && (cum->stdarg
5390 || (cum->nargs_prototype < 0
5391 && (cum->prototype || TARGET_NO_PROTOTYPE))))
5393 /* For the SPE, we need to crxor CR6 always. */
5394 if (TARGET_SPE_ABI)
5395 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
5396 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
5397 return GEN_INT (cum->call_cookie
5398 | ((cum->fregno == FP_ARG_MIN_REG)
5399 ? CALL_V4_SET_FP_ARGS
5400 : CALL_V4_CLEAR_FP_ARGS));
5403 return GEN_INT (cum->call_cookie);
5406 if (rs6000_darwin64_abi && mode == BLKmode
5407 && TREE_CODE (type) == RECORD_TYPE)
5409 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
5410 if (rslt != NULL_RTX)
5411 return rslt;
5412 /* Else fall through to usual handling. */
5415 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
5416 if (TARGET_64BIT && ! cum->prototype)
5418 /* Vector parameters get passed in vector register
5419 and also in GPRs or memory, in absence of prototype. */
5420 int align_words;
5421 rtx slot;
5422 align_words = (cum->words + 1) & ~1;
5424 if (align_words >= GP_ARG_NUM_REG)
5426 slot = NULL_RTX;
5428 else
5430 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5432 return gen_rtx_PARALLEL (mode,
5433 gen_rtvec (2,
5434 gen_rtx_EXPR_LIST (VOIDmode,
5435 slot, const0_rtx),
5436 gen_rtx_EXPR_LIST (VOIDmode,
5437 gen_rtx_REG (mode, cum->vregno),
5438 const0_rtx)));
5440 else
5441 return gen_rtx_REG (mode, cum->vregno);
5442 else if (TARGET_ALTIVEC_ABI
5443 && (ALTIVEC_VECTOR_MODE (mode)
5444 || (type && TREE_CODE (type) == VECTOR_TYPE
5445 && int_size_in_bytes (type) == 16)))
5447 if (named || abi == ABI_V4)
5448 return NULL_RTX;
5449 else
5451 /* Vector parameters to varargs functions under AIX or Darwin
5452 get passed in memory and possibly also in GPRs. */
5453 int align, align_words, n_words;
5454 enum machine_mode part_mode;
5456 /* Vector parameters must be 16-byte aligned. This places them at
5457 2 mod 4 in terms of words in 32-bit mode, since the parameter
5458 save area starts at offset 24 from the stack. In 64-bit mode,
5459 they just have to start on an even word, since the parameter
5460 save area is 16-byte aligned. */
5461 if (TARGET_32BIT)
5462 align = (2 - cum->words) & 3;
5463 else
5464 align = cum->words & 1;
5465 align_words = cum->words + align;
5467 /* Out of registers? Memory, then. */
5468 if (align_words >= GP_ARG_NUM_REG)
5469 return NULL_RTX;
5471 if (TARGET_32BIT && TARGET_POWERPC64)
5472 return rs6000_mixed_function_arg (mode, type, align_words);
5474 /* The vector value goes in GPRs. Only the part of the
5475 value in GPRs is reported here. */
5476 part_mode = mode;
5477 n_words = rs6000_arg_size (mode, type);
5478 if (align_words + n_words > GP_ARG_NUM_REG)
5479 /* Fortunately, there are only two possibilities, the value
5480 is either wholly in GPRs or half in GPRs and half not. */
5481 part_mode = DImode;
5483 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
5486 else if (TARGET_SPE_ABI && TARGET_SPE
5487 && (SPE_VECTOR_MODE (mode)
5488 || (TARGET_E500_DOUBLE && (mode == DFmode
5489 || mode == DCmode
5490 || mode == TFmode
5491 || mode == TCmode))))
5492 return rs6000_spe_function_arg (cum, mode, type);
5494 else if (abi == ABI_V4)
5496 if (TARGET_HARD_FLOAT && TARGET_FPRS
5497 && (mode == SFmode || mode == DFmode
5498 || (mode == TFmode && !TARGET_IEEEQUAD)))
5500 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
5501 return gen_rtx_REG (mode, cum->fregno);
5502 else
5503 return NULL_RTX;
5505 else
5507 int n_words = rs6000_arg_size (mode, type);
5508 int gregno = cum->sysv_gregno;
5510 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5511 (r7,r8) or (r9,r10). As does any other 2 word item such
5512 as complex int due to a historical mistake. */
5513 if (n_words == 2)
5514 gregno += (1 - gregno) & 1;
5516 /* Multi-reg args are not split between registers and stack. */
5517 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5518 return NULL_RTX;
5520 if (TARGET_32BIT && TARGET_POWERPC64)
5521 return rs6000_mixed_function_arg (mode, type,
5522 gregno - GP_ARG_MIN_REG);
5523 return gen_rtx_REG (mode, gregno);
5526 else
5528 int align_words = rs6000_parm_start (mode, type, cum->words);
5530 if (USE_FP_FOR_ARG_P (cum, mode, type))
5532 rtx rvec[GP_ARG_NUM_REG + 1];
5533 rtx r;
5534 int k;
5535 bool needs_psave;
5536 enum machine_mode fmode = mode;
5537 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
5539 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
5541 /* Currently, we only ever need one reg here because complex
5542 doubles are split. */
5543 gcc_assert (cum->fregno == FP_ARG_MAX_REG && fmode == TFmode);
5545 /* Long double split over regs and memory. */
5546 fmode = DFmode;
5549 /* Do we also need to pass this arg in the parameter save
5550 area? */
5551 needs_psave = (type
5552 && (cum->nargs_prototype <= 0
5553 || (DEFAULT_ABI == ABI_AIX
5554 && TARGET_XL_COMPAT
5555 && align_words >= GP_ARG_NUM_REG)));
5557 if (!needs_psave && mode == fmode)
5558 return gen_rtx_REG (fmode, cum->fregno);
5560 k = 0;
5561 if (needs_psave)
5563 /* Describe the part that goes in gprs or the stack.
5564 This piece must come first, before the fprs. */
5565 if (align_words < GP_ARG_NUM_REG)
5567 unsigned long n_words = rs6000_arg_size (mode, type);
5569 if (align_words + n_words > GP_ARG_NUM_REG
5570 || (TARGET_32BIT && TARGET_POWERPC64))
5572 /* If this is partially on the stack, then we only
5573 include the portion actually in registers here. */
5574 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
5575 rtx off;
5576 int i = 0;
5577 if (align_words + n_words > GP_ARG_NUM_REG)
5578 /* Not all of the arg fits in gprs. Say that it
5579 goes in memory too, using a magic NULL_RTX
5580 component. Also see comment in
5581 rs6000_mixed_function_arg for why the normal
5582 function_arg_partial_nregs scheme doesn't work
5583 in this case. */
5584 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
5585 const0_rtx);
5588 r = gen_rtx_REG (rmode,
5589 GP_ARG_MIN_REG + align_words);
5590 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
5591 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5593 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
5595 else
5597 /* The whole arg fits in gprs. */
5598 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5599 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5602 else
5603 /* It's entirely in memory. */
5604 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5607 /* Describe where this piece goes in the fprs. */
5608 r = gen_rtx_REG (fmode, cum->fregno);
5609 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5611 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5613 else if (align_words < GP_ARG_NUM_REG)
5615 if (TARGET_32BIT && TARGET_POWERPC64)
5616 return rs6000_mixed_function_arg (mode, type, align_words);
5618 if (mode == BLKmode)
5619 mode = Pmode;
5621 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5623 else
5624 return NULL_RTX;
5628 /* For an arg passed partly in registers and partly in memory, this is
5629 the number of bytes passed in registers. For args passed entirely in
5630 registers or entirely in memory, zero. When an arg is described by a
5631 PARALLEL, perhaps using more than one register type, this function
5632 returns the number of bytes used by the first element of the PARALLEL. */
5634 static int
5635 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5636 tree type, bool named)
5638 int ret = 0;
5639 int align_words;
5641 if (DEFAULT_ABI == ABI_V4)
5642 return 0;
5644 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
5645 && cum->nargs_prototype >= 0)
5646 return 0;
5648 /* In this complicated case we just disable the partial_nregs code. */
5649 if (rs6000_darwin64_abi && mode == BLKmode
5650 && TREE_CODE (type) == RECORD_TYPE
5651 && int_size_in_bytes (type) > 0)
5652 return 0;
5654 align_words = rs6000_parm_start (mode, type, cum->words);
5656 if (USE_FP_FOR_ARG_P (cum, mode, type))
5658 /* If we are passing this arg in the fixed parameter save area
5659 (gprs or memory) as well as fprs, then this function should
5660 return the number of partial bytes passed in the parameter
5661 save area rather than partial bytes passed in fprs. */
5662 if (type
5663 && (cum->nargs_prototype <= 0
5664 || (DEFAULT_ABI == ABI_AIX
5665 && TARGET_XL_COMPAT
5666 && align_words >= GP_ARG_NUM_REG)))
5667 return 0;
5668 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
5669 > FP_ARG_MAX_REG + 1)
5670 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
5671 else if (cum->nargs_prototype >= 0)
5672 return 0;
5675 if (align_words < GP_ARG_NUM_REG
5676 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
5677 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
5679 if (ret != 0 && TARGET_DEBUG_ARG)
5680 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
5682 return ret;
5685 /* A C expression that indicates when an argument must be passed by
5686 reference. If nonzero for an argument, a copy of that argument is
5687 made in memory and a pointer to the argument is passed instead of
5688 the argument itself. The pointer is passed in whatever way is
5689 appropriate for passing a pointer to that type.
5691 Under V.4, aggregates and long double are passed by reference.
5693 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5694 reference unless the AltiVec vector extension ABI is in force.
5696 As an extension to all ABIs, variable sized types are passed by
5697 reference. */
5699 static bool
5700 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5701 enum machine_mode mode, tree type,
5702 bool named ATTRIBUTE_UNUSED)
5704 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
5706 if (TARGET_DEBUG_ARG)
5707 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
5708 return 1;
5711 if (!type)
5712 return 0;
5714 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
5716 if (TARGET_DEBUG_ARG)
5717 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
5718 return 1;
5721 if (int_size_in_bytes (type) < 0)
5723 if (TARGET_DEBUG_ARG)
5724 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
5725 return 1;
5728 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5729 modes only exist for GCC vector types if -maltivec. */
5730 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
5732 if (TARGET_DEBUG_ARG)
5733 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
5734 return 1;
5737 /* Pass synthetic vectors in memory. */
5738 if (TREE_CODE (type) == VECTOR_TYPE
5739 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
5741 static bool warned_for_pass_big_vectors = false;
5742 if (TARGET_DEBUG_ARG)
5743 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
5744 if (!warned_for_pass_big_vectors)
5746 warning (0, "GCC vector passed by reference: "
5747 "non-standard ABI extension with no compatibility guarantee");
5748 warned_for_pass_big_vectors = true;
5750 return 1;
5753 return 0;
5756 static void
5757 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
5759 int i;
5760 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
5762 if (nregs == 0)
5763 return;
5765 for (i = 0; i < nregs; i++)
5767 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
5768 if (reload_completed)
5770 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
5771 tem = NULL_RTX;
5772 else
5773 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
5774 i * GET_MODE_SIZE (reg_mode));
5776 else
5777 tem = replace_equiv_address (tem, XEXP (tem, 0));
5779 gcc_assert (tem);
5781 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
5785 /* Perform any needed actions needed for a function that is receiving a
5786 variable number of arguments.
5788 CUM is as above.
5790 MODE and TYPE are the mode and type of the current parameter.
5792 PRETEND_SIZE is a variable that should be set to the amount of stack
5793 that must be pushed by the prolog to pretend that our caller pushed
5796 Normally, this macro will push all remaining incoming registers on the
5797 stack and set PRETEND_SIZE to the length of the registers pushed. */
5799 static void
5800 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5801 tree type, int *pretend_size ATTRIBUTE_UNUSED,
5802 int no_rtl)
5804 CUMULATIVE_ARGS next_cum;
5805 int reg_size = TARGET_32BIT ? 4 : 8;
5806 rtx save_area = NULL_RTX, mem;
5807 int first_reg_offset, set;
5809 /* Skip the last named argument. */
5810 next_cum = *cum;
5811 function_arg_advance (&next_cum, mode, type, 1, 0);
5813 if (DEFAULT_ABI == ABI_V4)
5815 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
5817 if (! no_rtl)
5819 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
5820 HOST_WIDE_INT offset = 0;
5822 /* Try to optimize the size of the varargs save area.
5823 The ABI requires that ap.reg_save_area is doubleword
5824 aligned, but we don't need to allocate space for all
5825 the bytes, only those to which we actually will save
5826 anything. */
5827 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
5828 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
5829 if (TARGET_HARD_FLOAT && TARGET_FPRS
5830 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5831 && cfun->va_list_fpr_size)
5833 if (gpr_reg_num)
5834 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
5835 * UNITS_PER_FP_WORD;
5836 if (cfun->va_list_fpr_size
5837 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5838 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
5839 else
5840 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5841 * UNITS_PER_FP_WORD;
5843 if (gpr_reg_num)
5845 offset = -((first_reg_offset * reg_size) & ~7);
5846 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
5848 gpr_reg_num = cfun->va_list_gpr_size;
5849 if (reg_size == 4 && (first_reg_offset & 1))
5850 gpr_reg_num++;
5852 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
5854 else if (fpr_size)
5855 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
5856 * UNITS_PER_FP_WORD
5857 - (int) (GP_ARG_NUM_REG * reg_size);
5859 if (gpr_size + fpr_size)
5861 rtx reg_save_area
5862 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
5863 gcc_assert (GET_CODE (reg_save_area) == MEM);
5864 reg_save_area = XEXP (reg_save_area, 0);
5865 if (GET_CODE (reg_save_area) == PLUS)
5867 gcc_assert (XEXP (reg_save_area, 0)
5868 == virtual_stack_vars_rtx);
5869 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
5870 offset += INTVAL (XEXP (reg_save_area, 1));
5872 else
5873 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
5876 cfun->machine->varargs_save_offset = offset;
5877 save_area = plus_constant (virtual_stack_vars_rtx, offset);
5880 else
5882 first_reg_offset = next_cum.words;
5883 save_area = virtual_incoming_args_rtx;
5885 if (targetm.calls.must_pass_in_stack (mode, type))
5886 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
5889 set = get_varargs_alias_set ();
5890 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
5891 && cfun->va_list_gpr_size)
5893 int nregs = GP_ARG_NUM_REG - first_reg_offset;
5895 if (va_list_gpr_counter_field)
5897 /* V4 va_list_gpr_size counts number of registers needed. */
5898 if (nregs > cfun->va_list_gpr_size)
5899 nregs = cfun->va_list_gpr_size;
5901 else
5903 /* char * va_list instead counts number of bytes needed. */
5904 if (nregs > cfun->va_list_gpr_size / reg_size)
5905 nregs = cfun->va_list_gpr_size / reg_size;
5908 mem = gen_rtx_MEM (BLKmode,
5909 plus_constant (save_area,
5910 first_reg_offset * reg_size));
5911 MEM_NOTRAP_P (mem) = 1;
5912 set_mem_alias_set (mem, set);
5913 set_mem_align (mem, BITS_PER_WORD);
5915 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
5916 nregs);
5919 /* Save FP registers if needed. */
5920 if (DEFAULT_ABI == ABI_V4
5921 && TARGET_HARD_FLOAT && TARGET_FPRS
5922 && ! no_rtl
5923 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5924 && cfun->va_list_fpr_size)
5926 int fregno = next_cum.fregno, nregs;
5927 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
5928 rtx lab = gen_label_rtx ();
5929 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
5930 * UNITS_PER_FP_WORD);
5932 emit_jump_insn
5933 (gen_rtx_SET (VOIDmode,
5934 pc_rtx,
5935 gen_rtx_IF_THEN_ELSE (VOIDmode,
5936 gen_rtx_NE (VOIDmode, cr1,
5937 const0_rtx),
5938 gen_rtx_LABEL_REF (VOIDmode, lab),
5939 pc_rtx)));
5941 for (nregs = 0;
5942 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
5943 fregno++, off += UNITS_PER_FP_WORD, nregs++)
5945 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
5946 MEM_NOTRAP_P (mem) = 1;
5947 set_mem_alias_set (mem, set);
5948 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
5949 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
5952 emit_label (lab);
5956 /* Create the va_list data type. */
5958 static tree
5959 rs6000_build_builtin_va_list (void)
5961 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
5963 /* For AIX, prefer 'char *' because that's what the system
5964 header files like. */
5965 if (DEFAULT_ABI != ABI_V4)
5966 return build_pointer_type (char_type_node);
5968 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5969 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5971 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
5972 unsigned_char_type_node);
5973 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
5974 unsigned_char_type_node);
5975 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
5976 every user file. */
5977 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
5978 short_unsigned_type_node);
5979 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
5980 ptr_type_node);
5981 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
5982 ptr_type_node);
5984 va_list_gpr_counter_field = f_gpr;
5985 va_list_fpr_counter_field = f_fpr;
5987 DECL_FIELD_CONTEXT (f_gpr) = record;
5988 DECL_FIELD_CONTEXT (f_fpr) = record;
5989 DECL_FIELD_CONTEXT (f_res) = record;
5990 DECL_FIELD_CONTEXT (f_ovf) = record;
5991 DECL_FIELD_CONTEXT (f_sav) = record;
5993 TREE_CHAIN (record) = type_decl;
5994 TYPE_NAME (record) = type_decl;
5995 TYPE_FIELDS (record) = f_gpr;
5996 TREE_CHAIN (f_gpr) = f_fpr;
5997 TREE_CHAIN (f_fpr) = f_res;
5998 TREE_CHAIN (f_res) = f_ovf;
5999 TREE_CHAIN (f_ovf) = f_sav;
6001 layout_type (record);
6003 /* The correct type is an array type of one element. */
6004 return build_array_type (record, build_index_type (size_zero_node));
6007 /* Implement va_start. */
6009 void
6010 rs6000_va_start (tree valist, rtx nextarg)
6012 HOST_WIDE_INT words, n_gpr, n_fpr;
6013 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6014 tree gpr, fpr, ovf, sav, t;
6016 /* Only SVR4 needs something special. */
6017 if (DEFAULT_ABI != ABI_V4)
6019 std_expand_builtin_va_start (valist, nextarg);
6020 return;
6023 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6024 f_fpr = TREE_CHAIN (f_gpr);
6025 f_res = TREE_CHAIN (f_fpr);
6026 f_ovf = TREE_CHAIN (f_res);
6027 f_sav = TREE_CHAIN (f_ovf);
6029 valist = build_va_arg_indirect_ref (valist);
6030 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6031 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6032 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6033 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6035 /* Count number of gp and fp argument registers used. */
6036 words = current_function_args_info.words;
6037 n_gpr = MIN (current_function_args_info.sysv_gregno - GP_ARG_MIN_REG,
6038 GP_ARG_NUM_REG);
6039 n_fpr = MIN (current_function_args_info.fregno - FP_ARG_MIN_REG,
6040 FP_ARG_NUM_REG);
6042 if (TARGET_DEBUG_ARG)
6043 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
6044 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
6045 words, n_gpr, n_fpr);
6047 if (cfun->va_list_gpr_size)
6049 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr,
6050 build_int_cst (NULL_TREE, n_gpr));
6051 TREE_SIDE_EFFECTS (t) = 1;
6052 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6055 if (cfun->va_list_fpr_size)
6057 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr,
6058 build_int_cst (NULL_TREE, n_fpr));
6059 TREE_SIDE_EFFECTS (t) = 1;
6060 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6063 /* Find the overflow area. */
6064 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6065 if (words != 0)
6066 t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t,
6067 build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
6068 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6069 TREE_SIDE_EFFECTS (t) = 1;
6070 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6072 /* If there were no va_arg invocations, don't set up the register
6073 save area. */
6074 if (!cfun->va_list_gpr_size
6075 && !cfun->va_list_fpr_size
6076 && n_gpr < GP_ARG_NUM_REG
6077 && n_fpr < FP_ARG_V4_MAX_REG)
6078 return;
6080 /* Find the register save area. */
6081 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
6082 if (cfun->machine->varargs_save_offset)
6083 t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
6084 build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
6085 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
6086 TREE_SIDE_EFFECTS (t) = 1;
6087 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6090 /* Implement va_arg. */
6092 tree
6093 rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
6095 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6096 tree gpr, fpr, ovf, sav, reg, t, u;
6097 int size, rsize, n_reg, sav_ofs, sav_scale;
6098 tree lab_false, lab_over, addr;
6099 int align;
6100 tree ptrtype = build_pointer_type (type);
6102 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
6104 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
6105 return build_va_arg_indirect_ref (t);
6108 if (DEFAULT_ABI != ABI_V4)
6110 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
6112 tree elem_type = TREE_TYPE (type);
6113 enum machine_mode elem_mode = TYPE_MODE (elem_type);
6114 int elem_size = GET_MODE_SIZE (elem_mode);
6116 if (elem_size < UNITS_PER_WORD)
6118 tree real_part, imag_part;
6119 tree post = NULL_TREE;
6121 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6122 &post);
6123 /* Copy the value into a temporary, lest the formal temporary
6124 be reused out from under us. */
6125 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
6126 append_to_statement_list (post, pre_p);
6128 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6129 post_p);
6131 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
6135 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6138 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6139 f_fpr = TREE_CHAIN (f_gpr);
6140 f_res = TREE_CHAIN (f_fpr);
6141 f_ovf = TREE_CHAIN (f_res);
6142 f_sav = TREE_CHAIN (f_ovf);
6144 valist = build_va_arg_indirect_ref (valist);
6145 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6146 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6147 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6148 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6150 size = int_size_in_bytes (type);
6151 rsize = (size + 3) / 4;
6152 align = 1;
6154 if (TARGET_HARD_FLOAT && TARGET_FPRS
6155 && (TYPE_MODE (type) == SFmode
6156 || TYPE_MODE (type) == DFmode
6157 || TYPE_MODE (type) == TFmode))
6159 /* FP args go in FP registers, if present. */
6160 reg = fpr;
6161 n_reg = (size + 7) / 8;
6162 sav_ofs = 8*4;
6163 sav_scale = 8;
6164 if (TYPE_MODE (type) != SFmode)
6165 align = 8;
6167 else
6169 /* Otherwise into GP registers. */
6170 reg = gpr;
6171 n_reg = rsize;
6172 sav_ofs = 0;
6173 sav_scale = 4;
6174 if (n_reg == 2)
6175 align = 8;
6178 /* Pull the value out of the saved registers.... */
6180 lab_over = NULL;
6181 addr = create_tmp_var (ptr_type_node, "addr");
6182 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
6184 /* AltiVec vectors never go in registers when -mabi=altivec. */
6185 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6186 align = 16;
6187 else
6189 lab_false = create_artificial_label ();
6190 lab_over = create_artificial_label ();
6192 /* Long long and SPE vectors are aligned in the registers.
6193 As are any other 2 gpr item such as complex int due to a
6194 historical mistake. */
6195 u = reg;
6196 if (n_reg == 2 && reg == gpr)
6198 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
6199 size_int (n_reg - 1));
6200 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
6203 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
6204 t = build2 (GE_EXPR, boolean_type_node, u, t);
6205 u = build1 (GOTO_EXPR, void_type_node, lab_false);
6206 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
6207 gimplify_and_add (t, pre_p);
6209 t = sav;
6210 if (sav_ofs)
6211 t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
6213 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
6214 u = build1 (CONVERT_EXPR, integer_type_node, u);
6215 u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
6216 t = build2 (PLUS_EXPR, ptr_type_node, t, u);
6218 t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6219 gimplify_and_add (t, pre_p);
6221 t = build1 (GOTO_EXPR, void_type_node, lab_over);
6222 gimplify_and_add (t, pre_p);
6224 t = build1 (LABEL_EXPR, void_type_node, lab_false);
6225 append_to_statement_list (t, pre_p);
6227 if ((n_reg == 2 && reg != gpr) || n_reg > 2)
6229 /* Ensure that we don't find any more args in regs.
6230 Alignment has taken care of the n_reg == 2 gpr case. */
6231 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (reg), reg, size_int (8));
6232 gimplify_and_add (t, pre_p);
6236 /* ... otherwise out of the overflow area. */
6238 /* Care for on-stack alignment if needed. */
6239 t = ovf;
6240 if (align != 1)
6242 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
6243 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
6244 build_int_cst (NULL_TREE, -align));
6246 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
6248 u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6249 gimplify_and_add (u, pre_p);
6251 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
6252 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6253 gimplify_and_add (t, pre_p);
6255 if (lab_over)
6257 t = build1 (LABEL_EXPR, void_type_node, lab_over);
6258 append_to_statement_list (t, pre_p);
6261 if (STRICT_ALIGNMENT
6262 && (TYPE_ALIGN (type)
6263 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
6265 /* The value (of type complex double, for example) may not be
6266 aligned in memory in the saved registers, so copy via a
6267 temporary. (This is the same code as used for SPARC.) */
6268 tree tmp = create_tmp_var (type, "va_arg_tmp");
6269 tree dest_addr = build_fold_addr_expr (tmp);
6271 tree copy = build_function_call_expr
6272 (implicit_built_in_decls[BUILT_IN_MEMCPY],
6273 tree_cons (NULL_TREE, dest_addr,
6274 tree_cons (NULL_TREE, addr,
6275 tree_cons (NULL_TREE, size_int (rsize * 4),
6276 NULL_TREE))));
6278 gimplify_and_add (copy, pre_p);
6279 addr = dest_addr;
6282 addr = fold_convert (ptrtype, addr);
6283 return build_va_arg_indirect_ref (addr);
6286 /* Builtins. */
6288 static void
6289 def_builtin (int mask, const char *name, tree type, int code)
6291 if (mask & target_flags)
6293 if (rs6000_builtin_decls[code])
6294 abort ();
6296 rs6000_builtin_decls[code] =
6297 add_builtin_function (name, type, code, BUILT_IN_MD,
6298 NULL, NULL_TREE);
6302 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6304 static const struct builtin_description bdesc_3arg[] =
6306 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
6307 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
6308 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
6309 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
6310 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
6311 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
6312 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
6313 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
6314 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
6315 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
6316 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
6317 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
6318 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
6319 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
6320 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
6321 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
6322 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
6323 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
6324 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
6325 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
6326 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
6327 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
6328 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
6330 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
6331 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
6332 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
6333 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
6334 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
6335 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
6336 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
6337 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
6338 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
6339 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
6340 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
6341 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
6342 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
6343 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
6344 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
6347 /* DST operations: void foo (void *, const int, const char). */
6349 static const struct builtin_description bdesc_dst[] =
6351 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
6352 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
6353 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
6354 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
6356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
6357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
6358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
6359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
6362 /* Simple binary operations: VECc = foo (VECa, VECb). */
6364 static struct builtin_description bdesc_2arg[] =
6366 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
6367 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
6368 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
6369 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
6370 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
6371 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
6372 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
6373 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
6374 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
6375 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
6376 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
6377 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
6378 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
6379 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
6380 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
6381 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
6382 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
6383 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
6384 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
6385 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
6386 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
6387 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
6388 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
6389 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
6390 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
6391 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
6392 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
6393 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
6394 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
6395 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
6396 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
6397 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
6398 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
6399 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
6400 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
6401 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
6402 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
6403 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
6404 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
6405 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
6406 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
6407 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
6408 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
6409 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
6410 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
6411 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
6412 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
6413 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
6414 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
6415 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
6416 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
6417 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
6418 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
6419 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
6420 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
6421 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
6422 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
6423 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
6424 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
6425 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
6426 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
6427 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
6428 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
6429 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
6430 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
6431 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
6432 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
6433 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
6434 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
6435 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
6436 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
6437 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
6438 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
6439 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
6440 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
6441 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
6442 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
6443 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
6444 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
6445 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
6446 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
6447 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
6448 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
6449 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
6450 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
6451 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
6452 { MASK_ALTIVEC, CODE_FOR_lshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
6453 { MASK_ALTIVEC, CODE_FOR_lshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
6454 { MASK_ALTIVEC, CODE_FOR_lshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
6455 { MASK_ALTIVEC, CODE_FOR_ashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
6456 { MASK_ALTIVEC, CODE_FOR_ashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
6457 { MASK_ALTIVEC, CODE_FOR_ashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
6458 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
6459 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
6460 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
6461 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
6462 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
6463 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
6464 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
6465 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
6466 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
6467 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
6468 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
6469 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
6470 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
6471 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
6472 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
6473 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
6474 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
6475 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
6476 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
6478 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
6479 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
6480 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
6481 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
6482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
6483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
6484 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
6485 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
6486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
6487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
6488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
6489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
6490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
6491 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
6492 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
6493 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
6494 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
6495 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
6496 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
6497 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
6498 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
6499 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
6500 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
6501 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
6502 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
6503 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
6504 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
6505 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
6506 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
6507 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
6508 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
6509 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
6510 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
6511 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
6512 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
6513 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
6514 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
6515 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
6516 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
6517 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
6518 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
6519 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
6520 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
6521 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
6522 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
6523 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
6524 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
6525 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
6526 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
6527 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
6528 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
6529 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
6530 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
6531 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
6532 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
6533 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
6534 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
6535 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
6536 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
6537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
6538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
6539 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
6540 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
6541 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
6542 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
6543 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
6544 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
6545 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
6546 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
6547 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
6548 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
6549 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
6550 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
6551 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
6552 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
6553 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
6554 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
6555 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
6556 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
6557 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
6558 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
6559 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
6560 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
6561 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
6562 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
6563 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
6564 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
6565 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
6566 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
6567 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
6568 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
6569 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
6570 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
6571 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
6572 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
6573 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
6574 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
6575 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
6576 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
6577 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
6578 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
6579 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
6580 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
6581 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
6582 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
6583 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
6584 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
6585 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
6586 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
6587 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
6588 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
6589 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
6590 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
6591 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
6592 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
6593 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
6594 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
6595 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
6596 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
6597 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
6598 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
6599 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
6600 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
6601 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
6602 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
6603 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
6604 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
6606 /* Place holder, leave as first spe builtin. */
6607 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
6608 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
6609 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
6610 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
6611 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
6612 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
6613 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
6614 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
6615 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
6616 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
6617 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
6618 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
6619 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
6620 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
6621 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
6622 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
6623 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
6624 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
6625 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
6626 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
6627 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
6628 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
6629 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
6630 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
6631 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
6632 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
6633 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
6634 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
6635 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
6636 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
6637 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
6638 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
6639 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
6640 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
6641 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
6642 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
6643 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
6644 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
6645 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
6646 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
6647 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
6648 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
6649 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
6650 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
6651 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
6652 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
6653 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
6654 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
6655 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
6656 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
6657 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
6658 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
6659 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
6660 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
6661 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
6662 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
6663 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
6664 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
6665 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
6666 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
6667 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
6668 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
6669 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
6670 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
6671 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
6672 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
6673 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
6674 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
6675 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
6676 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
6677 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
6678 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
6679 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
6680 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
6681 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
6682 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
6683 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
6684 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
6685 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
6686 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
6687 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
6688 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
6689 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
6690 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
6691 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
6692 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
6693 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
6694 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
6695 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
6696 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
6697 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
6698 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
6699 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
6700 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
6701 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
6702 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
6703 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
6704 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
6705 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
6706 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
6707 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
6708 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
6709 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
6710 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
6711 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
6712 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
6713 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
6714 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
6715 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
6717 /* SPE binary operations expecting a 5-bit unsigned literal. */
6718 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
6720 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
6721 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
6722 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
6723 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
6724 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
6725 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
6726 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
6727 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
6728 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
6729 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
6730 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
6731 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
6732 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
6733 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
6734 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
6735 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
6736 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
6737 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
6738 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
6739 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
6740 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
6741 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
6742 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
6743 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
6744 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
6745 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
6747 /* Place-holder. Leave as last binary SPE builtin. */
6748 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
6751 /* AltiVec predicates. */
6753 struct builtin_description_predicates
6755 const unsigned int mask;
6756 const enum insn_code icode;
6757 const char *opcode;
6758 const char *const name;
6759 const enum rs6000_builtins code;
6762 static const struct builtin_description_predicates bdesc_altivec_preds[] =
6764 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
6765 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
6766 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
6767 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
6768 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
6769 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
6770 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
6771 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
6772 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
6773 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
6774 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
6775 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
6776 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
6778 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
6779 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
6780 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
6783 /* SPE predicates. */
6784 static struct builtin_description bdesc_spe_predicates[] =
6786 /* Place-holder. Leave as first. */
6787 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
6788 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
6789 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
6790 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
6791 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
6792 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
6793 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
6794 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
6795 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
6796 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
6797 /* Place-holder. Leave as last. */
6798 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
6801 /* SPE evsel predicates. */
6802 static struct builtin_description bdesc_spe_evsel[] =
6804 /* Place-holder. Leave as first. */
6805 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
6806 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
6807 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
6808 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
6809 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
6810 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
6811 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
6812 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
6813 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
6814 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
6815 /* Place-holder. Leave as last. */
6816 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
6819 /* ABS* operations. */
6821 static const struct builtin_description bdesc_abs[] =
6823 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
6824 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
6825 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
6826 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
6827 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
6828 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
6829 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
6832 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6833 foo (VECa). */
6835 static struct builtin_description bdesc_1arg[] =
6837 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
6838 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
6839 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
6840 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
6841 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
6842 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
6843 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
6844 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
6845 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
6846 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
6847 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
6848 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
6849 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
6850 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
6851 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
6852 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
6853 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
6855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
6856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
6857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
6858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
6859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
6860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
6861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
6862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
6863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
6864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
6865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
6866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
6867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
6868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
6869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
6870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
6871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
6872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
6873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
6875 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6876 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6877 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
6878 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
6879 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
6880 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
6881 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
6882 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
6883 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
6884 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
6885 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
6886 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
6887 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
6888 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
6889 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
6890 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
6891 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
6892 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
6893 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
6894 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
6895 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
6896 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
6897 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
6898 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
6899 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
6900 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
6901 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
6902 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
6903 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
6904 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
6906 /* Place-holder. Leave as last unary SPE builtin. */
6907 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW }
6910 static rtx
6911 rs6000_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
6913 rtx pat;
6914 tree arg0 = TREE_VALUE (arglist);
6915 rtx op0 = expand_normal (arg0);
6916 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6917 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6919 if (icode == CODE_FOR_nothing)
6920 /* Builtin not supported on this processor. */
6921 return 0;
6923 /* If we got invalid arguments bail out before generating bad rtl. */
6924 if (arg0 == error_mark_node)
6925 return const0_rtx;
6927 if (icode == CODE_FOR_altivec_vspltisb
6928 || icode == CODE_FOR_altivec_vspltish
6929 || icode == CODE_FOR_altivec_vspltisw
6930 || icode == CODE_FOR_spe_evsplatfi
6931 || icode == CODE_FOR_spe_evsplati)
6933 /* Only allow 5-bit *signed* literals. */
6934 if (GET_CODE (op0) != CONST_INT
6935 || INTVAL (op0) > 15
6936 || INTVAL (op0) < -16)
6938 error ("argument 1 must be a 5-bit signed literal");
6939 return const0_rtx;
6943 if (target == 0
6944 || GET_MODE (target) != tmode
6945 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6946 target = gen_reg_rtx (tmode);
6948 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6949 op0 = copy_to_mode_reg (mode0, op0);
6951 pat = GEN_FCN (icode) (target, op0);
6952 if (! pat)
6953 return 0;
6954 emit_insn (pat);
6956 return target;
6959 static rtx
6960 altivec_expand_abs_builtin (enum insn_code icode, tree arglist, rtx target)
6962 rtx pat, scratch1, scratch2;
6963 tree arg0 = TREE_VALUE (arglist);
6964 rtx op0 = expand_normal (arg0);
6965 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6966 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6968 /* If we have invalid arguments, bail out before generating bad rtl. */
6969 if (arg0 == error_mark_node)
6970 return const0_rtx;
6972 if (target == 0
6973 || GET_MODE (target) != tmode
6974 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6975 target = gen_reg_rtx (tmode);
6977 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6978 op0 = copy_to_mode_reg (mode0, op0);
6980 scratch1 = gen_reg_rtx (mode0);
6981 scratch2 = gen_reg_rtx (mode0);
6983 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
6984 if (! pat)
6985 return 0;
6986 emit_insn (pat);
6988 return target;
6991 static rtx
6992 rs6000_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
6994 rtx pat;
6995 tree arg0 = TREE_VALUE (arglist);
6996 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6997 rtx op0 = expand_normal (arg0);
6998 rtx op1 = expand_normal (arg1);
6999 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7000 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7001 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7003 if (icode == CODE_FOR_nothing)
7004 /* Builtin not supported on this processor. */
7005 return 0;
7007 /* If we got invalid arguments bail out before generating bad rtl. */
7008 if (arg0 == error_mark_node || arg1 == error_mark_node)
7009 return const0_rtx;
7011 if (icode == CODE_FOR_altivec_vcfux
7012 || icode == CODE_FOR_altivec_vcfsx
7013 || icode == CODE_FOR_altivec_vctsxs
7014 || icode == CODE_FOR_altivec_vctuxs
7015 || icode == CODE_FOR_altivec_vspltb
7016 || icode == CODE_FOR_altivec_vsplth
7017 || icode == CODE_FOR_altivec_vspltw
7018 || icode == CODE_FOR_spe_evaddiw
7019 || icode == CODE_FOR_spe_evldd
7020 || icode == CODE_FOR_spe_evldh
7021 || icode == CODE_FOR_spe_evldw
7022 || icode == CODE_FOR_spe_evlhhesplat
7023 || icode == CODE_FOR_spe_evlhhossplat
7024 || icode == CODE_FOR_spe_evlhhousplat
7025 || icode == CODE_FOR_spe_evlwhe
7026 || icode == CODE_FOR_spe_evlwhos
7027 || icode == CODE_FOR_spe_evlwhou
7028 || icode == CODE_FOR_spe_evlwhsplat
7029 || icode == CODE_FOR_spe_evlwwsplat
7030 || icode == CODE_FOR_spe_evrlwi
7031 || icode == CODE_FOR_spe_evslwi
7032 || icode == CODE_FOR_spe_evsrwis
7033 || icode == CODE_FOR_spe_evsubifw
7034 || icode == CODE_FOR_spe_evsrwiu)
7036 /* Only allow 5-bit unsigned literals. */
7037 STRIP_NOPS (arg1);
7038 if (TREE_CODE (arg1) != INTEGER_CST
7039 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7041 error ("argument 2 must be a 5-bit unsigned literal");
7042 return const0_rtx;
7046 if (target == 0
7047 || GET_MODE (target) != tmode
7048 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7049 target = gen_reg_rtx (tmode);
7051 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7052 op0 = copy_to_mode_reg (mode0, op0);
7053 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7054 op1 = copy_to_mode_reg (mode1, op1);
7056 pat = GEN_FCN (icode) (target, op0, op1);
7057 if (! pat)
7058 return 0;
7059 emit_insn (pat);
7061 return target;
7064 static rtx
7065 altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
7066 tree arglist, rtx target)
7068 rtx pat, scratch;
7069 tree cr6_form = TREE_VALUE (arglist);
7070 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
7071 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7072 rtx op0 = expand_normal (arg0);
7073 rtx op1 = expand_normal (arg1);
7074 enum machine_mode tmode = SImode;
7075 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7076 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7077 int cr6_form_int;
7079 if (TREE_CODE (cr6_form) != INTEGER_CST)
7081 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7082 return const0_rtx;
7084 else
7085 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
7087 gcc_assert (mode0 == mode1);
7089 /* If we have invalid arguments, bail out before generating bad rtl. */
7090 if (arg0 == error_mark_node || arg1 == error_mark_node)
7091 return const0_rtx;
7093 if (target == 0
7094 || GET_MODE (target) != tmode
7095 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7096 target = gen_reg_rtx (tmode);
7098 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7099 op0 = copy_to_mode_reg (mode0, op0);
7100 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7101 op1 = copy_to_mode_reg (mode1, op1);
7103 scratch = gen_reg_rtx (mode0);
7105 pat = GEN_FCN (icode) (scratch, op0, op1,
7106 gen_rtx_SYMBOL_REF (Pmode, opcode));
7107 if (! pat)
7108 return 0;
7109 emit_insn (pat);
7111 /* The vec_any* and vec_all* predicates use the same opcodes for two
7112 different operations, but the bits in CR6 will be different
7113 depending on what information we want. So we have to play tricks
7114 with CR6 to get the right bits out.
7116 If you think this is disgusting, look at the specs for the
7117 AltiVec predicates. */
7119 switch (cr6_form_int)
7121 case 0:
7122 emit_insn (gen_cr6_test_for_zero (target));
7123 break;
7124 case 1:
7125 emit_insn (gen_cr6_test_for_zero_reverse (target));
7126 break;
7127 case 2:
7128 emit_insn (gen_cr6_test_for_lt (target));
7129 break;
7130 case 3:
7131 emit_insn (gen_cr6_test_for_lt_reverse (target));
7132 break;
7133 default:
7134 error ("argument 1 of __builtin_altivec_predicate is out of range");
7135 break;
7138 return target;
7141 static rtx
7142 altivec_expand_lv_builtin (enum insn_code icode, tree arglist, rtx target)
7144 rtx pat, addr;
7145 tree arg0 = TREE_VALUE (arglist);
7146 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7147 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7148 enum machine_mode mode0 = Pmode;
7149 enum machine_mode mode1 = Pmode;
7150 rtx op0 = expand_normal (arg0);
7151 rtx op1 = expand_normal (arg1);
7153 if (icode == CODE_FOR_nothing)
7154 /* Builtin not supported on this processor. */
7155 return 0;
7157 /* If we got invalid arguments bail out before generating bad rtl. */
7158 if (arg0 == error_mark_node || arg1 == error_mark_node)
7159 return const0_rtx;
7161 if (target == 0
7162 || GET_MODE (target) != tmode
7163 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7164 target = gen_reg_rtx (tmode);
7166 op1 = copy_to_mode_reg (mode1, op1);
7168 if (op0 == const0_rtx)
7170 addr = gen_rtx_MEM (tmode, op1);
7172 else
7174 op0 = copy_to_mode_reg (mode0, op0);
7175 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7178 pat = GEN_FCN (icode) (target, addr);
7180 if (! pat)
7181 return 0;
7182 emit_insn (pat);
7184 return target;
7187 static rtx
7188 spe_expand_stv_builtin (enum insn_code icode, tree arglist)
7190 tree arg0 = TREE_VALUE (arglist);
7191 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7192 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7193 rtx op0 = expand_normal (arg0);
7194 rtx op1 = expand_normal (arg1);
7195 rtx op2 = expand_normal (arg2);
7196 rtx pat;
7197 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
7198 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
7199 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
7201 /* Invalid arguments. Bail before doing anything stoopid! */
7202 if (arg0 == error_mark_node
7203 || arg1 == error_mark_node
7204 || arg2 == error_mark_node)
7205 return const0_rtx;
7207 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
7208 op0 = copy_to_mode_reg (mode2, op0);
7209 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
7210 op1 = copy_to_mode_reg (mode0, op1);
7211 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7212 op2 = copy_to_mode_reg (mode1, op2);
7214 pat = GEN_FCN (icode) (op1, op2, op0);
7215 if (pat)
7216 emit_insn (pat);
7217 return NULL_RTX;
7220 static rtx
7221 altivec_expand_stv_builtin (enum insn_code icode, tree arglist)
7223 tree arg0 = TREE_VALUE (arglist);
7224 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7225 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7226 rtx op0 = expand_normal (arg0);
7227 rtx op1 = expand_normal (arg1);
7228 rtx op2 = expand_normal (arg2);
7229 rtx pat, addr;
7230 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7231 enum machine_mode mode1 = Pmode;
7232 enum machine_mode mode2 = Pmode;
7234 /* Invalid arguments. Bail before doing anything stoopid! */
7235 if (arg0 == error_mark_node
7236 || arg1 == error_mark_node
7237 || arg2 == error_mark_node)
7238 return const0_rtx;
7240 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
7241 op0 = copy_to_mode_reg (tmode, op0);
7243 op2 = copy_to_mode_reg (mode2, op2);
7245 if (op1 == const0_rtx)
7247 addr = gen_rtx_MEM (tmode, op2);
7249 else
7251 op1 = copy_to_mode_reg (mode1, op1);
7252 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
7255 pat = GEN_FCN (icode) (addr, op0);
7256 if (pat)
7257 emit_insn (pat);
7258 return NULL_RTX;
7261 static rtx
7262 rs6000_expand_ternop_builtin (enum insn_code icode, tree arglist, rtx target)
7264 rtx pat;
7265 tree arg0 = TREE_VALUE (arglist);
7266 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7267 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7268 rtx op0 = expand_normal (arg0);
7269 rtx op1 = expand_normal (arg1);
7270 rtx op2 = expand_normal (arg2);
7271 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7272 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7273 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7274 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
7276 if (icode == CODE_FOR_nothing)
7277 /* Builtin not supported on this processor. */
7278 return 0;
7280 /* If we got invalid arguments bail out before generating bad rtl. */
7281 if (arg0 == error_mark_node
7282 || arg1 == error_mark_node
7283 || arg2 == error_mark_node)
7284 return const0_rtx;
7286 if (icode == CODE_FOR_altivec_vsldoi_v4sf
7287 || icode == CODE_FOR_altivec_vsldoi_v4si
7288 || icode == CODE_FOR_altivec_vsldoi_v8hi
7289 || icode == CODE_FOR_altivec_vsldoi_v16qi)
7291 /* Only allow 4-bit unsigned literals. */
7292 STRIP_NOPS (arg2);
7293 if (TREE_CODE (arg2) != INTEGER_CST
7294 || TREE_INT_CST_LOW (arg2) & ~0xf)
7296 error ("argument 3 must be a 4-bit unsigned literal");
7297 return const0_rtx;
7301 if (target == 0
7302 || GET_MODE (target) != tmode
7303 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7304 target = gen_reg_rtx (tmode);
7306 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7307 op0 = copy_to_mode_reg (mode0, op0);
7308 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7309 op1 = copy_to_mode_reg (mode1, op1);
7310 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
7311 op2 = copy_to_mode_reg (mode2, op2);
7313 pat = GEN_FCN (icode) (target, op0, op1, op2);
7314 if (! pat)
7315 return 0;
7316 emit_insn (pat);
7318 return target;
7321 /* Expand the lvx builtins. */
7322 static rtx
7323 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
7325 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7326 tree arglist = TREE_OPERAND (exp, 1);
7327 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7328 tree arg0;
7329 enum machine_mode tmode, mode0;
7330 rtx pat, op0;
7331 enum insn_code icode;
7333 switch (fcode)
7335 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
7336 icode = CODE_FOR_altivec_lvx_v16qi;
7337 break;
7338 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
7339 icode = CODE_FOR_altivec_lvx_v8hi;
7340 break;
7341 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
7342 icode = CODE_FOR_altivec_lvx_v4si;
7343 break;
7344 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
7345 icode = CODE_FOR_altivec_lvx_v4sf;
7346 break;
7347 default:
7348 *expandedp = false;
7349 return NULL_RTX;
7352 *expandedp = true;
7354 arg0 = TREE_VALUE (arglist);
7355 op0 = expand_normal (arg0);
7356 tmode = insn_data[icode].operand[0].mode;
7357 mode0 = insn_data[icode].operand[1].mode;
7359 if (target == 0
7360 || GET_MODE (target) != tmode
7361 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7362 target = gen_reg_rtx (tmode);
7364 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7365 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7367 pat = GEN_FCN (icode) (target, op0);
7368 if (! pat)
7369 return 0;
7370 emit_insn (pat);
7371 return target;
7374 /* Expand the stvx builtins. */
7375 static rtx
7376 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
7377 bool *expandedp)
7379 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7380 tree arglist = TREE_OPERAND (exp, 1);
7381 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7382 tree arg0, arg1;
7383 enum machine_mode mode0, mode1;
7384 rtx pat, op0, op1;
7385 enum insn_code icode;
7387 switch (fcode)
7389 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
7390 icode = CODE_FOR_altivec_stvx_v16qi;
7391 break;
7392 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
7393 icode = CODE_FOR_altivec_stvx_v8hi;
7394 break;
7395 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
7396 icode = CODE_FOR_altivec_stvx_v4si;
7397 break;
7398 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
7399 icode = CODE_FOR_altivec_stvx_v4sf;
7400 break;
7401 default:
7402 *expandedp = false;
7403 return NULL_RTX;
7406 arg0 = TREE_VALUE (arglist);
7407 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7408 op0 = expand_normal (arg0);
7409 op1 = expand_normal (arg1);
7410 mode0 = insn_data[icode].operand[0].mode;
7411 mode1 = insn_data[icode].operand[1].mode;
7413 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7414 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7415 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7416 op1 = copy_to_mode_reg (mode1, op1);
7418 pat = GEN_FCN (icode) (op0, op1);
7419 if (pat)
7420 emit_insn (pat);
7422 *expandedp = true;
7423 return NULL_RTX;
7426 /* Expand the dst builtins. */
7427 static rtx
7428 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
7429 bool *expandedp)
7431 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7432 tree arglist = TREE_OPERAND (exp, 1);
7433 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7434 tree arg0, arg1, arg2;
7435 enum machine_mode mode0, mode1, mode2;
7436 rtx pat, op0, op1, op2;
7437 struct builtin_description *d;
7438 size_t i;
7440 *expandedp = false;
7442 /* Handle DST variants. */
7443 d = (struct builtin_description *) bdesc_dst;
7444 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
7445 if (d->code == fcode)
7447 arg0 = TREE_VALUE (arglist);
7448 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7449 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7450 op0 = expand_normal (arg0);
7451 op1 = expand_normal (arg1);
7452 op2 = expand_normal (arg2);
7453 mode0 = insn_data[d->icode].operand[0].mode;
7454 mode1 = insn_data[d->icode].operand[1].mode;
7455 mode2 = insn_data[d->icode].operand[2].mode;
7457 /* Invalid arguments, bail out before generating bad rtl. */
7458 if (arg0 == error_mark_node
7459 || arg1 == error_mark_node
7460 || arg2 == error_mark_node)
7461 return const0_rtx;
7463 *expandedp = true;
7464 STRIP_NOPS (arg2);
7465 if (TREE_CODE (arg2) != INTEGER_CST
7466 || TREE_INT_CST_LOW (arg2) & ~0x3)
7468 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
7469 return const0_rtx;
7472 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
7473 op0 = copy_to_mode_reg (Pmode, op0);
7474 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
7475 op1 = copy_to_mode_reg (mode1, op1);
7477 pat = GEN_FCN (d->icode) (op0, op1, op2);
7478 if (pat != 0)
7479 emit_insn (pat);
7481 return NULL_RTX;
7484 return NULL_RTX;
7487 /* Expand vec_init builtin. */
7488 static rtx
7489 altivec_expand_vec_init_builtin (tree type, tree arglist, rtx target)
7491 enum machine_mode tmode = TYPE_MODE (type);
7492 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
7493 int i, n_elt = GET_MODE_NUNITS (tmode);
7494 rtvec v = rtvec_alloc (n_elt);
7496 gcc_assert (VECTOR_MODE_P (tmode));
7498 for (i = 0; i < n_elt; ++i, arglist = TREE_CHAIN (arglist))
7500 rtx x = expand_normal (TREE_VALUE (arglist));
7501 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
7504 gcc_assert (arglist == NULL);
7506 if (!target || !register_operand (target, tmode))
7507 target = gen_reg_rtx (tmode);
7509 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
7510 return target;
7513 /* Return the integer constant in ARG. Constrain it to be in the range
7514 of the subparts of VEC_TYPE; issue an error if not. */
7516 static int
7517 get_element_number (tree vec_type, tree arg)
7519 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
7521 if (!host_integerp (arg, 1)
7522 || (elt = tree_low_cst (arg, 1), elt > max))
7524 error ("selector must be an integer constant in the range 0..%wi", max);
7525 return 0;
7528 return elt;
7531 /* Expand vec_set builtin. */
7532 static rtx
7533 altivec_expand_vec_set_builtin (tree arglist)
7535 enum machine_mode tmode, mode1;
7536 tree arg0, arg1, arg2;
7537 int elt;
7538 rtx op0, op1;
7540 arg0 = TREE_VALUE (arglist);
7541 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7542 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7544 tmode = TYPE_MODE (TREE_TYPE (arg0));
7545 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7546 gcc_assert (VECTOR_MODE_P (tmode));
7548 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
7549 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
7550 elt = get_element_number (TREE_TYPE (arg0), arg2);
7552 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
7553 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
7555 op0 = force_reg (tmode, op0);
7556 op1 = force_reg (mode1, op1);
7558 rs6000_expand_vector_set (op0, op1, elt);
7560 return op0;
7563 /* Expand vec_ext builtin. */
7564 static rtx
7565 altivec_expand_vec_ext_builtin (tree arglist, rtx target)
7567 enum machine_mode tmode, mode0;
7568 tree arg0, arg1;
7569 int elt;
7570 rtx op0;
7572 arg0 = TREE_VALUE (arglist);
7573 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7575 op0 = expand_normal (arg0);
7576 elt = get_element_number (TREE_TYPE (arg0), arg1);
7578 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7579 mode0 = TYPE_MODE (TREE_TYPE (arg0));
7580 gcc_assert (VECTOR_MODE_P (mode0));
7582 op0 = force_reg (mode0, op0);
7584 if (optimize || !target || !register_operand (target, tmode))
7585 target = gen_reg_rtx (tmode);
7587 rs6000_expand_vector_extract (target, op0, elt);
7589 return target;
7592 /* Expand the builtin in EXP and store the result in TARGET. Store
7593 true in *EXPANDEDP if we found a builtin to expand. */
7594 static rtx
7595 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
7597 struct builtin_description *d;
7598 struct builtin_description_predicates *dp;
7599 size_t i;
7600 enum insn_code icode;
7601 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7602 tree arglist = TREE_OPERAND (exp, 1);
7603 tree arg0;
7604 rtx op0, pat;
7605 enum machine_mode tmode, mode0;
7606 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7608 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7609 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
7611 *expandedp = true;
7612 error ("unresolved overload for Altivec builtin %qF", fndecl);
7613 return const0_rtx;
7616 target = altivec_expand_ld_builtin (exp, target, expandedp);
7617 if (*expandedp)
7618 return target;
7620 target = altivec_expand_st_builtin (exp, target, expandedp);
7621 if (*expandedp)
7622 return target;
7624 target = altivec_expand_dst_builtin (exp, target, expandedp);
7625 if (*expandedp)
7626 return target;
7628 *expandedp = true;
7630 switch (fcode)
7632 case ALTIVEC_BUILTIN_STVX:
7633 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
7634 case ALTIVEC_BUILTIN_STVEBX:
7635 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
7636 case ALTIVEC_BUILTIN_STVEHX:
7637 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
7638 case ALTIVEC_BUILTIN_STVEWX:
7639 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
7640 case ALTIVEC_BUILTIN_STVXL:
7641 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
7643 case ALTIVEC_BUILTIN_MFVSCR:
7644 icode = CODE_FOR_altivec_mfvscr;
7645 tmode = insn_data[icode].operand[0].mode;
7647 if (target == 0
7648 || GET_MODE (target) != tmode
7649 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7650 target = gen_reg_rtx (tmode);
7652 pat = GEN_FCN (icode) (target);
7653 if (! pat)
7654 return 0;
7655 emit_insn (pat);
7656 return target;
7658 case ALTIVEC_BUILTIN_MTVSCR:
7659 icode = CODE_FOR_altivec_mtvscr;
7660 arg0 = TREE_VALUE (arglist);
7661 op0 = expand_normal (arg0);
7662 mode0 = insn_data[icode].operand[0].mode;
7664 /* If we got invalid arguments bail out before generating bad rtl. */
7665 if (arg0 == error_mark_node)
7666 return const0_rtx;
7668 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7669 op0 = copy_to_mode_reg (mode0, op0);
7671 pat = GEN_FCN (icode) (op0);
7672 if (pat)
7673 emit_insn (pat);
7674 return NULL_RTX;
7676 case ALTIVEC_BUILTIN_DSSALL:
7677 emit_insn (gen_altivec_dssall ());
7678 return NULL_RTX;
7680 case ALTIVEC_BUILTIN_DSS:
7681 icode = CODE_FOR_altivec_dss;
7682 arg0 = TREE_VALUE (arglist);
7683 STRIP_NOPS (arg0);
7684 op0 = expand_normal (arg0);
7685 mode0 = insn_data[icode].operand[0].mode;
7687 /* If we got invalid arguments bail out before generating bad rtl. */
7688 if (arg0 == error_mark_node)
7689 return const0_rtx;
7691 if (TREE_CODE (arg0) != INTEGER_CST
7692 || TREE_INT_CST_LOW (arg0) & ~0x3)
7694 error ("argument to dss must be a 2-bit unsigned literal");
7695 return const0_rtx;
7698 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7699 op0 = copy_to_mode_reg (mode0, op0);
7701 emit_insn (gen_altivec_dss (op0));
7702 return NULL_RTX;
7704 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
7705 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
7706 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
7707 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
7708 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), arglist, target);
7710 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
7711 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
7712 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
7713 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
7714 return altivec_expand_vec_set_builtin (arglist);
7716 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
7717 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
7718 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
7719 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
7720 return altivec_expand_vec_ext_builtin (arglist, target);
7722 default:
7723 break;
7724 /* Fall through. */
7727 /* Expand abs* operations. */
7728 d = (struct builtin_description *) bdesc_abs;
7729 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
7730 if (d->code == fcode)
7731 return altivec_expand_abs_builtin (d->icode, arglist, target);
7733 /* Expand the AltiVec predicates. */
7734 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
7735 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
7736 if (dp->code == fcode)
7737 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
7738 arglist, target);
7740 /* LV* are funky. We initialized them differently. */
7741 switch (fcode)
7743 case ALTIVEC_BUILTIN_LVSL:
7744 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
7745 arglist, target);
7746 case ALTIVEC_BUILTIN_LVSR:
7747 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
7748 arglist, target);
7749 case ALTIVEC_BUILTIN_LVEBX:
7750 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
7751 arglist, target);
7752 case ALTIVEC_BUILTIN_LVEHX:
7753 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
7754 arglist, target);
7755 case ALTIVEC_BUILTIN_LVEWX:
7756 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
7757 arglist, target);
7758 case ALTIVEC_BUILTIN_LVXL:
7759 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
7760 arglist, target);
7761 case ALTIVEC_BUILTIN_LVX:
7762 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
7763 arglist, target);
7764 default:
7765 break;
7766 /* Fall through. */
7769 *expandedp = false;
7770 return NULL_RTX;
7773 /* Binops that need to be initialized manually, but can be expanded
7774 automagically by rs6000_expand_binop_builtin. */
7775 static struct builtin_description bdesc_2arg_spe[] =
7777 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
7778 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
7779 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
7780 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
7781 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
7782 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
7783 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
7784 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
7785 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
7786 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
7787 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
7788 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
7789 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
7790 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
7791 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
7792 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
7793 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
7794 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
7795 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
7796 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
7797 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
7798 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
7801 /* Expand the builtin in EXP and store the result in TARGET. Store
7802 true in *EXPANDEDP if we found a builtin to expand.
7804 This expands the SPE builtins that are not simple unary and binary
7805 operations. */
7806 static rtx
7807 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
7809 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7810 tree arglist = TREE_OPERAND (exp, 1);
7811 tree arg1, arg0;
7812 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7813 enum insn_code icode;
7814 enum machine_mode tmode, mode0;
7815 rtx pat, op0;
7816 struct builtin_description *d;
7817 size_t i;
7819 *expandedp = true;
7821 /* Syntax check for a 5-bit unsigned immediate. */
7822 switch (fcode)
7824 case SPE_BUILTIN_EVSTDD:
7825 case SPE_BUILTIN_EVSTDH:
7826 case SPE_BUILTIN_EVSTDW:
7827 case SPE_BUILTIN_EVSTWHE:
7828 case SPE_BUILTIN_EVSTWHO:
7829 case SPE_BUILTIN_EVSTWWE:
7830 case SPE_BUILTIN_EVSTWWO:
7831 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7832 if (TREE_CODE (arg1) != INTEGER_CST
7833 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7835 error ("argument 2 must be a 5-bit unsigned literal");
7836 return const0_rtx;
7838 break;
7839 default:
7840 break;
7843 /* The evsplat*i instructions are not quite generic. */
7844 switch (fcode)
7846 case SPE_BUILTIN_EVSPLATFI:
7847 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
7848 arglist, target);
7849 case SPE_BUILTIN_EVSPLATI:
7850 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
7851 arglist, target);
7852 default:
7853 break;
7856 d = (struct builtin_description *) bdesc_2arg_spe;
7857 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
7858 if (d->code == fcode)
7859 return rs6000_expand_binop_builtin (d->icode, arglist, target);
7861 d = (struct builtin_description *) bdesc_spe_predicates;
7862 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
7863 if (d->code == fcode)
7864 return spe_expand_predicate_builtin (d->icode, arglist, target);
7866 d = (struct builtin_description *) bdesc_spe_evsel;
7867 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
7868 if (d->code == fcode)
7869 return spe_expand_evsel_builtin (d->icode, arglist, target);
7871 switch (fcode)
7873 case SPE_BUILTIN_EVSTDDX:
7874 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
7875 case SPE_BUILTIN_EVSTDHX:
7876 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
7877 case SPE_BUILTIN_EVSTDWX:
7878 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
7879 case SPE_BUILTIN_EVSTWHEX:
7880 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
7881 case SPE_BUILTIN_EVSTWHOX:
7882 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
7883 case SPE_BUILTIN_EVSTWWEX:
7884 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
7885 case SPE_BUILTIN_EVSTWWOX:
7886 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
7887 case SPE_BUILTIN_EVSTDD:
7888 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
7889 case SPE_BUILTIN_EVSTDH:
7890 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
7891 case SPE_BUILTIN_EVSTDW:
7892 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
7893 case SPE_BUILTIN_EVSTWHE:
7894 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
7895 case SPE_BUILTIN_EVSTWHO:
7896 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
7897 case SPE_BUILTIN_EVSTWWE:
7898 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
7899 case SPE_BUILTIN_EVSTWWO:
7900 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
7901 case SPE_BUILTIN_MFSPEFSCR:
7902 icode = CODE_FOR_spe_mfspefscr;
7903 tmode = insn_data[icode].operand[0].mode;
7905 if (target == 0
7906 || GET_MODE (target) != tmode
7907 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7908 target = gen_reg_rtx (tmode);
7910 pat = GEN_FCN (icode) (target);
7911 if (! pat)
7912 return 0;
7913 emit_insn (pat);
7914 return target;
7915 case SPE_BUILTIN_MTSPEFSCR:
7916 icode = CODE_FOR_spe_mtspefscr;
7917 arg0 = TREE_VALUE (arglist);
7918 op0 = expand_normal (arg0);
7919 mode0 = insn_data[icode].operand[0].mode;
7921 if (arg0 == error_mark_node)
7922 return const0_rtx;
7924 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7925 op0 = copy_to_mode_reg (mode0, op0);
7927 pat = GEN_FCN (icode) (op0);
7928 if (pat)
7929 emit_insn (pat);
7930 return NULL_RTX;
7931 default:
7932 break;
7935 *expandedp = false;
7936 return NULL_RTX;
7939 static rtx
7940 spe_expand_predicate_builtin (enum insn_code icode, tree arglist, rtx target)
7942 rtx pat, scratch, tmp;
7943 tree form = TREE_VALUE (arglist);
7944 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
7945 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7946 rtx op0 = expand_normal (arg0);
7947 rtx op1 = expand_normal (arg1);
7948 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7949 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7950 int form_int;
7951 enum rtx_code code;
7953 if (TREE_CODE (form) != INTEGER_CST)
7955 error ("argument 1 of __builtin_spe_predicate must be a constant");
7956 return const0_rtx;
7958 else
7959 form_int = TREE_INT_CST_LOW (form);
7961 gcc_assert (mode0 == mode1);
7963 if (arg0 == error_mark_node || arg1 == error_mark_node)
7964 return const0_rtx;
7966 if (target == 0
7967 || GET_MODE (target) != SImode
7968 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
7969 target = gen_reg_rtx (SImode);
7971 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7972 op0 = copy_to_mode_reg (mode0, op0);
7973 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7974 op1 = copy_to_mode_reg (mode1, op1);
7976 scratch = gen_reg_rtx (CCmode);
7978 pat = GEN_FCN (icode) (scratch, op0, op1);
7979 if (! pat)
7980 return const0_rtx;
7981 emit_insn (pat);
7983 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
7984 _lower_. We use one compare, but look in different bits of the
7985 CR for each variant.
7987 There are 2 elements in each SPE simd type (upper/lower). The CR
7988 bits are set as follows:
7990 BIT0 | BIT 1 | BIT 2 | BIT 3
7991 U | L | (U | L) | (U & L)
7993 So, for an "all" relationship, BIT 3 would be set.
7994 For an "any" relationship, BIT 2 would be set. Etc.
7996 Following traditional nomenclature, these bits map to:
7998 BIT0 | BIT 1 | BIT 2 | BIT 3
7999 LT | GT | EQ | OV
8001 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8004 switch (form_int)
8006 /* All variant. OV bit. */
8007 case 0:
8008 /* We need to get to the OV bit, which is the ORDERED bit. We
8009 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
8010 that's ugly and will make validate_condition_mode die.
8011 So let's just use another pattern. */
8012 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
8013 return target;
8014 /* Any variant. EQ bit. */
8015 case 1:
8016 code = EQ;
8017 break;
8018 /* Upper variant. LT bit. */
8019 case 2:
8020 code = LT;
8021 break;
8022 /* Lower variant. GT bit. */
8023 case 3:
8024 code = GT;
8025 break;
8026 default:
8027 error ("argument 1 of __builtin_spe_predicate is out of range");
8028 return const0_rtx;
8031 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8032 emit_move_insn (target, tmp);
8034 return target;
8037 /* The evsel builtins look like this:
8039 e = __builtin_spe_evsel_OP (a, b, c, d);
8041 and work like this:
8043 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8044 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8047 static rtx
8048 spe_expand_evsel_builtin (enum insn_code icode, tree arglist, rtx target)
8050 rtx pat, scratch;
8051 tree arg0 = TREE_VALUE (arglist);
8052 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8053 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8054 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
8055 rtx op0 = expand_normal (arg0);
8056 rtx op1 = expand_normal (arg1);
8057 rtx op2 = expand_normal (arg2);
8058 rtx op3 = expand_normal (arg3);
8059 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8060 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8062 gcc_assert (mode0 == mode1);
8064 if (arg0 == error_mark_node || arg1 == error_mark_node
8065 || arg2 == error_mark_node || arg3 == error_mark_node)
8066 return const0_rtx;
8068 if (target == 0
8069 || GET_MODE (target) != mode0
8070 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
8071 target = gen_reg_rtx (mode0);
8073 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8074 op0 = copy_to_mode_reg (mode0, op0);
8075 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
8076 op1 = copy_to_mode_reg (mode0, op1);
8077 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
8078 op2 = copy_to_mode_reg (mode0, op2);
8079 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
8080 op3 = copy_to_mode_reg (mode0, op3);
8082 /* Generate the compare. */
8083 scratch = gen_reg_rtx (CCmode);
8084 pat = GEN_FCN (icode) (scratch, op0, op1);
8085 if (! pat)
8086 return const0_rtx;
8087 emit_insn (pat);
8089 if (mode0 == V2SImode)
8090 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
8091 else
8092 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
8094 return target;
8097 /* Expand an expression EXP that calls a built-in function,
8098 with result going to TARGET if that's convenient
8099 (and in mode MODE if that's convenient).
8100 SUBTARGET may be used as the target for computing one of EXP's operands.
8101 IGNORE is nonzero if the value is to be ignored. */
8103 static rtx
8104 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8105 enum machine_mode mode ATTRIBUTE_UNUSED,
8106 int ignore ATTRIBUTE_UNUSED)
8108 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8109 tree arglist = TREE_OPERAND (exp, 1);
8110 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8111 struct builtin_description *d;
8112 size_t i;
8113 rtx ret;
8114 bool success;
8116 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
8117 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
8119 int icode = (int) CODE_FOR_altivec_lvsr;
8120 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8121 enum machine_mode mode = insn_data[icode].operand[1].mode;
8122 tree arg;
8123 rtx op, addr, pat;
8125 gcc_assert (TARGET_ALTIVEC);
8127 arg = TREE_VALUE (arglist);
8128 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
8129 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
8130 addr = memory_address (mode, op);
8131 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
8132 op = addr;
8133 else
8135 /* For the load case need to negate the address. */
8136 op = gen_reg_rtx (GET_MODE (addr));
8137 emit_insn (gen_rtx_SET (VOIDmode, op,
8138 gen_rtx_NEG (GET_MODE (addr), addr)));
8140 op = gen_rtx_MEM (mode, op);
8142 if (target == 0
8143 || GET_MODE (target) != tmode
8144 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8145 target = gen_reg_rtx (tmode);
8147 /*pat = gen_altivec_lvsr (target, op);*/
8148 pat = GEN_FCN (icode) (target, op);
8149 if (!pat)
8150 return 0;
8151 emit_insn (pat);
8153 return target;
8156 if (TARGET_ALTIVEC)
8158 ret = altivec_expand_builtin (exp, target, &success);
8160 if (success)
8161 return ret;
8163 if (TARGET_SPE)
8165 ret = spe_expand_builtin (exp, target, &success);
8167 if (success)
8168 return ret;
8171 gcc_assert (TARGET_ALTIVEC || TARGET_SPE);
8173 /* Handle simple unary operations. */
8174 d = (struct builtin_description *) bdesc_1arg;
8175 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
8176 if (d->code == fcode)
8177 return rs6000_expand_unop_builtin (d->icode, arglist, target);
8179 /* Handle simple binary operations. */
8180 d = (struct builtin_description *) bdesc_2arg;
8181 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
8182 if (d->code == fcode)
8183 return rs6000_expand_binop_builtin (d->icode, arglist, target);
8185 /* Handle simple ternary operations. */
8186 d = (struct builtin_description *) bdesc_3arg;
8187 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
8188 if (d->code == fcode)
8189 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
8191 gcc_unreachable ();
8194 static tree
8195 build_opaque_vector_type (tree node, int nunits)
8197 node = copy_node (node);
8198 TYPE_MAIN_VARIANT (node) = node;
8199 return build_vector_type (node, nunits);
8202 static void
8203 rs6000_init_builtins (void)
8205 V2SI_type_node = build_vector_type (intSI_type_node, 2);
8206 V2SF_type_node = build_vector_type (float_type_node, 2);
8207 V4HI_type_node = build_vector_type (intHI_type_node, 4);
8208 V4SI_type_node = build_vector_type (intSI_type_node, 4);
8209 V4SF_type_node = build_vector_type (float_type_node, 4);
8210 V8HI_type_node = build_vector_type (intHI_type_node, 8);
8211 V16QI_type_node = build_vector_type (intQI_type_node, 16);
8213 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
8214 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
8215 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
8217 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
8218 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
8219 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
8220 opaque_V4SI_type_node = copy_node (V4SI_type_node);
8222 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
8223 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
8224 'vector unsigned short'. */
8226 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
8227 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8228 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
8229 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8231 long_integer_type_internal_node = long_integer_type_node;
8232 long_unsigned_type_internal_node = long_unsigned_type_node;
8233 intQI_type_internal_node = intQI_type_node;
8234 uintQI_type_internal_node = unsigned_intQI_type_node;
8235 intHI_type_internal_node = intHI_type_node;
8236 uintHI_type_internal_node = unsigned_intHI_type_node;
8237 intSI_type_internal_node = intSI_type_node;
8238 uintSI_type_internal_node = unsigned_intSI_type_node;
8239 float_type_internal_node = float_type_node;
8240 void_type_internal_node = void_type_node;
8242 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8243 get_identifier ("__bool char"),
8244 bool_char_type_node));
8245 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8246 get_identifier ("__bool short"),
8247 bool_short_type_node));
8248 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8249 get_identifier ("__bool int"),
8250 bool_int_type_node));
8251 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8252 get_identifier ("__pixel"),
8253 pixel_type_node));
8255 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
8256 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
8257 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
8258 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
8260 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8261 get_identifier ("__vector unsigned char"),
8262 unsigned_V16QI_type_node));
8263 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8264 get_identifier ("__vector signed char"),
8265 V16QI_type_node));
8266 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8267 get_identifier ("__vector __bool char"),
8268 bool_V16QI_type_node));
8270 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8271 get_identifier ("__vector unsigned short"),
8272 unsigned_V8HI_type_node));
8273 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8274 get_identifier ("__vector signed short"),
8275 V8HI_type_node));
8276 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8277 get_identifier ("__vector __bool short"),
8278 bool_V8HI_type_node));
8280 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8281 get_identifier ("__vector unsigned int"),
8282 unsigned_V4SI_type_node));
8283 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8284 get_identifier ("__vector signed int"),
8285 V4SI_type_node));
8286 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8287 get_identifier ("__vector __bool int"),
8288 bool_V4SI_type_node));
8290 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8291 get_identifier ("__vector float"),
8292 V4SF_type_node));
8293 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8294 get_identifier ("__vector __pixel"),
8295 pixel_V8HI_type_node));
8297 if (TARGET_SPE)
8298 spe_init_builtins ();
8299 if (TARGET_ALTIVEC)
8300 altivec_init_builtins ();
8301 if (TARGET_ALTIVEC || TARGET_SPE)
8302 rs6000_common_init_builtins ();
8304 #if TARGET_XCOFF
8305 /* AIX libm provides clog as __clog. */
8306 if (built_in_decls [BUILT_IN_CLOG])
8307 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
8308 #endif
8311 /* Search through a set of builtins and enable the mask bits.
8312 DESC is an array of builtins.
8313 SIZE is the total number of builtins.
8314 START is the builtin enum at which to start.
8315 END is the builtin enum at which to end. */
8316 static void
8317 enable_mask_for_builtins (struct builtin_description *desc, int size,
8318 enum rs6000_builtins start,
8319 enum rs6000_builtins end)
8321 int i;
8323 for (i = 0; i < size; ++i)
8324 if (desc[i].code == start)
8325 break;
8327 if (i == size)
8328 return;
8330 for (; i < size; ++i)
8332 /* Flip all the bits on. */
8333 desc[i].mask = target_flags;
8334 if (desc[i].code == end)
8335 break;
8339 static void
8340 spe_init_builtins (void)
8342 tree endlink = void_list_node;
8343 tree puint_type_node = build_pointer_type (unsigned_type_node);
8344 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
8345 struct builtin_description *d;
8346 size_t i;
8348 tree v2si_ftype_4_v2si
8349 = build_function_type
8350 (opaque_V2SI_type_node,
8351 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8352 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8353 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8354 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8355 endlink)))));
8357 tree v2sf_ftype_4_v2sf
8358 = build_function_type
8359 (opaque_V2SF_type_node,
8360 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8361 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8362 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8363 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8364 endlink)))));
8366 tree int_ftype_int_v2si_v2si
8367 = build_function_type
8368 (integer_type_node,
8369 tree_cons (NULL_TREE, integer_type_node,
8370 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8371 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8372 endlink))));
8374 tree int_ftype_int_v2sf_v2sf
8375 = build_function_type
8376 (integer_type_node,
8377 tree_cons (NULL_TREE, integer_type_node,
8378 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8379 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8380 endlink))));
8382 tree void_ftype_v2si_puint_int
8383 = build_function_type (void_type_node,
8384 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8385 tree_cons (NULL_TREE, puint_type_node,
8386 tree_cons (NULL_TREE,
8387 integer_type_node,
8388 endlink))));
8390 tree void_ftype_v2si_puint_char
8391 = build_function_type (void_type_node,
8392 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8393 tree_cons (NULL_TREE, puint_type_node,
8394 tree_cons (NULL_TREE,
8395 char_type_node,
8396 endlink))));
8398 tree void_ftype_v2si_pv2si_int
8399 = build_function_type (void_type_node,
8400 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8401 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8402 tree_cons (NULL_TREE,
8403 integer_type_node,
8404 endlink))));
8406 tree void_ftype_v2si_pv2si_char
8407 = build_function_type (void_type_node,
8408 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8409 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8410 tree_cons (NULL_TREE,
8411 char_type_node,
8412 endlink))));
8414 tree void_ftype_int
8415 = build_function_type (void_type_node,
8416 tree_cons (NULL_TREE, integer_type_node, endlink));
8418 tree int_ftype_void
8419 = build_function_type (integer_type_node, endlink);
8421 tree v2si_ftype_pv2si_int
8422 = build_function_type (opaque_V2SI_type_node,
8423 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8424 tree_cons (NULL_TREE, integer_type_node,
8425 endlink)));
8427 tree v2si_ftype_puint_int
8428 = build_function_type (opaque_V2SI_type_node,
8429 tree_cons (NULL_TREE, puint_type_node,
8430 tree_cons (NULL_TREE, integer_type_node,
8431 endlink)));
8433 tree v2si_ftype_pushort_int
8434 = build_function_type (opaque_V2SI_type_node,
8435 tree_cons (NULL_TREE, pushort_type_node,
8436 tree_cons (NULL_TREE, integer_type_node,
8437 endlink)));
8439 tree v2si_ftype_signed_char
8440 = build_function_type (opaque_V2SI_type_node,
8441 tree_cons (NULL_TREE, signed_char_type_node,
8442 endlink));
8444 /* The initialization of the simple binary and unary builtins is
8445 done in rs6000_common_init_builtins, but we have to enable the
8446 mask bits here manually because we have run out of `target_flags'
8447 bits. We really need to redesign this mask business. */
8449 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
8450 ARRAY_SIZE (bdesc_2arg),
8451 SPE_BUILTIN_EVADDW,
8452 SPE_BUILTIN_EVXOR);
8453 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
8454 ARRAY_SIZE (bdesc_1arg),
8455 SPE_BUILTIN_EVABS,
8456 SPE_BUILTIN_EVSUBFUSIAAW);
8457 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
8458 ARRAY_SIZE (bdesc_spe_predicates),
8459 SPE_BUILTIN_EVCMPEQ,
8460 SPE_BUILTIN_EVFSTSTLT);
8461 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
8462 ARRAY_SIZE (bdesc_spe_evsel),
8463 SPE_BUILTIN_EVSEL_CMPGTS,
8464 SPE_BUILTIN_EVSEL_FSTSTEQ);
8466 (*lang_hooks.decls.pushdecl)
8467 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
8468 opaque_V2SI_type_node));
8470 /* Initialize irregular SPE builtins. */
8472 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
8473 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
8474 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
8475 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
8476 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
8477 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
8478 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
8479 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
8480 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
8481 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
8482 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
8483 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
8484 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
8485 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
8486 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
8487 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
8488 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
8489 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
8491 /* Loads. */
8492 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
8493 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
8494 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
8495 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
8496 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
8497 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
8498 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
8499 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
8500 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
8501 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
8502 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
8503 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
8504 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
8505 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
8506 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
8507 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
8508 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
8509 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
8510 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
8511 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
8512 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
8513 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
8515 /* Predicates. */
8516 d = (struct builtin_description *) bdesc_spe_predicates;
8517 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
8519 tree type;
8521 switch (insn_data[d->icode].operand[1].mode)
8523 case V2SImode:
8524 type = int_ftype_int_v2si_v2si;
8525 break;
8526 case V2SFmode:
8527 type = int_ftype_int_v2sf_v2sf;
8528 break;
8529 default:
8530 gcc_unreachable ();
8533 def_builtin (d->mask, d->name, type, d->code);
8536 /* Evsel predicates. */
8537 d = (struct builtin_description *) bdesc_spe_evsel;
8538 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
8540 tree type;
8542 switch (insn_data[d->icode].operand[1].mode)
8544 case V2SImode:
8545 type = v2si_ftype_4_v2si;
8546 break;
8547 case V2SFmode:
8548 type = v2sf_ftype_4_v2sf;
8549 break;
8550 default:
8551 gcc_unreachable ();
8554 def_builtin (d->mask, d->name, type, d->code);
8558 static void
8559 altivec_init_builtins (void)
8561 struct builtin_description *d;
8562 struct builtin_description_predicates *dp;
8563 size_t i;
8564 tree ftype;
8566 tree pfloat_type_node = build_pointer_type (float_type_node);
8567 tree pint_type_node = build_pointer_type (integer_type_node);
8568 tree pshort_type_node = build_pointer_type (short_integer_type_node);
8569 tree pchar_type_node = build_pointer_type (char_type_node);
8571 tree pvoid_type_node = build_pointer_type (void_type_node);
8573 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
8574 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
8575 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
8576 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
8578 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
8580 tree int_ftype_opaque
8581 = build_function_type_list (integer_type_node,
8582 opaque_V4SI_type_node, NULL_TREE);
8584 tree opaque_ftype_opaque_int
8585 = build_function_type_list (opaque_V4SI_type_node,
8586 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
8587 tree opaque_ftype_opaque_opaque_int
8588 = build_function_type_list (opaque_V4SI_type_node,
8589 opaque_V4SI_type_node, opaque_V4SI_type_node,
8590 integer_type_node, NULL_TREE);
8591 tree int_ftype_int_opaque_opaque
8592 = build_function_type_list (integer_type_node,
8593 integer_type_node, opaque_V4SI_type_node,
8594 opaque_V4SI_type_node, NULL_TREE);
8595 tree int_ftype_int_v4si_v4si
8596 = build_function_type_list (integer_type_node,
8597 integer_type_node, V4SI_type_node,
8598 V4SI_type_node, NULL_TREE);
8599 tree v4sf_ftype_pcfloat
8600 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
8601 tree void_ftype_pfloat_v4sf
8602 = build_function_type_list (void_type_node,
8603 pfloat_type_node, V4SF_type_node, NULL_TREE);
8604 tree v4si_ftype_pcint
8605 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
8606 tree void_ftype_pint_v4si
8607 = build_function_type_list (void_type_node,
8608 pint_type_node, V4SI_type_node, NULL_TREE);
8609 tree v8hi_ftype_pcshort
8610 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
8611 tree void_ftype_pshort_v8hi
8612 = build_function_type_list (void_type_node,
8613 pshort_type_node, V8HI_type_node, NULL_TREE);
8614 tree v16qi_ftype_pcchar
8615 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
8616 tree void_ftype_pchar_v16qi
8617 = build_function_type_list (void_type_node,
8618 pchar_type_node, V16QI_type_node, NULL_TREE);
8619 tree void_ftype_v4si
8620 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
8621 tree v8hi_ftype_void
8622 = build_function_type (V8HI_type_node, void_list_node);
8623 tree void_ftype_void
8624 = build_function_type (void_type_node, void_list_node);
8625 tree void_ftype_int
8626 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
8628 tree opaque_ftype_long_pcvoid
8629 = build_function_type_list (opaque_V4SI_type_node,
8630 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8631 tree v16qi_ftype_long_pcvoid
8632 = build_function_type_list (V16QI_type_node,
8633 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8634 tree v8hi_ftype_long_pcvoid
8635 = build_function_type_list (V8HI_type_node,
8636 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8637 tree v4si_ftype_long_pcvoid
8638 = build_function_type_list (V4SI_type_node,
8639 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8641 tree void_ftype_opaque_long_pvoid
8642 = build_function_type_list (void_type_node,
8643 opaque_V4SI_type_node, long_integer_type_node,
8644 pvoid_type_node, NULL_TREE);
8645 tree void_ftype_v4si_long_pvoid
8646 = build_function_type_list (void_type_node,
8647 V4SI_type_node, long_integer_type_node,
8648 pvoid_type_node, NULL_TREE);
8649 tree void_ftype_v16qi_long_pvoid
8650 = build_function_type_list (void_type_node,
8651 V16QI_type_node, long_integer_type_node,
8652 pvoid_type_node, NULL_TREE);
8653 tree void_ftype_v8hi_long_pvoid
8654 = build_function_type_list (void_type_node,
8655 V8HI_type_node, long_integer_type_node,
8656 pvoid_type_node, NULL_TREE);
8657 tree int_ftype_int_v8hi_v8hi
8658 = build_function_type_list (integer_type_node,
8659 integer_type_node, V8HI_type_node,
8660 V8HI_type_node, NULL_TREE);
8661 tree int_ftype_int_v16qi_v16qi
8662 = build_function_type_list (integer_type_node,
8663 integer_type_node, V16QI_type_node,
8664 V16QI_type_node, NULL_TREE);
8665 tree int_ftype_int_v4sf_v4sf
8666 = build_function_type_list (integer_type_node,
8667 integer_type_node, V4SF_type_node,
8668 V4SF_type_node, NULL_TREE);
8669 tree v4si_ftype_v4si
8670 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
8671 tree v8hi_ftype_v8hi
8672 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
8673 tree v16qi_ftype_v16qi
8674 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
8675 tree v4sf_ftype_v4sf
8676 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8677 tree void_ftype_pcvoid_int_int
8678 = build_function_type_list (void_type_node,
8679 pcvoid_type_node, integer_type_node,
8680 integer_type_node, NULL_TREE);
8682 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
8683 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
8684 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
8685 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
8686 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
8687 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
8688 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
8689 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
8690 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
8691 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
8692 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
8693 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
8694 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
8695 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
8696 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
8697 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
8698 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
8699 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
8700 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
8701 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
8702 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
8703 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
8704 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
8705 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
8706 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
8707 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
8708 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
8709 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
8710 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
8711 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
8712 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
8713 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
8714 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
8715 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
8716 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
8717 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
8718 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
8719 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
8720 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
8721 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
8722 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
8723 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
8724 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
8725 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
8726 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
8727 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
8729 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
8731 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
8732 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
8733 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
8734 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
8735 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
8736 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
8737 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
8738 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
8739 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
8740 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
8742 /* Add the DST variants. */
8743 d = (struct builtin_description *) bdesc_dst;
8744 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8745 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
8747 /* Initialize the predicates. */
8748 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
8749 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
8751 enum machine_mode mode1;
8752 tree type;
8753 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8754 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8756 if (is_overloaded)
8757 mode1 = VOIDmode;
8758 else
8759 mode1 = insn_data[dp->icode].operand[1].mode;
8761 switch (mode1)
8763 case VOIDmode:
8764 type = int_ftype_int_opaque_opaque;
8765 break;
8766 case V4SImode:
8767 type = int_ftype_int_v4si_v4si;
8768 break;
8769 case V8HImode:
8770 type = int_ftype_int_v8hi_v8hi;
8771 break;
8772 case V16QImode:
8773 type = int_ftype_int_v16qi_v16qi;
8774 break;
8775 case V4SFmode:
8776 type = int_ftype_int_v4sf_v4sf;
8777 break;
8778 default:
8779 gcc_unreachable ();
8782 def_builtin (dp->mask, dp->name, type, dp->code);
8785 /* Initialize the abs* operators. */
8786 d = (struct builtin_description *) bdesc_abs;
8787 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
8789 enum machine_mode mode0;
8790 tree type;
8792 mode0 = insn_data[d->icode].operand[0].mode;
8794 switch (mode0)
8796 case V4SImode:
8797 type = v4si_ftype_v4si;
8798 break;
8799 case V8HImode:
8800 type = v8hi_ftype_v8hi;
8801 break;
8802 case V16QImode:
8803 type = v16qi_ftype_v16qi;
8804 break;
8805 case V4SFmode:
8806 type = v4sf_ftype_v4sf;
8807 break;
8808 default:
8809 gcc_unreachable ();
8812 def_builtin (d->mask, d->name, type, d->code);
8815 if (TARGET_ALTIVEC)
8817 tree decl;
8819 /* Initialize target builtin that implements
8820 targetm.vectorize.builtin_mask_for_load. */
8822 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
8823 v16qi_ftype_long_pcvoid,
8824 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
8825 BUILT_IN_MD, NULL, NULL_TREE);
8826 TREE_READONLY (decl) = 1;
8827 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8828 altivec_builtin_mask_for_load = decl;
8831 /* Access to the vec_init patterns. */
8832 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
8833 integer_type_node, integer_type_node,
8834 integer_type_node, NULL_TREE);
8835 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
8836 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
8838 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
8839 short_integer_type_node,
8840 short_integer_type_node,
8841 short_integer_type_node,
8842 short_integer_type_node,
8843 short_integer_type_node,
8844 short_integer_type_node,
8845 short_integer_type_node, NULL_TREE);
8846 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
8847 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
8849 ftype = build_function_type_list (V16QI_type_node, char_type_node,
8850 char_type_node, char_type_node,
8851 char_type_node, char_type_node,
8852 char_type_node, char_type_node,
8853 char_type_node, char_type_node,
8854 char_type_node, char_type_node,
8855 char_type_node, char_type_node,
8856 char_type_node, char_type_node,
8857 char_type_node, NULL_TREE);
8858 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
8859 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
8861 ftype = build_function_type_list (V4SF_type_node, float_type_node,
8862 float_type_node, float_type_node,
8863 float_type_node, NULL_TREE);
8864 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
8865 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
8867 /* Access to the vec_set patterns. */
8868 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
8869 intSI_type_node,
8870 integer_type_node, NULL_TREE);
8871 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
8872 ALTIVEC_BUILTIN_VEC_SET_V4SI);
8874 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
8875 intHI_type_node,
8876 integer_type_node, NULL_TREE);
8877 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
8878 ALTIVEC_BUILTIN_VEC_SET_V8HI);
8880 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
8881 intQI_type_node,
8882 integer_type_node, NULL_TREE);
8883 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
8884 ALTIVEC_BUILTIN_VEC_SET_V16QI);
8886 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
8887 float_type_node,
8888 integer_type_node, NULL_TREE);
8889 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
8890 ALTIVEC_BUILTIN_VEC_SET_V4SF);
8892 /* Access to the vec_extract patterns. */
8893 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
8894 integer_type_node, NULL_TREE);
8895 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
8896 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
8898 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
8899 integer_type_node, NULL_TREE);
8900 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
8901 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
8903 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
8904 integer_type_node, NULL_TREE);
8905 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
8906 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
8908 ftype = build_function_type_list (float_type_node, V4SF_type_node,
8909 integer_type_node, NULL_TREE);
8910 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
8911 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
8914 static void
8915 rs6000_common_init_builtins (void)
8917 struct builtin_description *d;
8918 size_t i;
8920 tree v4sf_ftype_v4sf_v4sf_v16qi
8921 = build_function_type_list (V4SF_type_node,
8922 V4SF_type_node, V4SF_type_node,
8923 V16QI_type_node, NULL_TREE);
8924 tree v4si_ftype_v4si_v4si_v16qi
8925 = build_function_type_list (V4SI_type_node,
8926 V4SI_type_node, V4SI_type_node,
8927 V16QI_type_node, NULL_TREE);
8928 tree v8hi_ftype_v8hi_v8hi_v16qi
8929 = build_function_type_list (V8HI_type_node,
8930 V8HI_type_node, V8HI_type_node,
8931 V16QI_type_node, NULL_TREE);
8932 tree v16qi_ftype_v16qi_v16qi_v16qi
8933 = build_function_type_list (V16QI_type_node,
8934 V16QI_type_node, V16QI_type_node,
8935 V16QI_type_node, NULL_TREE);
8936 tree v4si_ftype_int
8937 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
8938 tree v8hi_ftype_int
8939 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
8940 tree v16qi_ftype_int
8941 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
8942 tree v8hi_ftype_v16qi
8943 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
8944 tree v4sf_ftype_v4sf
8945 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8947 tree v2si_ftype_v2si_v2si
8948 = build_function_type_list (opaque_V2SI_type_node,
8949 opaque_V2SI_type_node,
8950 opaque_V2SI_type_node, NULL_TREE);
8952 tree v2sf_ftype_v2sf_v2sf
8953 = build_function_type_list (opaque_V2SF_type_node,
8954 opaque_V2SF_type_node,
8955 opaque_V2SF_type_node, NULL_TREE);
8957 tree v2si_ftype_int_int
8958 = build_function_type_list (opaque_V2SI_type_node,
8959 integer_type_node, integer_type_node,
8960 NULL_TREE);
8962 tree opaque_ftype_opaque
8963 = build_function_type_list (opaque_V4SI_type_node,
8964 opaque_V4SI_type_node, NULL_TREE);
8966 tree v2si_ftype_v2si
8967 = build_function_type_list (opaque_V2SI_type_node,
8968 opaque_V2SI_type_node, NULL_TREE);
8970 tree v2sf_ftype_v2sf
8971 = build_function_type_list (opaque_V2SF_type_node,
8972 opaque_V2SF_type_node, NULL_TREE);
8974 tree v2sf_ftype_v2si
8975 = build_function_type_list (opaque_V2SF_type_node,
8976 opaque_V2SI_type_node, NULL_TREE);
8978 tree v2si_ftype_v2sf
8979 = build_function_type_list (opaque_V2SI_type_node,
8980 opaque_V2SF_type_node, NULL_TREE);
8982 tree v2si_ftype_v2si_char
8983 = build_function_type_list (opaque_V2SI_type_node,
8984 opaque_V2SI_type_node,
8985 char_type_node, NULL_TREE);
8987 tree v2si_ftype_int_char
8988 = build_function_type_list (opaque_V2SI_type_node,
8989 integer_type_node, char_type_node, NULL_TREE);
8991 tree v2si_ftype_char
8992 = build_function_type_list (opaque_V2SI_type_node,
8993 char_type_node, NULL_TREE);
8995 tree int_ftype_int_int
8996 = build_function_type_list (integer_type_node,
8997 integer_type_node, integer_type_node,
8998 NULL_TREE);
9000 tree opaque_ftype_opaque_opaque
9001 = build_function_type_list (opaque_V4SI_type_node,
9002 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
9003 tree v4si_ftype_v4si_v4si
9004 = build_function_type_list (V4SI_type_node,
9005 V4SI_type_node, V4SI_type_node, NULL_TREE);
9006 tree v4sf_ftype_v4si_int
9007 = build_function_type_list (V4SF_type_node,
9008 V4SI_type_node, integer_type_node, NULL_TREE);
9009 tree v4si_ftype_v4sf_int
9010 = build_function_type_list (V4SI_type_node,
9011 V4SF_type_node, integer_type_node, NULL_TREE);
9012 tree v4si_ftype_v4si_int
9013 = build_function_type_list (V4SI_type_node,
9014 V4SI_type_node, integer_type_node, NULL_TREE);
9015 tree v8hi_ftype_v8hi_int
9016 = build_function_type_list (V8HI_type_node,
9017 V8HI_type_node, integer_type_node, NULL_TREE);
9018 tree v16qi_ftype_v16qi_int
9019 = build_function_type_list (V16QI_type_node,
9020 V16QI_type_node, integer_type_node, NULL_TREE);
9021 tree v16qi_ftype_v16qi_v16qi_int
9022 = build_function_type_list (V16QI_type_node,
9023 V16QI_type_node, V16QI_type_node,
9024 integer_type_node, NULL_TREE);
9025 tree v8hi_ftype_v8hi_v8hi_int
9026 = build_function_type_list (V8HI_type_node,
9027 V8HI_type_node, V8HI_type_node,
9028 integer_type_node, NULL_TREE);
9029 tree v4si_ftype_v4si_v4si_int
9030 = build_function_type_list (V4SI_type_node,
9031 V4SI_type_node, V4SI_type_node,
9032 integer_type_node, NULL_TREE);
9033 tree v4sf_ftype_v4sf_v4sf_int
9034 = build_function_type_list (V4SF_type_node,
9035 V4SF_type_node, V4SF_type_node,
9036 integer_type_node, NULL_TREE);
9037 tree v4sf_ftype_v4sf_v4sf
9038 = build_function_type_list (V4SF_type_node,
9039 V4SF_type_node, V4SF_type_node, NULL_TREE);
9040 tree opaque_ftype_opaque_opaque_opaque
9041 = build_function_type_list (opaque_V4SI_type_node,
9042 opaque_V4SI_type_node, opaque_V4SI_type_node,
9043 opaque_V4SI_type_node, NULL_TREE);
9044 tree v4sf_ftype_v4sf_v4sf_v4si
9045 = build_function_type_list (V4SF_type_node,
9046 V4SF_type_node, V4SF_type_node,
9047 V4SI_type_node, NULL_TREE);
9048 tree v4sf_ftype_v4sf_v4sf_v4sf
9049 = build_function_type_list (V4SF_type_node,
9050 V4SF_type_node, V4SF_type_node,
9051 V4SF_type_node, NULL_TREE);
9052 tree v4si_ftype_v4si_v4si_v4si
9053 = build_function_type_list (V4SI_type_node,
9054 V4SI_type_node, V4SI_type_node,
9055 V4SI_type_node, NULL_TREE);
9056 tree v8hi_ftype_v8hi_v8hi
9057 = build_function_type_list (V8HI_type_node,
9058 V8HI_type_node, V8HI_type_node, NULL_TREE);
9059 tree v8hi_ftype_v8hi_v8hi_v8hi
9060 = build_function_type_list (V8HI_type_node,
9061 V8HI_type_node, V8HI_type_node,
9062 V8HI_type_node, NULL_TREE);
9063 tree v4si_ftype_v8hi_v8hi_v4si
9064 = build_function_type_list (V4SI_type_node,
9065 V8HI_type_node, V8HI_type_node,
9066 V4SI_type_node, NULL_TREE);
9067 tree v4si_ftype_v16qi_v16qi_v4si
9068 = build_function_type_list (V4SI_type_node,
9069 V16QI_type_node, V16QI_type_node,
9070 V4SI_type_node, NULL_TREE);
9071 tree v16qi_ftype_v16qi_v16qi
9072 = build_function_type_list (V16QI_type_node,
9073 V16QI_type_node, V16QI_type_node, NULL_TREE);
9074 tree v4si_ftype_v4sf_v4sf
9075 = build_function_type_list (V4SI_type_node,
9076 V4SF_type_node, V4SF_type_node, NULL_TREE);
9077 tree v8hi_ftype_v16qi_v16qi
9078 = build_function_type_list (V8HI_type_node,
9079 V16QI_type_node, V16QI_type_node, NULL_TREE);
9080 tree v4si_ftype_v8hi_v8hi
9081 = build_function_type_list (V4SI_type_node,
9082 V8HI_type_node, V8HI_type_node, NULL_TREE);
9083 tree v8hi_ftype_v4si_v4si
9084 = build_function_type_list (V8HI_type_node,
9085 V4SI_type_node, V4SI_type_node, NULL_TREE);
9086 tree v16qi_ftype_v8hi_v8hi
9087 = build_function_type_list (V16QI_type_node,
9088 V8HI_type_node, V8HI_type_node, NULL_TREE);
9089 tree v4si_ftype_v16qi_v4si
9090 = build_function_type_list (V4SI_type_node,
9091 V16QI_type_node, V4SI_type_node, NULL_TREE);
9092 tree v4si_ftype_v16qi_v16qi
9093 = build_function_type_list (V4SI_type_node,
9094 V16QI_type_node, V16QI_type_node, NULL_TREE);
9095 tree v4si_ftype_v8hi_v4si
9096 = build_function_type_list (V4SI_type_node,
9097 V8HI_type_node, V4SI_type_node, NULL_TREE);
9098 tree v4si_ftype_v8hi
9099 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
9100 tree int_ftype_v4si_v4si
9101 = build_function_type_list (integer_type_node,
9102 V4SI_type_node, V4SI_type_node, NULL_TREE);
9103 tree int_ftype_v4sf_v4sf
9104 = build_function_type_list (integer_type_node,
9105 V4SF_type_node, V4SF_type_node, NULL_TREE);
9106 tree int_ftype_v16qi_v16qi
9107 = build_function_type_list (integer_type_node,
9108 V16QI_type_node, V16QI_type_node, NULL_TREE);
9109 tree int_ftype_v8hi_v8hi
9110 = build_function_type_list (integer_type_node,
9111 V8HI_type_node, V8HI_type_node, NULL_TREE);
9113 /* Add the simple ternary operators. */
9114 d = (struct builtin_description *) bdesc_3arg;
9115 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
9117 enum machine_mode mode0, mode1, mode2, mode3;
9118 tree type;
9119 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9120 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9122 if (is_overloaded)
9124 mode0 = VOIDmode;
9125 mode1 = VOIDmode;
9126 mode2 = VOIDmode;
9127 mode3 = VOIDmode;
9129 else
9131 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9132 continue;
9134 mode0 = insn_data[d->icode].operand[0].mode;
9135 mode1 = insn_data[d->icode].operand[1].mode;
9136 mode2 = insn_data[d->icode].operand[2].mode;
9137 mode3 = insn_data[d->icode].operand[3].mode;
9140 /* When all four are of the same mode. */
9141 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
9143 switch (mode0)
9145 case VOIDmode:
9146 type = opaque_ftype_opaque_opaque_opaque;
9147 break;
9148 case V4SImode:
9149 type = v4si_ftype_v4si_v4si_v4si;
9150 break;
9151 case V4SFmode:
9152 type = v4sf_ftype_v4sf_v4sf_v4sf;
9153 break;
9154 case V8HImode:
9155 type = v8hi_ftype_v8hi_v8hi_v8hi;
9156 break;
9157 case V16QImode:
9158 type = v16qi_ftype_v16qi_v16qi_v16qi;
9159 break;
9160 default:
9161 gcc_unreachable ();
9164 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
9166 switch (mode0)
9168 case V4SImode:
9169 type = v4si_ftype_v4si_v4si_v16qi;
9170 break;
9171 case V4SFmode:
9172 type = v4sf_ftype_v4sf_v4sf_v16qi;
9173 break;
9174 case V8HImode:
9175 type = v8hi_ftype_v8hi_v8hi_v16qi;
9176 break;
9177 case V16QImode:
9178 type = v16qi_ftype_v16qi_v16qi_v16qi;
9179 break;
9180 default:
9181 gcc_unreachable ();
9184 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
9185 && mode3 == V4SImode)
9186 type = v4si_ftype_v16qi_v16qi_v4si;
9187 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
9188 && mode3 == V4SImode)
9189 type = v4si_ftype_v8hi_v8hi_v4si;
9190 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
9191 && mode3 == V4SImode)
9192 type = v4sf_ftype_v4sf_v4sf_v4si;
9194 /* vchar, vchar, vchar, 4 bit literal. */
9195 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
9196 && mode3 == QImode)
9197 type = v16qi_ftype_v16qi_v16qi_int;
9199 /* vshort, vshort, vshort, 4 bit literal. */
9200 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
9201 && mode3 == QImode)
9202 type = v8hi_ftype_v8hi_v8hi_int;
9204 /* vint, vint, vint, 4 bit literal. */
9205 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
9206 && mode3 == QImode)
9207 type = v4si_ftype_v4si_v4si_int;
9209 /* vfloat, vfloat, vfloat, 4 bit literal. */
9210 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
9211 && mode3 == QImode)
9212 type = v4sf_ftype_v4sf_v4sf_int;
9214 else
9215 gcc_unreachable ();
9217 def_builtin (d->mask, d->name, type, d->code);
9220 /* Add the simple binary operators. */
9221 d = (struct builtin_description *) bdesc_2arg;
9222 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
9224 enum machine_mode mode0, mode1, mode2;
9225 tree type;
9226 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9227 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9229 if (is_overloaded)
9231 mode0 = VOIDmode;
9232 mode1 = VOIDmode;
9233 mode2 = VOIDmode;
9235 else
9237 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9238 continue;
9240 mode0 = insn_data[d->icode].operand[0].mode;
9241 mode1 = insn_data[d->icode].operand[1].mode;
9242 mode2 = insn_data[d->icode].operand[2].mode;
9245 /* When all three operands are of the same mode. */
9246 if (mode0 == mode1 && mode1 == mode2)
9248 switch (mode0)
9250 case VOIDmode:
9251 type = opaque_ftype_opaque_opaque;
9252 break;
9253 case V4SFmode:
9254 type = v4sf_ftype_v4sf_v4sf;
9255 break;
9256 case V4SImode:
9257 type = v4si_ftype_v4si_v4si;
9258 break;
9259 case V16QImode:
9260 type = v16qi_ftype_v16qi_v16qi;
9261 break;
9262 case V8HImode:
9263 type = v8hi_ftype_v8hi_v8hi;
9264 break;
9265 case V2SImode:
9266 type = v2si_ftype_v2si_v2si;
9267 break;
9268 case V2SFmode:
9269 type = v2sf_ftype_v2sf_v2sf;
9270 break;
9271 case SImode:
9272 type = int_ftype_int_int;
9273 break;
9274 default:
9275 gcc_unreachable ();
9279 /* A few other combos we really don't want to do manually. */
9281 /* vint, vfloat, vfloat. */
9282 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
9283 type = v4si_ftype_v4sf_v4sf;
9285 /* vshort, vchar, vchar. */
9286 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
9287 type = v8hi_ftype_v16qi_v16qi;
9289 /* vint, vshort, vshort. */
9290 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
9291 type = v4si_ftype_v8hi_v8hi;
9293 /* vshort, vint, vint. */
9294 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
9295 type = v8hi_ftype_v4si_v4si;
9297 /* vchar, vshort, vshort. */
9298 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
9299 type = v16qi_ftype_v8hi_v8hi;
9301 /* vint, vchar, vint. */
9302 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
9303 type = v4si_ftype_v16qi_v4si;
9305 /* vint, vchar, vchar. */
9306 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
9307 type = v4si_ftype_v16qi_v16qi;
9309 /* vint, vshort, vint. */
9310 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
9311 type = v4si_ftype_v8hi_v4si;
9313 /* vint, vint, 5 bit literal. */
9314 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
9315 type = v4si_ftype_v4si_int;
9317 /* vshort, vshort, 5 bit literal. */
9318 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
9319 type = v8hi_ftype_v8hi_int;
9321 /* vchar, vchar, 5 bit literal. */
9322 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
9323 type = v16qi_ftype_v16qi_int;
9325 /* vfloat, vint, 5 bit literal. */
9326 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
9327 type = v4sf_ftype_v4si_int;
9329 /* vint, vfloat, 5 bit literal. */
9330 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
9331 type = v4si_ftype_v4sf_int;
9333 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
9334 type = v2si_ftype_int_int;
9336 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
9337 type = v2si_ftype_v2si_char;
9339 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
9340 type = v2si_ftype_int_char;
9342 else
9344 /* int, x, x. */
9345 gcc_assert (mode0 == SImode);
9346 switch (mode1)
9348 case V4SImode:
9349 type = int_ftype_v4si_v4si;
9350 break;
9351 case V4SFmode:
9352 type = int_ftype_v4sf_v4sf;
9353 break;
9354 case V16QImode:
9355 type = int_ftype_v16qi_v16qi;
9356 break;
9357 case V8HImode:
9358 type = int_ftype_v8hi_v8hi;
9359 break;
9360 default:
9361 gcc_unreachable ();
9365 def_builtin (d->mask, d->name, type, d->code);
9368 /* Add the simple unary operators. */
9369 d = (struct builtin_description *) bdesc_1arg;
9370 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
9372 enum machine_mode mode0, mode1;
9373 tree type;
9374 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9375 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9377 if (is_overloaded)
9379 mode0 = VOIDmode;
9380 mode1 = VOIDmode;
9382 else
9384 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9385 continue;
9387 mode0 = insn_data[d->icode].operand[0].mode;
9388 mode1 = insn_data[d->icode].operand[1].mode;
9391 if (mode0 == V4SImode && mode1 == QImode)
9392 type = v4si_ftype_int;
9393 else if (mode0 == V8HImode && mode1 == QImode)
9394 type = v8hi_ftype_int;
9395 else if (mode0 == V16QImode && mode1 == QImode)
9396 type = v16qi_ftype_int;
9397 else if (mode0 == VOIDmode && mode1 == VOIDmode)
9398 type = opaque_ftype_opaque;
9399 else if (mode0 == V4SFmode && mode1 == V4SFmode)
9400 type = v4sf_ftype_v4sf;
9401 else if (mode0 == V8HImode && mode1 == V16QImode)
9402 type = v8hi_ftype_v16qi;
9403 else if (mode0 == V4SImode && mode1 == V8HImode)
9404 type = v4si_ftype_v8hi;
9405 else if (mode0 == V2SImode && mode1 == V2SImode)
9406 type = v2si_ftype_v2si;
9407 else if (mode0 == V2SFmode && mode1 == V2SFmode)
9408 type = v2sf_ftype_v2sf;
9409 else if (mode0 == V2SFmode && mode1 == V2SImode)
9410 type = v2sf_ftype_v2si;
9411 else if (mode0 == V2SImode && mode1 == V2SFmode)
9412 type = v2si_ftype_v2sf;
9413 else if (mode0 == V2SImode && mode1 == QImode)
9414 type = v2si_ftype_char;
9415 else
9416 gcc_unreachable ();
9418 def_builtin (d->mask, d->name, type, d->code);
9422 static void
9423 rs6000_init_libfuncs (void)
9425 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
9426 && !TARGET_POWER2 && !TARGET_POWERPC)
9428 /* AIX library routines for float->int conversion. */
9429 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
9430 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
9431 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
9432 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
9435 if (!TARGET_IEEEQUAD)
9436 /* AIX/Darwin/64-bit Linux quad floating point routines. */
9437 if (!TARGET_XL_COMPAT)
9439 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
9440 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
9441 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
9442 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
9444 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
9446 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
9447 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
9448 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
9449 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
9450 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
9451 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
9452 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
9453 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
9455 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
9456 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
9457 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
9458 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
9459 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
9460 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
9461 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
9462 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
9465 else
9467 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
9468 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
9469 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
9470 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
9472 else
9474 /* 32-bit SVR4 quad floating point routines. */
9476 set_optab_libfunc (add_optab, TFmode, "_q_add");
9477 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
9478 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
9479 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
9480 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
9481 if (TARGET_PPC_GPOPT || TARGET_POWER2)
9482 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
9484 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
9485 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
9486 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
9487 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
9488 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
9489 set_optab_libfunc (le_optab, TFmode, "_q_fle");
9491 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
9492 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
9493 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
9494 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
9495 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
9496 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
9497 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
9498 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
9503 /* Expand a block clear operation, and return 1 if successful. Return 0
9504 if we should let the compiler generate normal code.
9506 operands[0] is the destination
9507 operands[1] is the length
9508 operands[3] is the alignment */
9511 expand_block_clear (rtx operands[])
9513 rtx orig_dest = operands[0];
9514 rtx bytes_rtx = operands[1];
9515 rtx align_rtx = operands[3];
9516 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
9517 HOST_WIDE_INT align;
9518 HOST_WIDE_INT bytes;
9519 int offset;
9520 int clear_bytes;
9521 int clear_step;
9523 /* If this is not a fixed size move, just call memcpy */
9524 if (! constp)
9525 return 0;
9527 /* This must be a fixed size alignment */
9528 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9529 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9531 /* Anything to clear? */
9532 bytes = INTVAL (bytes_rtx);
9533 if (bytes <= 0)
9534 return 1;
9536 /* Use the builtin memset after a point, to avoid huge code bloat.
9537 When optimize_size, avoid any significant code bloat; calling
9538 memset is about 4 instructions, so allow for one instruction to
9539 load zero and three to do clearing. */
9540 if (TARGET_ALTIVEC && align >= 128)
9541 clear_step = 16;
9542 else if (TARGET_POWERPC64 && align >= 32)
9543 clear_step = 8;
9544 else
9545 clear_step = 4;
9547 if (optimize_size && bytes > 3 * clear_step)
9548 return 0;
9549 if (! optimize_size && bytes > 8 * clear_step)
9550 return 0;
9552 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
9554 enum machine_mode mode = BLKmode;
9555 rtx dest;
9557 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
9559 clear_bytes = 16;
9560 mode = V4SImode;
9562 else if (bytes >= 8 && TARGET_POWERPC64
9563 /* 64-bit loads and stores require word-aligned
9564 displacements. */
9565 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9567 clear_bytes = 8;
9568 mode = DImode;
9570 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9571 { /* move 4 bytes */
9572 clear_bytes = 4;
9573 mode = SImode;
9575 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9576 { /* move 2 bytes */
9577 clear_bytes = 2;
9578 mode = HImode;
9580 else /* move 1 byte at a time */
9582 clear_bytes = 1;
9583 mode = QImode;
9586 dest = adjust_address (orig_dest, mode, offset);
9588 emit_move_insn (dest, CONST0_RTX (mode));
9591 return 1;
9595 /* Expand a block move operation, and return 1 if successful. Return 0
9596 if we should let the compiler generate normal code.
9598 operands[0] is the destination
9599 operands[1] is the source
9600 operands[2] is the length
9601 operands[3] is the alignment */
9603 #define MAX_MOVE_REG 4
9606 expand_block_move (rtx operands[])
9608 rtx orig_dest = operands[0];
9609 rtx orig_src = operands[1];
9610 rtx bytes_rtx = operands[2];
9611 rtx align_rtx = operands[3];
9612 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
9613 int align;
9614 int bytes;
9615 int offset;
9616 int move_bytes;
9617 rtx stores[MAX_MOVE_REG];
9618 int num_reg = 0;
9620 /* If this is not a fixed size move, just call memcpy */
9621 if (! constp)
9622 return 0;
9624 /* This must be a fixed size alignment */
9625 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9626 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9628 /* Anything to move? */
9629 bytes = INTVAL (bytes_rtx);
9630 if (bytes <= 0)
9631 return 1;
9633 /* store_one_arg depends on expand_block_move to handle at least the size of
9634 reg_parm_stack_space. */
9635 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
9636 return 0;
9638 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
9640 union {
9641 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
9642 rtx (*mov) (rtx, rtx);
9643 } gen_func;
9644 enum machine_mode mode = BLKmode;
9645 rtx src, dest;
9647 /* Altivec first, since it will be faster than a string move
9648 when it applies, and usually not significantly larger. */
9649 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
9651 move_bytes = 16;
9652 mode = V4SImode;
9653 gen_func.mov = gen_movv4si;
9655 else if (TARGET_STRING
9656 && bytes > 24 /* move up to 32 bytes at a time */
9657 && ! fixed_regs[5]
9658 && ! fixed_regs[6]
9659 && ! fixed_regs[7]
9660 && ! fixed_regs[8]
9661 && ! fixed_regs[9]
9662 && ! fixed_regs[10]
9663 && ! fixed_regs[11]
9664 && ! fixed_regs[12])
9666 move_bytes = (bytes > 32) ? 32 : bytes;
9667 gen_func.movmemsi = gen_movmemsi_8reg;
9669 else if (TARGET_STRING
9670 && bytes > 16 /* move up to 24 bytes at a time */
9671 && ! fixed_regs[5]
9672 && ! fixed_regs[6]
9673 && ! fixed_regs[7]
9674 && ! fixed_regs[8]
9675 && ! fixed_regs[9]
9676 && ! fixed_regs[10])
9678 move_bytes = (bytes > 24) ? 24 : bytes;
9679 gen_func.movmemsi = gen_movmemsi_6reg;
9681 else if (TARGET_STRING
9682 && bytes > 8 /* move up to 16 bytes at a time */
9683 && ! fixed_regs[5]
9684 && ! fixed_regs[6]
9685 && ! fixed_regs[7]
9686 && ! fixed_regs[8])
9688 move_bytes = (bytes > 16) ? 16 : bytes;
9689 gen_func.movmemsi = gen_movmemsi_4reg;
9691 else if (bytes >= 8 && TARGET_POWERPC64
9692 /* 64-bit loads and stores require word-aligned
9693 displacements. */
9694 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9696 move_bytes = 8;
9697 mode = DImode;
9698 gen_func.mov = gen_movdi;
9700 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
9701 { /* move up to 8 bytes at a time */
9702 move_bytes = (bytes > 8) ? 8 : bytes;
9703 gen_func.movmemsi = gen_movmemsi_2reg;
9705 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9706 { /* move 4 bytes */
9707 move_bytes = 4;
9708 mode = SImode;
9709 gen_func.mov = gen_movsi;
9711 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9712 { /* move 2 bytes */
9713 move_bytes = 2;
9714 mode = HImode;
9715 gen_func.mov = gen_movhi;
9717 else if (TARGET_STRING && bytes > 1)
9718 { /* move up to 4 bytes at a time */
9719 move_bytes = (bytes > 4) ? 4 : bytes;
9720 gen_func.movmemsi = gen_movmemsi_1reg;
9722 else /* move 1 byte at a time */
9724 move_bytes = 1;
9725 mode = QImode;
9726 gen_func.mov = gen_movqi;
9729 src = adjust_address (orig_src, mode, offset);
9730 dest = adjust_address (orig_dest, mode, offset);
9732 if (mode != BLKmode)
9734 rtx tmp_reg = gen_reg_rtx (mode);
9736 emit_insn ((*gen_func.mov) (tmp_reg, src));
9737 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
9740 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
9742 int i;
9743 for (i = 0; i < num_reg; i++)
9744 emit_insn (stores[i]);
9745 num_reg = 0;
9748 if (mode == BLKmode)
9750 /* Move the address into scratch registers. The movmemsi
9751 patterns require zero offset. */
9752 if (!REG_P (XEXP (src, 0)))
9754 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
9755 src = replace_equiv_address (src, src_reg);
9757 set_mem_size (src, GEN_INT (move_bytes));
9759 if (!REG_P (XEXP (dest, 0)))
9761 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
9762 dest = replace_equiv_address (dest, dest_reg);
9764 set_mem_size (dest, GEN_INT (move_bytes));
9766 emit_insn ((*gen_func.movmemsi) (dest, src,
9767 GEN_INT (move_bytes & 31),
9768 align_rtx));
9772 return 1;
9776 /* Return a string to perform a load_multiple operation.
9777 operands[0] is the vector.
9778 operands[1] is the source address.
9779 operands[2] is the first destination register. */
9781 const char *
9782 rs6000_output_load_multiple (rtx operands[3])
9784 /* We have to handle the case where the pseudo used to contain the address
9785 is assigned to one of the output registers. */
9786 int i, j;
9787 int words = XVECLEN (operands[0], 0);
9788 rtx xop[10];
9790 if (XVECLEN (operands[0], 0) == 1)
9791 return "{l|lwz} %2,0(%1)";
9793 for (i = 0; i < words; i++)
9794 if (refers_to_regno_p (REGNO (operands[2]) + i,
9795 REGNO (operands[2]) + i + 1, operands[1], 0))
9797 if (i == words-1)
9799 xop[0] = GEN_INT (4 * (words-1));
9800 xop[1] = operands[1];
9801 xop[2] = operands[2];
9802 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
9803 return "";
9805 else if (i == 0)
9807 xop[0] = GEN_INT (4 * (words-1));
9808 xop[1] = operands[1];
9809 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
9810 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);
9811 return "";
9813 else
9815 for (j = 0; j < words; j++)
9816 if (j != i)
9818 xop[0] = GEN_INT (j * 4);
9819 xop[1] = operands[1];
9820 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
9821 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
9823 xop[0] = GEN_INT (i * 4);
9824 xop[1] = operands[1];
9825 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
9826 return "";
9830 return "{lsi|lswi} %2,%1,%N0";
9834 /* A validation routine: say whether CODE, a condition code, and MODE
9835 match. The other alternatives either don't make sense or should
9836 never be generated. */
9838 void
9839 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
9841 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
9842 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
9843 && GET_MODE_CLASS (mode) == MODE_CC);
9845 /* These don't make sense. */
9846 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
9847 || mode != CCUNSmode);
9849 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
9850 || mode == CCUNSmode);
9852 gcc_assert (mode == CCFPmode
9853 || (code != ORDERED && code != UNORDERED
9854 && code != UNEQ && code != LTGT
9855 && code != UNGT && code != UNLT
9856 && code != UNGE && code != UNLE));
9858 /* These should never be generated except for
9859 flag_finite_math_only. */
9860 gcc_assert (mode != CCFPmode
9861 || flag_finite_math_only
9862 || (code != LE && code != GE
9863 && code != UNEQ && code != LTGT
9864 && code != UNGT && code != UNLT));
9866 /* These are invalid; the information is not there. */
9867 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
9871 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9872 mask required to convert the result of a rotate insn into a shift
9873 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9876 includes_lshift_p (rtx shiftop, rtx andop)
9878 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9880 shift_mask <<= INTVAL (shiftop);
9882 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9885 /* Similar, but for right shift. */
9888 includes_rshift_p (rtx shiftop, rtx andop)
9890 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9892 shift_mask >>= INTVAL (shiftop);
9894 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9897 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9898 to perform a left shift. It must have exactly SHIFTOP least
9899 significant 0's, then one or more 1's, then zero or more 0's. */
9902 includes_rldic_lshift_p (rtx shiftop, rtx andop)
9904 if (GET_CODE (andop) == CONST_INT)
9906 HOST_WIDE_INT c, lsb, shift_mask;
9908 c = INTVAL (andop);
9909 if (c == 0 || c == ~0)
9910 return 0;
9912 shift_mask = ~0;
9913 shift_mask <<= INTVAL (shiftop);
9915 /* Find the least significant one bit. */
9916 lsb = c & -c;
9918 /* It must coincide with the LSB of the shift mask. */
9919 if (-lsb != shift_mask)
9920 return 0;
9922 /* Invert to look for the next transition (if any). */
9923 c = ~c;
9925 /* Remove the low group of ones (originally low group of zeros). */
9926 c &= -lsb;
9928 /* Again find the lsb, and check we have all 1's above. */
9929 lsb = c & -c;
9930 return c == -lsb;
9932 else if (GET_CODE (andop) == CONST_DOUBLE
9933 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9935 HOST_WIDE_INT low, high, lsb;
9936 HOST_WIDE_INT shift_mask_low, shift_mask_high;
9938 low = CONST_DOUBLE_LOW (andop);
9939 if (HOST_BITS_PER_WIDE_INT < 64)
9940 high = CONST_DOUBLE_HIGH (andop);
9942 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
9943 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
9944 return 0;
9946 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9948 shift_mask_high = ~0;
9949 if (INTVAL (shiftop) > 32)
9950 shift_mask_high <<= INTVAL (shiftop) - 32;
9952 lsb = high & -high;
9954 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
9955 return 0;
9957 high = ~high;
9958 high &= -lsb;
9960 lsb = high & -high;
9961 return high == -lsb;
9964 shift_mask_low = ~0;
9965 shift_mask_low <<= INTVAL (shiftop);
9967 lsb = low & -low;
9969 if (-lsb != shift_mask_low)
9970 return 0;
9972 if (HOST_BITS_PER_WIDE_INT < 64)
9973 high = ~high;
9974 low = ~low;
9975 low &= -lsb;
9977 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9979 lsb = high & -high;
9980 return high == -lsb;
9983 lsb = low & -low;
9984 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
9986 else
9987 return 0;
9990 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
9991 to perform a left shift. It must have SHIFTOP or more least
9992 significant 0's, with the remainder of the word 1's. */
9995 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
9997 if (GET_CODE (andop) == CONST_INT)
9999 HOST_WIDE_INT c, lsb, shift_mask;
10001 shift_mask = ~0;
10002 shift_mask <<= INTVAL (shiftop);
10003 c = INTVAL (andop);
10005 /* Find the least significant one bit. */
10006 lsb = c & -c;
10008 /* It must be covered by the shift mask.
10009 This test also rejects c == 0. */
10010 if ((lsb & shift_mask) == 0)
10011 return 0;
10013 /* Check we have all 1's above the transition, and reject all 1's. */
10014 return c == -lsb && lsb != 1;
10016 else if (GET_CODE (andop) == CONST_DOUBLE
10017 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
10019 HOST_WIDE_INT low, lsb, shift_mask_low;
10021 low = CONST_DOUBLE_LOW (andop);
10023 if (HOST_BITS_PER_WIDE_INT < 64)
10025 HOST_WIDE_INT high, shift_mask_high;
10027 high = CONST_DOUBLE_HIGH (andop);
10029 if (low == 0)
10031 shift_mask_high = ~0;
10032 if (INTVAL (shiftop) > 32)
10033 shift_mask_high <<= INTVAL (shiftop) - 32;
10035 lsb = high & -high;
10037 if ((lsb & shift_mask_high) == 0)
10038 return 0;
10040 return high == -lsb;
10042 if (high != ~0)
10043 return 0;
10046 shift_mask_low = ~0;
10047 shift_mask_low <<= INTVAL (shiftop);
10049 lsb = low & -low;
10051 if ((lsb & shift_mask_low) == 0)
10052 return 0;
10054 return low == -lsb && lsb != 1;
10056 else
10057 return 0;
10060 /* Return 1 if operands will generate a valid arguments to rlwimi
10061 instruction for insert with right shift in 64-bit mode. The mask may
10062 not start on the first bit or stop on the last bit because wrap-around
10063 effects of instruction do not correspond to semantics of RTL insn. */
10066 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
10068 if (INTVAL (startop) > 32
10069 && INTVAL (startop) < 64
10070 && INTVAL (sizeop) > 1
10071 && INTVAL (sizeop) + INTVAL (startop) < 64
10072 && INTVAL (shiftop) > 0
10073 && INTVAL (sizeop) + INTVAL (shiftop) < 32
10074 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
10075 return 1;
10077 return 0;
10080 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
10081 for lfq and stfq insns iff the registers are hard registers. */
10084 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
10086 /* We might have been passed a SUBREG. */
10087 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
10088 return 0;
10090 /* We might have been passed non floating point registers. */
10091 if (!FP_REGNO_P (REGNO (reg1))
10092 || !FP_REGNO_P (REGNO (reg2)))
10093 return 0;
10095 return (REGNO (reg1) == REGNO (reg2) - 1);
10098 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
10099 addr1 and addr2 must be in consecutive memory locations
10100 (addr2 == addr1 + 8). */
10103 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
10105 rtx addr1, addr2;
10106 unsigned int reg1, reg2;
10107 int offset1, offset2;
10109 /* The mems cannot be volatile. */
10110 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
10111 return 0;
10113 addr1 = XEXP (mem1, 0);
10114 addr2 = XEXP (mem2, 0);
10116 /* Extract an offset (if used) from the first addr. */
10117 if (GET_CODE (addr1) == PLUS)
10119 /* If not a REG, return zero. */
10120 if (GET_CODE (XEXP (addr1, 0)) != REG)
10121 return 0;
10122 else
10124 reg1 = REGNO (XEXP (addr1, 0));
10125 /* The offset must be constant! */
10126 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
10127 return 0;
10128 offset1 = INTVAL (XEXP (addr1, 1));
10131 else if (GET_CODE (addr1) != REG)
10132 return 0;
10133 else
10135 reg1 = REGNO (addr1);
10136 /* This was a simple (mem (reg)) expression. Offset is 0. */
10137 offset1 = 0;
10140 /* And now for the second addr. */
10141 if (GET_CODE (addr2) == PLUS)
10143 /* If not a REG, return zero. */
10144 if (GET_CODE (XEXP (addr2, 0)) != REG)
10145 return 0;
10146 else
10148 reg2 = REGNO (XEXP (addr2, 0));
10149 /* The offset must be constant. */
10150 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
10151 return 0;
10152 offset2 = INTVAL (XEXP (addr2, 1));
10155 else if (GET_CODE (addr2) != REG)
10156 return 0;
10157 else
10159 reg2 = REGNO (addr2);
10160 /* This was a simple (mem (reg)) expression. Offset is 0. */
10161 offset2 = 0;
10164 /* Both of these must have the same base register. */
10165 if (reg1 != reg2)
10166 return 0;
10168 /* The offset for the second addr must be 8 more than the first addr. */
10169 if (offset2 != offset1 + 8)
10170 return 0;
10172 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
10173 instructions. */
10174 return 1;
10177 /* Return the register class of a scratch register needed to copy IN into
10178 or out of a register in CLASS in MODE. If it can be done directly,
10179 NO_REGS is returned. */
10181 enum reg_class
10182 rs6000_secondary_reload_class (enum reg_class class,
10183 enum machine_mode mode ATTRIBUTE_UNUSED,
10184 rtx in)
10186 int regno;
10188 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
10189 #if TARGET_MACHO
10190 && MACHOPIC_INDIRECT
10191 #endif
10194 /* We cannot copy a symbolic operand directly into anything
10195 other than BASE_REGS for TARGET_ELF. So indicate that a
10196 register from BASE_REGS is needed as an intermediate
10197 register.
10199 On Darwin, pic addresses require a load from memory, which
10200 needs a base register. */
10201 if (class != BASE_REGS
10202 && (GET_CODE (in) == SYMBOL_REF
10203 || GET_CODE (in) == HIGH
10204 || GET_CODE (in) == LABEL_REF
10205 || GET_CODE (in) == CONST))
10206 return BASE_REGS;
10209 if (GET_CODE (in) == REG)
10211 regno = REGNO (in);
10212 if (regno >= FIRST_PSEUDO_REGISTER)
10214 regno = true_regnum (in);
10215 if (regno >= FIRST_PSEUDO_REGISTER)
10216 regno = -1;
10219 else if (GET_CODE (in) == SUBREG)
10221 regno = true_regnum (in);
10222 if (regno >= FIRST_PSEUDO_REGISTER)
10223 regno = -1;
10225 else
10226 regno = -1;
10228 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
10229 into anything. */
10230 if (class == GENERAL_REGS || class == BASE_REGS
10231 || (regno >= 0 && INT_REGNO_P (regno)))
10232 return NO_REGS;
10234 /* Constants, memory, and FP registers can go into FP registers. */
10235 if ((regno == -1 || FP_REGNO_P (regno))
10236 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
10237 return NO_REGS;
10239 /* Memory, and AltiVec registers can go into AltiVec registers. */
10240 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
10241 && class == ALTIVEC_REGS)
10242 return NO_REGS;
10244 /* We can copy among the CR registers. */
10245 if ((class == CR_REGS || class == CR0_REGS)
10246 && regno >= 0 && CR_REGNO_P (regno))
10247 return NO_REGS;
10249 /* Otherwise, we need GENERAL_REGS. */
10250 return GENERAL_REGS;
10253 /* Given a comparison operation, return the bit number in CCR to test. We
10254 know this is a valid comparison.
10256 SCC_P is 1 if this is for an scc. That means that %D will have been
10257 used instead of %C, so the bits will be in different places.
10259 Return -1 if OP isn't a valid comparison for some reason. */
10262 ccr_bit (rtx op, int scc_p)
10264 enum rtx_code code = GET_CODE (op);
10265 enum machine_mode cc_mode;
10266 int cc_regnum;
10267 int base_bit;
10268 rtx reg;
10270 if (!COMPARISON_P (op))
10271 return -1;
10273 reg = XEXP (op, 0);
10275 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
10277 cc_mode = GET_MODE (reg);
10278 cc_regnum = REGNO (reg);
10279 base_bit = 4 * (cc_regnum - CR0_REGNO);
10281 validate_condition_mode (code, cc_mode);
10283 /* When generating a sCOND operation, only positive conditions are
10284 allowed. */
10285 gcc_assert (!scc_p
10286 || code == EQ || code == GT || code == LT || code == UNORDERED
10287 || code == GTU || code == LTU);
10289 switch (code)
10291 case NE:
10292 return scc_p ? base_bit + 3 : base_bit + 2;
10293 case EQ:
10294 return base_bit + 2;
10295 case GT: case GTU: case UNLE:
10296 return base_bit + 1;
10297 case LT: case LTU: case UNGE:
10298 return base_bit;
10299 case ORDERED: case UNORDERED:
10300 return base_bit + 3;
10302 case GE: case GEU:
10303 /* If scc, we will have done a cror to put the bit in the
10304 unordered position. So test that bit. For integer, this is ! LT
10305 unless this is an scc insn. */
10306 return scc_p ? base_bit + 3 : base_bit;
10308 case LE: case LEU:
10309 return scc_p ? base_bit + 3 : base_bit + 1;
10311 default:
10312 gcc_unreachable ();
10316 /* Return the GOT register. */
10319 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
10321 /* The second flow pass currently (June 1999) can't update
10322 regs_ever_live without disturbing other parts of the compiler, so
10323 update it here to make the prolog/epilogue code happy. */
10324 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
10325 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
10327 current_function_uses_pic_offset_table = 1;
10329 return pic_offset_table_rtx;
10332 /* Function to init struct machine_function.
10333 This will be called, via a pointer variable,
10334 from push_function_context. */
10336 static struct machine_function *
10337 rs6000_init_machine_status (void)
10339 return ggc_alloc_cleared (sizeof (machine_function));
10342 /* These macros test for integers and extract the low-order bits. */
10343 #define INT_P(X) \
10344 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
10345 && GET_MODE (X) == VOIDmode)
10347 #define INT_LOWPART(X) \
10348 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
10351 extract_MB (rtx op)
10353 int i;
10354 unsigned long val = INT_LOWPART (op);
10356 /* If the high bit is zero, the value is the first 1 bit we find
10357 from the left. */
10358 if ((val & 0x80000000) == 0)
10360 gcc_assert (val & 0xffffffff);
10362 i = 1;
10363 while (((val <<= 1) & 0x80000000) == 0)
10364 ++i;
10365 return i;
10368 /* If the high bit is set and the low bit is not, or the mask is all
10369 1's, the value is zero. */
10370 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
10371 return 0;
10373 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10374 from the right. */
10375 i = 31;
10376 while (((val >>= 1) & 1) != 0)
10377 --i;
10379 return i;
10383 extract_ME (rtx op)
10385 int i;
10386 unsigned long val = INT_LOWPART (op);
10388 /* If the low bit is zero, the value is the first 1 bit we find from
10389 the right. */
10390 if ((val & 1) == 0)
10392 gcc_assert (val & 0xffffffff);
10394 i = 30;
10395 while (((val >>= 1) & 1) == 0)
10396 --i;
10398 return i;
10401 /* If the low bit is set and the high bit is not, or the mask is all
10402 1's, the value is 31. */
10403 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
10404 return 31;
10406 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10407 from the left. */
10408 i = 0;
10409 while (((val <<= 1) & 0x80000000) != 0)
10410 ++i;
10412 return i;
10415 /* Locate some local-dynamic symbol still in use by this function
10416 so that we can print its name in some tls_ld pattern. */
10418 static const char *
10419 rs6000_get_some_local_dynamic_name (void)
10421 rtx insn;
10423 if (cfun->machine->some_ld_name)
10424 return cfun->machine->some_ld_name;
10426 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
10427 if (INSN_P (insn)
10428 && for_each_rtx (&PATTERN (insn),
10429 rs6000_get_some_local_dynamic_name_1, 0))
10430 return cfun->machine->some_ld_name;
10432 gcc_unreachable ();
10435 /* Helper function for rs6000_get_some_local_dynamic_name. */
10437 static int
10438 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
10440 rtx x = *px;
10442 if (GET_CODE (x) == SYMBOL_REF)
10444 const char *str = XSTR (x, 0);
10445 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
10447 cfun->machine->some_ld_name = str;
10448 return 1;
10452 return 0;
10455 /* Write out a function code label. */
10457 void
10458 rs6000_output_function_entry (FILE *file, const char *fname)
10460 if (fname[0] != '.')
10462 switch (DEFAULT_ABI)
10464 default:
10465 gcc_unreachable ();
10467 case ABI_AIX:
10468 if (DOT_SYMBOLS)
10469 putc ('.', file);
10470 else
10471 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
10472 break;
10474 case ABI_V4:
10475 case ABI_DARWIN:
10476 break;
10479 if (TARGET_AIX)
10480 RS6000_OUTPUT_BASENAME (file, fname);
10481 else
10482 assemble_name (file, fname);
10485 /* Print an operand. Recognize special options, documented below. */
10487 #if TARGET_ELF
10488 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
10489 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
10490 #else
10491 #define SMALL_DATA_RELOC "sda21"
10492 #define SMALL_DATA_REG 0
10493 #endif
10495 void
10496 print_operand (FILE *file, rtx x, int code)
10498 int i;
10499 HOST_WIDE_INT val;
10500 unsigned HOST_WIDE_INT uval;
10502 switch (code)
10504 case '.':
10505 /* Write out an instruction after the call which may be replaced
10506 with glue code by the loader. This depends on the AIX version. */
10507 asm_fprintf (file, RS6000_CALL_GLUE);
10508 return;
10510 /* %a is output_address. */
10512 case 'A':
10513 /* If X is a constant integer whose low-order 5 bits are zero,
10514 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10515 in the AIX assembler where "sri" with a zero shift count
10516 writes a trash instruction. */
10517 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
10518 putc ('l', file);
10519 else
10520 putc ('r', file);
10521 return;
10523 case 'b':
10524 /* If constant, low-order 16 bits of constant, unsigned.
10525 Otherwise, write normally. */
10526 if (INT_P (x))
10527 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
10528 else
10529 print_operand (file, x, 0);
10530 return;
10532 case 'B':
10533 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10534 for 64-bit mask direction. */
10535 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
10536 return;
10538 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10539 output_operand. */
10541 case 'c':
10542 /* X is a CR register. Print the number of the GT bit of the CR. */
10543 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10544 output_operand_lossage ("invalid %%E value");
10545 else
10546 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
10547 return;
10549 case 'D':
10550 /* Like 'J' but get to the GT bit only. */
10551 gcc_assert (GET_CODE (x) == REG);
10553 /* Bit 1 is GT bit. */
10554 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
10556 /* Add one for shift count in rlinm for scc. */
10557 fprintf (file, "%d", i + 1);
10558 return;
10560 case 'E':
10561 /* X is a CR register. Print the number of the EQ bit of the CR */
10562 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10563 output_operand_lossage ("invalid %%E value");
10564 else
10565 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
10566 return;
10568 case 'f':
10569 /* X is a CR register. Print the shift count needed to move it
10570 to the high-order four bits. */
10571 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10572 output_operand_lossage ("invalid %%f value");
10573 else
10574 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
10575 return;
10577 case 'F':
10578 /* Similar, but print the count for the rotate in the opposite
10579 direction. */
10580 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10581 output_operand_lossage ("invalid %%F value");
10582 else
10583 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
10584 return;
10586 case 'G':
10587 /* X is a constant integer. If it is negative, print "m",
10588 otherwise print "z". This is to make an aze or ame insn. */
10589 if (GET_CODE (x) != CONST_INT)
10590 output_operand_lossage ("invalid %%G value");
10591 else if (INTVAL (x) >= 0)
10592 putc ('z', file);
10593 else
10594 putc ('m', file);
10595 return;
10597 case 'h':
10598 /* If constant, output low-order five bits. Otherwise, write
10599 normally. */
10600 if (INT_P (x))
10601 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
10602 else
10603 print_operand (file, x, 0);
10604 return;
10606 case 'H':
10607 /* If constant, output low-order six bits. Otherwise, write
10608 normally. */
10609 if (INT_P (x))
10610 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
10611 else
10612 print_operand (file, x, 0);
10613 return;
10615 case 'I':
10616 /* Print `i' if this is a constant, else nothing. */
10617 if (INT_P (x))
10618 putc ('i', file);
10619 return;
10621 case 'j':
10622 /* Write the bit number in CCR for jump. */
10623 i = ccr_bit (x, 0);
10624 if (i == -1)
10625 output_operand_lossage ("invalid %%j code");
10626 else
10627 fprintf (file, "%d", i);
10628 return;
10630 case 'J':
10631 /* Similar, but add one for shift count in rlinm for scc and pass
10632 scc flag to `ccr_bit'. */
10633 i = ccr_bit (x, 1);
10634 if (i == -1)
10635 output_operand_lossage ("invalid %%J code");
10636 else
10637 /* If we want bit 31, write a shift count of zero, not 32. */
10638 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10639 return;
10641 case 'k':
10642 /* X must be a constant. Write the 1's complement of the
10643 constant. */
10644 if (! INT_P (x))
10645 output_operand_lossage ("invalid %%k value");
10646 else
10647 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
10648 return;
10650 case 'K':
10651 /* X must be a symbolic constant on ELF. Write an
10652 expression suitable for an 'addi' that adds in the low 16
10653 bits of the MEM. */
10654 if (GET_CODE (x) != CONST)
10656 print_operand_address (file, x);
10657 fputs ("@l", file);
10659 else
10661 if (GET_CODE (XEXP (x, 0)) != PLUS
10662 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
10663 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
10664 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
10665 output_operand_lossage ("invalid %%K value");
10666 print_operand_address (file, XEXP (XEXP (x, 0), 0));
10667 fputs ("@l", file);
10668 /* For GNU as, there must be a non-alphanumeric character
10669 between 'l' and the number. The '-' is added by
10670 print_operand() already. */
10671 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
10672 fputs ("+", file);
10673 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
10675 return;
10677 /* %l is output_asm_label. */
10679 case 'L':
10680 /* Write second word of DImode or DFmode reference. Works on register
10681 or non-indexed memory only. */
10682 if (GET_CODE (x) == REG)
10683 fputs (reg_names[REGNO (x) + 1], file);
10684 else if (GET_CODE (x) == MEM)
10686 /* Handle possible auto-increment. Since it is pre-increment and
10687 we have already done it, we can just use an offset of word. */
10688 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10689 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10690 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
10691 UNITS_PER_WORD));
10692 else
10693 output_address (XEXP (adjust_address_nv (x, SImode,
10694 UNITS_PER_WORD),
10695 0));
10697 if (small_data_operand (x, GET_MODE (x)))
10698 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10699 reg_names[SMALL_DATA_REG]);
10701 return;
10703 case 'm':
10704 /* MB value for a mask operand. */
10705 if (! mask_operand (x, SImode))
10706 output_operand_lossage ("invalid %%m value");
10708 fprintf (file, "%d", extract_MB (x));
10709 return;
10711 case 'M':
10712 /* ME value for a mask operand. */
10713 if (! mask_operand (x, SImode))
10714 output_operand_lossage ("invalid %%M value");
10716 fprintf (file, "%d", extract_ME (x));
10717 return;
10719 /* %n outputs the negative of its operand. */
10721 case 'N':
10722 /* Write the number of elements in the vector times 4. */
10723 if (GET_CODE (x) != PARALLEL)
10724 output_operand_lossage ("invalid %%N value");
10725 else
10726 fprintf (file, "%d", XVECLEN (x, 0) * 4);
10727 return;
10729 case 'O':
10730 /* Similar, but subtract 1 first. */
10731 if (GET_CODE (x) != PARALLEL)
10732 output_operand_lossage ("invalid %%O value");
10733 else
10734 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
10735 return;
10737 case 'p':
10738 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10739 if (! INT_P (x)
10740 || INT_LOWPART (x) < 0
10741 || (i = exact_log2 (INT_LOWPART (x))) < 0)
10742 output_operand_lossage ("invalid %%p value");
10743 else
10744 fprintf (file, "%d", i);
10745 return;
10747 case 'P':
10748 /* The operand must be an indirect memory reference. The result
10749 is the register name. */
10750 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
10751 || REGNO (XEXP (x, 0)) >= 32)
10752 output_operand_lossage ("invalid %%P value");
10753 else
10754 fputs (reg_names[REGNO (XEXP (x, 0))], file);
10755 return;
10757 case 'q':
10758 /* This outputs the logical code corresponding to a boolean
10759 expression. The expression may have one or both operands
10760 negated (if one, only the first one). For condition register
10761 logical operations, it will also treat the negated
10762 CR codes as NOTs, but not handle NOTs of them. */
10764 const char *const *t = 0;
10765 const char *s;
10766 enum rtx_code code = GET_CODE (x);
10767 static const char * const tbl[3][3] = {
10768 { "and", "andc", "nor" },
10769 { "or", "orc", "nand" },
10770 { "xor", "eqv", "xor" } };
10772 if (code == AND)
10773 t = tbl[0];
10774 else if (code == IOR)
10775 t = tbl[1];
10776 else if (code == XOR)
10777 t = tbl[2];
10778 else
10779 output_operand_lossage ("invalid %%q value");
10781 if (GET_CODE (XEXP (x, 0)) != NOT)
10782 s = t[0];
10783 else
10785 if (GET_CODE (XEXP (x, 1)) == NOT)
10786 s = t[2];
10787 else
10788 s = t[1];
10791 fputs (s, file);
10793 return;
10795 case 'Q':
10796 if (TARGET_MFCRF)
10797 fputc (',', file);
10798 /* FALLTHRU */
10799 else
10800 return;
10802 case 'R':
10803 /* X is a CR register. Print the mask for `mtcrf'. */
10804 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10805 output_operand_lossage ("invalid %%R value");
10806 else
10807 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
10808 return;
10810 case 's':
10811 /* Low 5 bits of 32 - value */
10812 if (! INT_P (x))
10813 output_operand_lossage ("invalid %%s value");
10814 else
10815 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
10816 return;
10818 case 'S':
10819 /* PowerPC64 mask position. All 0's is excluded.
10820 CONST_INT 32-bit mask is considered sign-extended so any
10821 transition must occur within the CONST_INT, not on the boundary. */
10822 if (! mask64_operand (x, DImode))
10823 output_operand_lossage ("invalid %%S value");
10825 uval = INT_LOWPART (x);
10827 if (uval & 1) /* Clear Left */
10829 #if HOST_BITS_PER_WIDE_INT > 64
10830 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10831 #endif
10832 i = 64;
10834 else /* Clear Right */
10836 uval = ~uval;
10837 #if HOST_BITS_PER_WIDE_INT > 64
10838 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10839 #endif
10840 i = 63;
10842 while (uval != 0)
10843 --i, uval >>= 1;
10844 gcc_assert (i >= 0);
10845 fprintf (file, "%d", i);
10846 return;
10848 case 't':
10849 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10850 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
10852 /* Bit 3 is OV bit. */
10853 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
10855 /* If we want bit 31, write a shift count of zero, not 32. */
10856 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10857 return;
10859 case 'T':
10860 /* Print the symbolic name of a branch target register. */
10861 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
10862 && REGNO (x) != COUNT_REGISTER_REGNUM))
10863 output_operand_lossage ("invalid %%T value");
10864 else if (REGNO (x) == LINK_REGISTER_REGNUM)
10865 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
10866 else
10867 fputs ("ctr", file);
10868 return;
10870 case 'u':
10871 /* High-order 16 bits of constant for use in unsigned operand. */
10872 if (! INT_P (x))
10873 output_operand_lossage ("invalid %%u value");
10874 else
10875 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10876 (INT_LOWPART (x) >> 16) & 0xffff);
10877 return;
10879 case 'v':
10880 /* High-order 16 bits of constant for use in signed operand. */
10881 if (! INT_P (x))
10882 output_operand_lossage ("invalid %%v value");
10883 else
10884 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10885 (INT_LOWPART (x) >> 16) & 0xffff);
10886 return;
10888 case 'U':
10889 /* Print `u' if this has an auto-increment or auto-decrement. */
10890 if (GET_CODE (x) == MEM
10891 && (GET_CODE (XEXP (x, 0)) == PRE_INC
10892 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
10893 putc ('u', file);
10894 return;
10896 case 'V':
10897 /* Print the trap code for this operand. */
10898 switch (GET_CODE (x))
10900 case EQ:
10901 fputs ("eq", file); /* 4 */
10902 break;
10903 case NE:
10904 fputs ("ne", file); /* 24 */
10905 break;
10906 case LT:
10907 fputs ("lt", file); /* 16 */
10908 break;
10909 case LE:
10910 fputs ("le", file); /* 20 */
10911 break;
10912 case GT:
10913 fputs ("gt", file); /* 8 */
10914 break;
10915 case GE:
10916 fputs ("ge", file); /* 12 */
10917 break;
10918 case LTU:
10919 fputs ("llt", file); /* 2 */
10920 break;
10921 case LEU:
10922 fputs ("lle", file); /* 6 */
10923 break;
10924 case GTU:
10925 fputs ("lgt", file); /* 1 */
10926 break;
10927 case GEU:
10928 fputs ("lge", file); /* 5 */
10929 break;
10930 default:
10931 gcc_unreachable ();
10933 break;
10935 case 'w':
10936 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10937 normally. */
10938 if (INT_P (x))
10939 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
10940 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
10941 else
10942 print_operand (file, x, 0);
10943 return;
10945 case 'W':
10946 /* MB value for a PowerPC64 rldic operand. */
10947 val = (GET_CODE (x) == CONST_INT
10948 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
10950 if (val < 0)
10951 i = -1;
10952 else
10953 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
10954 if ((val <<= 1) < 0)
10955 break;
10957 #if HOST_BITS_PER_WIDE_INT == 32
10958 if (GET_CODE (x) == CONST_INT && i >= 0)
10959 i += 32; /* zero-extend high-part was all 0's */
10960 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
10962 val = CONST_DOUBLE_LOW (x);
10964 gcc_assert (val);
10965 if (val < 0)
10966 --i;
10967 else
10968 for ( ; i < 64; i++)
10969 if ((val <<= 1) < 0)
10970 break;
10972 #endif
10974 fprintf (file, "%d", i + 1);
10975 return;
10977 case 'X':
10978 if (GET_CODE (x) == MEM
10979 && legitimate_indexed_address_p (XEXP (x, 0), 0))
10980 putc ('x', file);
10981 return;
10983 case 'Y':
10984 /* Like 'L', for third word of TImode */
10985 if (GET_CODE (x) == REG)
10986 fputs (reg_names[REGNO (x) + 2], file);
10987 else if (GET_CODE (x) == MEM)
10989 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10990 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10991 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
10992 else
10993 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
10994 if (small_data_operand (x, GET_MODE (x)))
10995 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10996 reg_names[SMALL_DATA_REG]);
10998 return;
11000 case 'z':
11001 /* X is a SYMBOL_REF. Write out the name preceded by a
11002 period and without any trailing data in brackets. Used for function
11003 names. If we are configured for System V (or the embedded ABI) on
11004 the PowerPC, do not emit the period, since those systems do not use
11005 TOCs and the like. */
11006 gcc_assert (GET_CODE (x) == SYMBOL_REF);
11008 /* Mark the decl as referenced so that cgraph will output the
11009 function. */
11010 if (SYMBOL_REF_DECL (x))
11011 mark_decl_referenced (SYMBOL_REF_DECL (x));
11013 /* For macho, check to see if we need a stub. */
11014 if (TARGET_MACHO)
11016 const char *name = XSTR (x, 0);
11017 #if TARGET_MACHO
11018 if (MACHOPIC_INDIRECT
11019 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
11020 name = machopic_indirection_name (x, /*stub_p=*/true);
11021 #endif
11022 assemble_name (file, name);
11024 else if (!DOT_SYMBOLS)
11025 assemble_name (file, XSTR (x, 0));
11026 else
11027 rs6000_output_function_entry (file, XSTR (x, 0));
11028 return;
11030 case 'Z':
11031 /* Like 'L', for last word of TImode. */
11032 if (GET_CODE (x) == REG)
11033 fputs (reg_names[REGNO (x) + 3], file);
11034 else if (GET_CODE (x) == MEM)
11036 if (GET_CODE (XEXP (x, 0)) == PRE_INC
11037 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
11038 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
11039 else
11040 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
11041 if (small_data_operand (x, GET_MODE (x)))
11042 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11043 reg_names[SMALL_DATA_REG]);
11045 return;
11047 /* Print AltiVec or SPE memory operand. */
11048 case 'y':
11050 rtx tmp;
11052 gcc_assert (GET_CODE (x) == MEM);
11054 tmp = XEXP (x, 0);
11056 /* Ugly hack because %y is overloaded. */
11057 if ((TARGET_SPE || TARGET_E500_DOUBLE)
11058 && (GET_MODE_SIZE (GET_MODE (x)) == 8
11059 || GET_MODE (x) == TFmode
11060 || GET_MODE (x) == TImode))
11062 /* Handle [reg]. */
11063 if (GET_CODE (tmp) == REG)
11065 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
11066 break;
11068 /* Handle [reg+UIMM]. */
11069 else if (GET_CODE (tmp) == PLUS &&
11070 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
11072 int x;
11074 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
11076 x = INTVAL (XEXP (tmp, 1));
11077 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
11078 break;
11081 /* Fall through. Must be [reg+reg]. */
11083 if (TARGET_ALTIVEC
11084 && GET_CODE (tmp) == AND
11085 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
11086 && INTVAL (XEXP (tmp, 1)) == -16)
11087 tmp = XEXP (tmp, 0);
11088 if (GET_CODE (tmp) == REG)
11089 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
11090 else
11092 gcc_assert (GET_CODE (tmp) == PLUS
11093 && REG_P (XEXP (tmp, 0))
11094 && REG_P (XEXP (tmp, 1)));
11096 if (REGNO (XEXP (tmp, 0)) == 0)
11097 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
11098 reg_names[ REGNO (XEXP (tmp, 0)) ]);
11099 else
11100 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
11101 reg_names[ REGNO (XEXP (tmp, 1)) ]);
11103 break;
11106 case 0:
11107 if (GET_CODE (x) == REG)
11108 fprintf (file, "%s", reg_names[REGNO (x)]);
11109 else if (GET_CODE (x) == MEM)
11111 /* We need to handle PRE_INC and PRE_DEC here, since we need to
11112 know the width from the mode. */
11113 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
11114 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
11115 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
11116 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
11117 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
11118 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
11119 else
11120 output_address (XEXP (x, 0));
11122 else
11123 output_addr_const (file, x);
11124 return;
11126 case '&':
11127 assemble_name (file, rs6000_get_some_local_dynamic_name ());
11128 return;
11130 default:
11131 output_operand_lossage ("invalid %%xn code");
11135 /* Print the address of an operand. */
11137 void
11138 print_operand_address (FILE *file, rtx x)
11140 if (GET_CODE (x) == REG)
11141 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
11142 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
11143 || GET_CODE (x) == LABEL_REF)
11145 output_addr_const (file, x);
11146 if (small_data_operand (x, GET_MODE (x)))
11147 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11148 reg_names[SMALL_DATA_REG]);
11149 else
11150 gcc_assert (!TARGET_TOC);
11152 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
11154 gcc_assert (REG_P (XEXP (x, 0)));
11155 if (REGNO (XEXP (x, 0)) == 0)
11156 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
11157 reg_names[ REGNO (XEXP (x, 0)) ]);
11158 else
11159 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
11160 reg_names[ REGNO (XEXP (x, 1)) ]);
11162 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
11163 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
11164 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
11165 #if TARGET_ELF
11166 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
11167 && CONSTANT_P (XEXP (x, 1)))
11169 output_addr_const (file, XEXP (x, 1));
11170 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
11172 #endif
11173 #if TARGET_MACHO
11174 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
11175 && CONSTANT_P (XEXP (x, 1)))
11177 fprintf (file, "lo16(");
11178 output_addr_const (file, XEXP (x, 1));
11179 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
11181 #endif
11182 else if (legitimate_constant_pool_address_p (x))
11184 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
11186 rtx contains_minus = XEXP (x, 1);
11187 rtx minus, symref;
11188 const char *name;
11190 /* Find the (minus (sym) (toc)) buried in X, and temporarily
11191 turn it into (sym) for output_addr_const. */
11192 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
11193 contains_minus = XEXP (contains_minus, 0);
11195 minus = XEXP (contains_minus, 0);
11196 symref = XEXP (minus, 0);
11197 XEXP (contains_minus, 0) = symref;
11198 if (TARGET_ELF)
11200 char *newname;
11202 name = XSTR (symref, 0);
11203 newname = alloca (strlen (name) + sizeof ("@toc"));
11204 strcpy (newname, name);
11205 strcat (newname, "@toc");
11206 XSTR (symref, 0) = newname;
11208 output_addr_const (file, XEXP (x, 1));
11209 if (TARGET_ELF)
11210 XSTR (symref, 0) = name;
11211 XEXP (contains_minus, 0) = minus;
11213 else
11214 output_addr_const (file, XEXP (x, 1));
11216 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
11218 else
11219 gcc_unreachable ();
11222 /* Target hook for assembling integer objects. The PowerPC version has
11223 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
11224 is defined. It also needs to handle DI-mode objects on 64-bit
11225 targets. */
11227 static bool
11228 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
11230 #ifdef RELOCATABLE_NEEDS_FIXUP
11231 /* Special handling for SI values. */
11232 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
11234 static int recurse = 0;
11236 /* For -mrelocatable, we mark all addresses that need to be fixed up
11237 in the .fixup section. */
11238 if (TARGET_RELOCATABLE
11239 && in_section != toc_section
11240 && in_section != text_section
11241 && !unlikely_text_section_p (in_section)
11242 && !recurse
11243 && GET_CODE (x) != CONST_INT
11244 && GET_CODE (x) != CONST_DOUBLE
11245 && CONSTANT_P (x))
11247 char buf[256];
11249 recurse = 1;
11250 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
11251 fixuplabelno++;
11252 ASM_OUTPUT_LABEL (asm_out_file, buf);
11253 fprintf (asm_out_file, "\t.long\t(");
11254 output_addr_const (asm_out_file, x);
11255 fprintf (asm_out_file, ")@fixup\n");
11256 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
11257 ASM_OUTPUT_ALIGN (asm_out_file, 2);
11258 fprintf (asm_out_file, "\t.long\t");
11259 assemble_name (asm_out_file, buf);
11260 fprintf (asm_out_file, "\n\t.previous\n");
11261 recurse = 0;
11262 return true;
11264 /* Remove initial .'s to turn a -mcall-aixdesc function
11265 address into the address of the descriptor, not the function
11266 itself. */
11267 else if (GET_CODE (x) == SYMBOL_REF
11268 && XSTR (x, 0)[0] == '.'
11269 && DEFAULT_ABI == ABI_AIX)
11271 const char *name = XSTR (x, 0);
11272 while (*name == '.')
11273 name++;
11275 fprintf (asm_out_file, "\t.long\t%s\n", name);
11276 return true;
11279 #endif /* RELOCATABLE_NEEDS_FIXUP */
11280 return default_assemble_integer (x, size, aligned_p);
11283 #ifdef HAVE_GAS_HIDDEN
11284 /* Emit an assembler directive to set symbol visibility for DECL to
11285 VISIBILITY_TYPE. */
11287 static void
11288 rs6000_assemble_visibility (tree decl, int vis)
11290 /* Functions need to have their entry point symbol visibility set as
11291 well as their descriptor symbol visibility. */
11292 if (DEFAULT_ABI == ABI_AIX
11293 && DOT_SYMBOLS
11294 && TREE_CODE (decl) == FUNCTION_DECL)
11296 static const char * const visibility_types[] = {
11297 NULL, "internal", "hidden", "protected"
11300 const char *name, *type;
11302 name = ((* targetm.strip_name_encoding)
11303 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
11304 type = visibility_types[vis];
11306 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
11307 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
11309 else
11310 default_assemble_visibility (decl, vis);
11312 #endif
11314 enum rtx_code
11315 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
11317 /* Reversal of FP compares takes care -- an ordered compare
11318 becomes an unordered compare and vice versa. */
11319 if (mode == CCFPmode
11320 && (!flag_finite_math_only
11321 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
11322 || code == UNEQ || code == LTGT))
11323 return reverse_condition_maybe_unordered (code);
11324 else
11325 return reverse_condition (code);
11328 /* Generate a compare for CODE. Return a brand-new rtx that
11329 represents the result of the compare. */
11331 static rtx
11332 rs6000_generate_compare (enum rtx_code code)
11334 enum machine_mode comp_mode;
11335 rtx compare_result;
11337 if (rs6000_compare_fp_p)
11338 comp_mode = CCFPmode;
11339 else if (code == GTU || code == LTU
11340 || code == GEU || code == LEU)
11341 comp_mode = CCUNSmode;
11342 else if ((code == EQ || code == NE)
11343 && GET_CODE (rs6000_compare_op0) == SUBREG
11344 && GET_CODE (rs6000_compare_op1) == SUBREG
11345 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
11346 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
11347 /* These are unsigned values, perhaps there will be a later
11348 ordering compare that can be shared with this one.
11349 Unfortunately we cannot detect the signedness of the operands
11350 for non-subregs. */
11351 comp_mode = CCUNSmode;
11352 else
11353 comp_mode = CCmode;
11355 /* First, the compare. */
11356 compare_result = gen_reg_rtx (comp_mode);
11358 /* E500 FP compare instructions on the GPRs. Yuck! */
11359 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
11360 && rs6000_compare_fp_p)
11362 rtx cmp, or_result, compare_result2;
11363 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
11365 if (op_mode == VOIDmode)
11366 op_mode = GET_MODE (rs6000_compare_op1);
11368 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
11369 This explains the following mess. */
11371 switch (code)
11373 case EQ: case UNEQ: case NE: case LTGT:
11374 switch (op_mode)
11376 case SFmode:
11377 cmp = flag_unsafe_math_optimizations
11378 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
11379 rs6000_compare_op1)
11380 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
11381 rs6000_compare_op1);
11382 break;
11384 case DFmode:
11385 cmp = flag_unsafe_math_optimizations
11386 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
11387 rs6000_compare_op1)
11388 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
11389 rs6000_compare_op1);
11390 break;
11392 case TFmode:
11393 cmp = flag_unsafe_math_optimizations
11394 ? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
11395 rs6000_compare_op1)
11396 : gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
11397 rs6000_compare_op1);
11398 break;
11400 default:
11401 gcc_unreachable ();
11403 break;
11405 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
11406 switch (op_mode)
11408 case SFmode:
11409 cmp = flag_unsafe_math_optimizations
11410 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
11411 rs6000_compare_op1)
11412 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
11413 rs6000_compare_op1);
11414 break;
11416 case DFmode:
11417 cmp = flag_unsafe_math_optimizations
11418 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
11419 rs6000_compare_op1)
11420 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
11421 rs6000_compare_op1);
11422 break;
11424 case TFmode:
11425 cmp = flag_unsafe_math_optimizations
11426 ? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
11427 rs6000_compare_op1)
11428 : gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
11429 rs6000_compare_op1);
11430 break;
11432 default:
11433 gcc_unreachable ();
11435 break;
11437 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
11438 switch (op_mode)
11440 case SFmode:
11441 cmp = flag_unsafe_math_optimizations
11442 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
11443 rs6000_compare_op1)
11444 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
11445 rs6000_compare_op1);
11446 break;
11448 case DFmode:
11449 cmp = flag_unsafe_math_optimizations
11450 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
11451 rs6000_compare_op1)
11452 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
11453 rs6000_compare_op1);
11454 break;
11456 case TFmode:
11457 cmp = flag_unsafe_math_optimizations
11458 ? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
11459 rs6000_compare_op1)
11460 : gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
11461 rs6000_compare_op1);
11462 break;
11464 default:
11465 gcc_unreachable ();
11467 break;
11468 default:
11469 gcc_unreachable ();
11472 /* Synthesize LE and GE from LT/GT || EQ. */
11473 if (code == LE || code == GE || code == LEU || code == GEU)
11475 emit_insn (cmp);
11477 switch (code)
11479 case LE: code = LT; break;
11480 case GE: code = GT; break;
11481 case LEU: code = LT; break;
11482 case GEU: code = GT; break;
11483 default: gcc_unreachable ();
11486 compare_result2 = gen_reg_rtx (CCFPmode);
11488 /* Do the EQ. */
11489 switch (op_mode)
11491 case SFmode:
11492 cmp = flag_unsafe_math_optimizations
11493 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
11494 rs6000_compare_op1)
11495 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
11496 rs6000_compare_op1);
11497 break;
11499 case DFmode:
11500 cmp = flag_unsafe_math_optimizations
11501 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
11502 rs6000_compare_op1)
11503 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
11504 rs6000_compare_op1);
11505 break;
11507 case TFmode:
11508 cmp = flag_unsafe_math_optimizations
11509 ? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
11510 rs6000_compare_op1)
11511 : gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
11512 rs6000_compare_op1);
11513 break;
11515 default:
11516 gcc_unreachable ();
11518 emit_insn (cmp);
11520 /* OR them together. */
11521 or_result = gen_reg_rtx (CCFPmode);
11522 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
11523 compare_result2);
11524 compare_result = or_result;
11525 code = EQ;
11527 else
11529 if (code == NE || code == LTGT)
11530 code = NE;
11531 else
11532 code = EQ;
11535 emit_insn (cmp);
11537 else
11539 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11540 CLOBBERs to match cmptf_internal2 pattern. */
11541 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
11542 && GET_MODE (rs6000_compare_op0) == TFmode
11543 && !TARGET_IEEEQUAD
11544 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
11545 emit_insn (gen_rtx_PARALLEL (VOIDmode,
11546 gen_rtvec (9,
11547 gen_rtx_SET (VOIDmode,
11548 compare_result,
11549 gen_rtx_COMPARE (comp_mode,
11550 rs6000_compare_op0,
11551 rs6000_compare_op1)),
11552 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11553 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11554 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11555 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11556 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11557 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11558 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11559 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
11560 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
11561 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
11563 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
11564 comp_mode = CCEQmode;
11565 compare_result = gen_reg_rtx (CCEQmode);
11566 if (TARGET_64BIT)
11567 emit_insn (gen_stack_protect_testdi (compare_result,
11568 rs6000_compare_op0, op1));
11569 else
11570 emit_insn (gen_stack_protect_testsi (compare_result,
11571 rs6000_compare_op0, op1));
11573 else
11574 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
11575 gen_rtx_COMPARE (comp_mode,
11576 rs6000_compare_op0,
11577 rs6000_compare_op1)));
11580 /* Some kinds of FP comparisons need an OR operation;
11581 under flag_finite_math_only we don't bother. */
11582 if (rs6000_compare_fp_p
11583 && !flag_finite_math_only
11584 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
11585 && (code == LE || code == GE
11586 || code == UNEQ || code == LTGT
11587 || code == UNGT || code == UNLT))
11589 enum rtx_code or1, or2;
11590 rtx or1_rtx, or2_rtx, compare2_rtx;
11591 rtx or_result = gen_reg_rtx (CCEQmode);
11593 switch (code)
11595 case LE: or1 = LT; or2 = EQ; break;
11596 case GE: or1 = GT; or2 = EQ; break;
11597 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
11598 case LTGT: or1 = LT; or2 = GT; break;
11599 case UNGT: or1 = UNORDERED; or2 = GT; break;
11600 case UNLT: or1 = UNORDERED; or2 = LT; break;
11601 default: gcc_unreachable ();
11603 validate_condition_mode (or1, comp_mode);
11604 validate_condition_mode (or2, comp_mode);
11605 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
11606 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
11607 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
11608 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
11609 const_true_rtx);
11610 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
11612 compare_result = or_result;
11613 code = EQ;
11616 validate_condition_mode (code, GET_MODE (compare_result));
11618 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
11622 /* Emit the RTL for an sCOND pattern. */
11624 void
11625 rs6000_emit_sCOND (enum rtx_code code, rtx result)
11627 rtx condition_rtx;
11628 enum machine_mode op_mode;
11629 enum rtx_code cond_code;
11631 condition_rtx = rs6000_generate_compare (code);
11632 cond_code = GET_CODE (condition_rtx);
11634 if (rs6000_compare_fp_p
11635 && !TARGET_FPRS && TARGET_HARD_FLOAT)
11637 rtx t;
11639 PUT_MODE (condition_rtx, SImode);
11640 t = XEXP (condition_rtx, 0);
11642 gcc_assert (cond_code == NE || cond_code == EQ);
11644 if (cond_code == NE)
11645 emit_insn (gen_e500_flip_gt_bit (t, t));
11647 emit_insn (gen_move_from_CR_gt_bit (result, t));
11648 return;
11651 if (cond_code == NE
11652 || cond_code == GE || cond_code == LE
11653 || cond_code == GEU || cond_code == LEU
11654 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
11656 rtx not_result = gen_reg_rtx (CCEQmode);
11657 rtx not_op, rev_cond_rtx;
11658 enum machine_mode cc_mode;
11660 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
11662 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
11663 SImode, XEXP (condition_rtx, 0), const0_rtx);
11664 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
11665 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
11666 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
11669 op_mode = GET_MODE (rs6000_compare_op0);
11670 if (op_mode == VOIDmode)
11671 op_mode = GET_MODE (rs6000_compare_op1);
11673 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
11675 PUT_MODE (condition_rtx, DImode);
11676 convert_move (result, condition_rtx, 0);
11678 else
11680 PUT_MODE (condition_rtx, SImode);
11681 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
11685 /* Emit a branch of kind CODE to location LOC. */
11687 void
11688 rs6000_emit_cbranch (enum rtx_code code, rtx loc)
11690 rtx condition_rtx, loc_ref;
11692 condition_rtx = rs6000_generate_compare (code);
11693 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
11694 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
11695 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
11696 loc_ref, pc_rtx)));
11699 /* Return the string to output a conditional branch to LABEL, which is
11700 the operand number of the label, or -1 if the branch is really a
11701 conditional return.
11703 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11704 condition code register and its mode specifies what kind of
11705 comparison we made.
11707 REVERSED is nonzero if we should reverse the sense of the comparison.
11709 INSN is the insn. */
11711 char *
11712 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
11714 static char string[64];
11715 enum rtx_code code = GET_CODE (op);
11716 rtx cc_reg = XEXP (op, 0);
11717 enum machine_mode mode = GET_MODE (cc_reg);
11718 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
11719 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
11720 int really_reversed = reversed ^ need_longbranch;
11721 char *s = string;
11722 const char *ccode;
11723 const char *pred;
11724 rtx note;
11726 validate_condition_mode (code, mode);
11728 /* Work out which way this really branches. We could use
11729 reverse_condition_maybe_unordered here always but this
11730 makes the resulting assembler clearer. */
11731 if (really_reversed)
11733 /* Reversal of FP compares takes care -- an ordered compare
11734 becomes an unordered compare and vice versa. */
11735 if (mode == CCFPmode)
11736 code = reverse_condition_maybe_unordered (code);
11737 else
11738 code = reverse_condition (code);
11741 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
11743 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11744 to the GT bit. */
11745 switch (code)
11747 case EQ:
11748 /* Opposite of GT. */
11749 code = GT;
11750 break;
11752 case NE:
11753 code = UNLE;
11754 break;
11756 default:
11757 gcc_unreachable ();
11761 switch (code)
11763 /* Not all of these are actually distinct opcodes, but
11764 we distinguish them for clarity of the resulting assembler. */
11765 case NE: case LTGT:
11766 ccode = "ne"; break;
11767 case EQ: case UNEQ:
11768 ccode = "eq"; break;
11769 case GE: case GEU:
11770 ccode = "ge"; break;
11771 case GT: case GTU: case UNGT:
11772 ccode = "gt"; break;
11773 case LE: case LEU:
11774 ccode = "le"; break;
11775 case LT: case LTU: case UNLT:
11776 ccode = "lt"; break;
11777 case UNORDERED: ccode = "un"; break;
11778 case ORDERED: ccode = "nu"; break;
11779 case UNGE: ccode = "nl"; break;
11780 case UNLE: ccode = "ng"; break;
11781 default:
11782 gcc_unreachable ();
11785 /* Maybe we have a guess as to how likely the branch is.
11786 The old mnemonics don't have a way to specify this information. */
11787 pred = "";
11788 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
11789 if (note != NULL_RTX)
11791 /* PROB is the difference from 50%. */
11792 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
11794 /* Only hint for highly probable/improbable branches on newer
11795 cpus as static prediction overrides processor dynamic
11796 prediction. For older cpus we may as well always hint, but
11797 assume not taken for branches that are very close to 50% as a
11798 mispredicted taken branch is more expensive than a
11799 mispredicted not-taken branch. */
11800 if (rs6000_always_hint
11801 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
11802 && br_prob_note_reliable_p (note)))
11804 if (abs (prob) > REG_BR_PROB_BASE / 20
11805 && ((prob > 0) ^ need_longbranch))
11806 pred = "+";
11807 else
11808 pred = "-";
11812 if (label == NULL)
11813 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
11814 else
11815 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
11817 /* We need to escape any '%' characters in the reg_names string.
11818 Assume they'd only be the first character.... */
11819 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
11820 *s++ = '%';
11821 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
11823 if (label != NULL)
11825 /* If the branch distance was too far, we may have to use an
11826 unconditional branch to go the distance. */
11827 if (need_longbranch)
11828 s += sprintf (s, ",$+8\n\tb %s", label);
11829 else
11830 s += sprintf (s, ",%s", label);
11833 return string;
11836 /* Return the string to flip the GT bit on a CR. */
11837 char *
11838 output_e500_flip_gt_bit (rtx dst, rtx src)
11840 static char string[64];
11841 int a, b;
11843 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
11844 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
11846 /* GT bit. */
11847 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
11848 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
11850 sprintf (string, "crnot %d,%d", a, b);
11851 return string;
11854 /* Return insn index for the vector compare instruction for given CODE,
11855 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11856 not available. */
11858 static int
11859 get_vec_cmp_insn (enum rtx_code code,
11860 enum machine_mode dest_mode,
11861 enum machine_mode op_mode)
11863 if (!TARGET_ALTIVEC)
11864 return INSN_NOT_AVAILABLE;
11866 switch (code)
11868 case EQ:
11869 if (dest_mode == V16QImode && op_mode == V16QImode)
11870 return UNSPEC_VCMPEQUB;
11871 if (dest_mode == V8HImode && op_mode == V8HImode)
11872 return UNSPEC_VCMPEQUH;
11873 if (dest_mode == V4SImode && op_mode == V4SImode)
11874 return UNSPEC_VCMPEQUW;
11875 if (dest_mode == V4SImode && op_mode == V4SFmode)
11876 return UNSPEC_VCMPEQFP;
11877 break;
11878 case GE:
11879 if (dest_mode == V4SImode && op_mode == V4SFmode)
11880 return UNSPEC_VCMPGEFP;
11881 case GT:
11882 if (dest_mode == V16QImode && op_mode == V16QImode)
11883 return UNSPEC_VCMPGTSB;
11884 if (dest_mode == V8HImode && op_mode == V8HImode)
11885 return UNSPEC_VCMPGTSH;
11886 if (dest_mode == V4SImode && op_mode == V4SImode)
11887 return UNSPEC_VCMPGTSW;
11888 if (dest_mode == V4SImode && op_mode == V4SFmode)
11889 return UNSPEC_VCMPGTFP;
11890 break;
11891 case GTU:
11892 if (dest_mode == V16QImode && op_mode == V16QImode)
11893 return UNSPEC_VCMPGTUB;
11894 if (dest_mode == V8HImode && op_mode == V8HImode)
11895 return UNSPEC_VCMPGTUH;
11896 if (dest_mode == V4SImode && op_mode == V4SImode)
11897 return UNSPEC_VCMPGTUW;
11898 break;
11899 default:
11900 break;
11902 return INSN_NOT_AVAILABLE;
11905 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
11906 DMODE is expected destination mode. This is a recursive function. */
11908 static rtx
11909 rs6000_emit_vector_compare (enum rtx_code rcode,
11910 rtx op0, rtx op1,
11911 enum machine_mode dmode)
11913 int vec_cmp_insn;
11914 rtx mask;
11915 enum machine_mode dest_mode;
11916 enum machine_mode op_mode = GET_MODE (op1);
11918 gcc_assert (TARGET_ALTIVEC);
11919 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
11921 /* Floating point vector compare instructions uses destination V4SImode.
11922 Move destination to appropriate mode later. */
11923 if (dmode == V4SFmode)
11924 dest_mode = V4SImode;
11925 else
11926 dest_mode = dmode;
11928 mask = gen_reg_rtx (dest_mode);
11929 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11931 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
11933 bool swap_operands = false;
11934 bool try_again = false;
11935 switch (rcode)
11937 case LT:
11938 rcode = GT;
11939 swap_operands = true;
11940 try_again = true;
11941 break;
11942 case LTU:
11943 rcode = GTU;
11944 swap_operands = true;
11945 try_again = true;
11946 break;
11947 case NE:
11948 case UNLE:
11949 case UNLT:
11950 case UNGE:
11951 case UNGT:
11952 /* Invert condition and try again.
11953 e.g., A != B becomes ~(A==B). */
11955 enum rtx_code rev_code;
11956 enum insn_code nor_code;
11957 rtx eq_rtx;
11959 rev_code = reverse_condition_maybe_unordered (rcode);
11960 eq_rtx = rs6000_emit_vector_compare (rev_code, op0, op1,
11961 dest_mode);
11963 nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
11964 gcc_assert (nor_code != CODE_FOR_nothing);
11965 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
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;
11975 break;
11976 case GE:
11977 case GEU:
11978 case LE:
11979 case LEU:
11980 /* Try GT/GTU/LT/LTU OR EQ */
11982 rtx c_rtx, eq_rtx;
11983 enum insn_code ior_code;
11984 enum rtx_code new_code;
11986 switch (rcode)
11988 case GE:
11989 new_code = GT;
11990 break;
11992 case GEU:
11993 new_code = GTU;
11994 break;
11996 case LE:
11997 new_code = LT;
11998 break;
12000 case LEU:
12001 new_code = LTU;
12002 break;
12004 default:
12005 gcc_unreachable ();
12008 c_rtx = rs6000_emit_vector_compare (new_code,
12009 op0, op1, dest_mode);
12010 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
12011 dest_mode);
12013 ior_code = ior_optab->handlers[(int)dest_mode].insn_code;
12014 gcc_assert (ior_code != CODE_FOR_nothing);
12015 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
12016 if (dmode != dest_mode)
12018 rtx temp = gen_reg_rtx (dest_mode);
12019 convert_move (temp, mask, 0);
12020 return temp;
12022 return mask;
12024 break;
12025 default:
12026 gcc_unreachable ();
12029 if (try_again)
12031 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
12032 /* You only get two chances. */
12033 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
12036 if (swap_operands)
12038 rtx tmp;
12039 tmp = op0;
12040 op0 = op1;
12041 op1 = tmp;
12045 emit_insn (gen_rtx_SET (VOIDmode, mask,
12046 gen_rtx_UNSPEC (dest_mode,
12047 gen_rtvec (2, op0, op1),
12048 vec_cmp_insn)));
12049 if (dmode != dest_mode)
12051 rtx temp = gen_reg_rtx (dest_mode);
12052 convert_move (temp, mask, 0);
12053 return temp;
12055 return mask;
12058 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
12059 valid insn doesn exist for given mode. */
12061 static int
12062 get_vsel_insn (enum machine_mode mode)
12064 switch (mode)
12066 case V4SImode:
12067 return UNSPEC_VSEL4SI;
12068 break;
12069 case V4SFmode:
12070 return UNSPEC_VSEL4SF;
12071 break;
12072 case V8HImode:
12073 return UNSPEC_VSEL8HI;
12074 break;
12075 case V16QImode:
12076 return UNSPEC_VSEL16QI;
12077 break;
12078 default:
12079 return INSN_NOT_AVAILABLE;
12080 break;
12082 return INSN_NOT_AVAILABLE;
12085 /* Emit vector select insn where DEST is destination using
12086 operands OP1, OP2 and MASK. */
12088 static void
12089 rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
12091 rtx t, temp;
12092 enum machine_mode dest_mode = GET_MODE (dest);
12093 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
12095 temp = gen_reg_rtx (dest_mode);
12097 /* For each vector element, select op1 when mask is 1 otherwise
12098 select op2. */
12099 t = gen_rtx_SET (VOIDmode, temp,
12100 gen_rtx_UNSPEC (dest_mode,
12101 gen_rtvec (3, op2, op1, mask),
12102 vsel_insn_index));
12103 emit_insn (t);
12104 emit_move_insn (dest, temp);
12105 return;
12108 /* Emit vector conditional expression.
12109 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
12110 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
12113 rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
12114 rtx cond, rtx cc_op0, rtx cc_op1)
12116 enum machine_mode dest_mode = GET_MODE (dest);
12117 enum rtx_code rcode = GET_CODE (cond);
12118 rtx mask;
12120 if (!TARGET_ALTIVEC)
12121 return 0;
12123 /* Get the vector mask for the given relational operations. */
12124 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
12126 rs6000_emit_vector_select (dest, op1, op2, mask);
12128 return 1;
12131 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
12132 operands of the last comparison is nonzero/true, FALSE_COND if it
12133 is zero/false. Return 0 if the hardware has no such operation. */
12136 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
12138 enum rtx_code code = GET_CODE (op);
12139 rtx op0 = rs6000_compare_op0;
12140 rtx op1 = rs6000_compare_op1;
12141 REAL_VALUE_TYPE c1;
12142 enum machine_mode compare_mode = GET_MODE (op0);
12143 enum machine_mode result_mode = GET_MODE (dest);
12144 rtx temp;
12145 bool is_against_zero;
12147 /* These modes should always match. */
12148 if (GET_MODE (op1) != compare_mode
12149 /* In the isel case however, we can use a compare immediate, so
12150 op1 may be a small constant. */
12151 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
12152 return 0;
12153 if (GET_MODE (true_cond) != result_mode)
12154 return 0;
12155 if (GET_MODE (false_cond) != result_mode)
12156 return 0;
12158 /* First, work out if the hardware can do this at all, or
12159 if it's too slow.... */
12160 if (! rs6000_compare_fp_p)
12162 if (TARGET_ISEL)
12163 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
12164 return 0;
12166 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
12167 && SCALAR_FLOAT_MODE_P (compare_mode))
12168 return 0;
12170 is_against_zero = op1 == CONST0_RTX (compare_mode);
12172 /* A floating-point subtract might overflow, underflow, or produce
12173 an inexact result, thus changing the floating-point flags, so it
12174 can't be generated if we care about that. It's safe if one side
12175 of the construct is zero, since then no subtract will be
12176 generated. */
12177 if (SCALAR_FLOAT_MODE_P (compare_mode)
12178 && flag_trapping_math && ! is_against_zero)
12179 return 0;
12181 /* Eliminate half of the comparisons by switching operands, this
12182 makes the remaining code simpler. */
12183 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
12184 || code == LTGT || code == LT || code == UNLE)
12186 code = reverse_condition_maybe_unordered (code);
12187 temp = true_cond;
12188 true_cond = false_cond;
12189 false_cond = temp;
12192 /* UNEQ and LTGT take four instructions for a comparison with zero,
12193 it'll probably be faster to use a branch here too. */
12194 if (code == UNEQ && HONOR_NANS (compare_mode))
12195 return 0;
12197 if (GET_CODE (op1) == CONST_DOUBLE)
12198 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
12200 /* We're going to try to implement comparisons by performing
12201 a subtract, then comparing against zero. Unfortunately,
12202 Inf - Inf is NaN which is not zero, and so if we don't
12203 know that the operand is finite and the comparison
12204 would treat EQ different to UNORDERED, we can't do it. */
12205 if (HONOR_INFINITIES (compare_mode)
12206 && code != GT && code != UNGE
12207 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
12208 /* Constructs of the form (a OP b ? a : b) are safe. */
12209 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
12210 || (! rtx_equal_p (op0, true_cond)
12211 && ! rtx_equal_p (op1, true_cond))))
12212 return 0;
12214 /* At this point we know we can use fsel. */
12216 /* Reduce the comparison to a comparison against zero. */
12217 if (! is_against_zero)
12219 temp = gen_reg_rtx (compare_mode);
12220 emit_insn (gen_rtx_SET (VOIDmode, temp,
12221 gen_rtx_MINUS (compare_mode, op0, op1)));
12222 op0 = temp;
12223 op1 = CONST0_RTX (compare_mode);
12226 /* If we don't care about NaNs we can reduce some of the comparisons
12227 down to faster ones. */
12228 if (! HONOR_NANS (compare_mode))
12229 switch (code)
12231 case GT:
12232 code = LE;
12233 temp = true_cond;
12234 true_cond = false_cond;
12235 false_cond = temp;
12236 break;
12237 case UNGE:
12238 code = GE;
12239 break;
12240 case UNEQ:
12241 code = EQ;
12242 break;
12243 default:
12244 break;
12247 /* Now, reduce everything down to a GE. */
12248 switch (code)
12250 case GE:
12251 break;
12253 case LE:
12254 temp = gen_reg_rtx (compare_mode);
12255 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12256 op0 = temp;
12257 break;
12259 case ORDERED:
12260 temp = gen_reg_rtx (compare_mode);
12261 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
12262 op0 = temp;
12263 break;
12265 case EQ:
12266 temp = gen_reg_rtx (compare_mode);
12267 emit_insn (gen_rtx_SET (VOIDmode, temp,
12268 gen_rtx_NEG (compare_mode,
12269 gen_rtx_ABS (compare_mode, op0))));
12270 op0 = temp;
12271 break;
12273 case UNGE:
12274 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
12275 temp = gen_reg_rtx (result_mode);
12276 emit_insn (gen_rtx_SET (VOIDmode, temp,
12277 gen_rtx_IF_THEN_ELSE (result_mode,
12278 gen_rtx_GE (VOIDmode,
12279 op0, op1),
12280 true_cond, false_cond)));
12281 false_cond = true_cond;
12282 true_cond = temp;
12284 temp = gen_reg_rtx (compare_mode);
12285 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12286 op0 = temp;
12287 break;
12289 case GT:
12290 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
12291 temp = gen_reg_rtx (result_mode);
12292 emit_insn (gen_rtx_SET (VOIDmode, temp,
12293 gen_rtx_IF_THEN_ELSE (result_mode,
12294 gen_rtx_GE (VOIDmode,
12295 op0, op1),
12296 true_cond, false_cond)));
12297 true_cond = false_cond;
12298 false_cond = temp;
12300 temp = gen_reg_rtx (compare_mode);
12301 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12302 op0 = temp;
12303 break;
12305 default:
12306 gcc_unreachable ();
12309 emit_insn (gen_rtx_SET (VOIDmode, dest,
12310 gen_rtx_IF_THEN_ELSE (result_mode,
12311 gen_rtx_GE (VOIDmode,
12312 op0, op1),
12313 true_cond, false_cond)));
12314 return 1;
12317 /* Same as above, but for ints (isel). */
12319 static int
12320 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
12322 rtx condition_rtx, cr;
12324 /* All isel implementations thus far are 32-bits. */
12325 if (GET_MODE (rs6000_compare_op0) != SImode)
12326 return 0;
12328 /* We still have to do the compare, because isel doesn't do a
12329 compare, it just looks at the CRx bits set by a previous compare
12330 instruction. */
12331 condition_rtx = rs6000_generate_compare (GET_CODE (op));
12332 cr = XEXP (condition_rtx, 0);
12334 if (GET_MODE (cr) == CCmode)
12335 emit_insn (gen_isel_signed (dest, condition_rtx,
12336 true_cond, false_cond, cr));
12337 else
12338 emit_insn (gen_isel_unsigned (dest, condition_rtx,
12339 true_cond, false_cond, cr));
12341 return 1;
12344 const char *
12345 output_isel (rtx *operands)
12347 enum rtx_code code;
12349 code = GET_CODE (operands[1]);
12350 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
12352 PUT_CODE (operands[1], reverse_condition (code));
12353 return "isel %0,%3,%2,%j1";
12355 else
12356 return "isel %0,%2,%3,%j1";
12359 void
12360 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
12362 enum machine_mode mode = GET_MODE (op0);
12363 enum rtx_code c;
12364 rtx target;
12366 if (code == SMAX || code == SMIN)
12367 c = GE;
12368 else
12369 c = GEU;
12371 if (code == SMAX || code == UMAX)
12372 target = emit_conditional_move (dest, c, op0, op1, mode,
12373 op0, op1, mode, 0);
12374 else
12375 target = emit_conditional_move (dest, c, op0, op1, mode,
12376 op1, op0, mode, 0);
12377 gcc_assert (target);
12378 if (target != dest)
12379 emit_move_insn (dest, target);
12382 /* Emit instructions to perform a load-reserved/store-conditional operation.
12383 The operation performed is an atomic
12384 (set M (CODE:MODE M OP))
12385 If not NULL, BEFORE is atomically set to M before the operation, and
12386 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
12387 If SYNC_P then a memory barrier is emitted before the operation.
12388 Either OP or M may be wrapped in a NOT operation. */
12390 void
12391 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
12392 rtx m, rtx op, rtx before_param, rtx after_param,
12393 bool sync_p)
12395 enum machine_mode used_mode;
12396 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
12397 rtx used_m;
12398 rtvec vec;
12399 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12400 rtx shift = NULL_RTX;
12402 if (sync_p)
12403 emit_insn (gen_memory_barrier ());
12405 if (GET_CODE (m) == NOT)
12406 used_m = XEXP (m, 0);
12407 else
12408 used_m = m;
12410 /* If this is smaller than SImode, we'll have to use SImode with
12411 adjustments. */
12412 if (mode == QImode || mode == HImode)
12414 rtx newop, oldop;
12416 if (MEM_ALIGN (used_m) >= 32)
12418 int ishift = 0;
12419 if (BYTES_BIG_ENDIAN)
12420 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
12422 shift = GEN_INT (ishift);
12424 else
12426 rtx addrSI, aligned_addr;
12427 int shift_mask = mode == QImode ? 0x18 : 0x10;
12429 addrSI = force_reg (SImode, gen_lowpart_common (SImode,
12430 XEXP (used_m, 0)));
12431 shift = gen_reg_rtx (SImode);
12433 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
12434 GEN_INT (shift_mask)));
12435 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
12437 aligned_addr = expand_binop (Pmode, and_optab,
12438 XEXP (used_m, 0),
12439 GEN_INT (-4), NULL_RTX,
12440 1, OPTAB_LIB_WIDEN);
12441 used_m = change_address (used_m, SImode, aligned_addr);
12442 set_mem_align (used_m, 32);
12443 /* It's safe to keep the old alias set of USED_M, because
12444 the operation is atomic and only affects the original
12445 USED_M. */
12446 if (GET_CODE (m) == NOT)
12447 m = gen_rtx_NOT (SImode, used_m);
12448 else
12449 m = used_m;
12452 if (GET_CODE (op) == NOT)
12454 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
12455 oldop = gen_rtx_NOT (SImode, oldop);
12457 else
12458 oldop = lowpart_subreg (SImode, op, mode);
12460 switch (code)
12462 case IOR:
12463 case XOR:
12464 newop = expand_binop (SImode, and_optab,
12465 oldop, GEN_INT (imask), NULL_RTX,
12466 1, OPTAB_LIB_WIDEN);
12467 emit_insn (gen_ashlsi3 (newop, newop, shift));
12468 break;
12470 case AND:
12471 newop = expand_binop (SImode, ior_optab,
12472 oldop, GEN_INT (~imask), NULL_RTX,
12473 1, OPTAB_LIB_WIDEN);
12474 emit_insn (gen_rotlsi3 (newop, newop, shift));
12475 break;
12477 case PLUS:
12478 case MINUS:
12480 rtx mask;
12482 newop = expand_binop (SImode, and_optab,
12483 oldop, GEN_INT (imask), NULL_RTX,
12484 1, OPTAB_LIB_WIDEN);
12485 emit_insn (gen_ashlsi3 (newop, newop, shift));
12487 mask = gen_reg_rtx (SImode);
12488 emit_move_insn (mask, GEN_INT (imask));
12489 emit_insn (gen_ashlsi3 (mask, mask, shift));
12491 if (code == PLUS)
12492 newop = gen_rtx_PLUS (SImode, m, newop);
12493 else
12494 newop = gen_rtx_MINUS (SImode, m, newop);
12495 newop = gen_rtx_AND (SImode, newop, mask);
12496 newop = gen_rtx_IOR (SImode, newop,
12497 gen_rtx_AND (SImode,
12498 gen_rtx_NOT (SImode, mask),
12499 m));
12500 break;
12503 default:
12504 gcc_unreachable ();
12507 if (GET_CODE (m) == NOT)
12509 rtx mask, xorm;
12511 mask = gen_reg_rtx (SImode);
12512 emit_move_insn (mask, GEN_INT (imask));
12513 emit_insn (gen_ashlsi3 (mask, mask, shift));
12515 xorm = gen_rtx_XOR (SImode, used_m, mask);
12516 /* Depending on the value of 'op', the XOR or the operation might
12517 be able to be simplified away. */
12518 newop = simplify_gen_binary (code, SImode, xorm, newop);
12520 op = newop;
12521 used_mode = SImode;
12522 before = gen_reg_rtx (used_mode);
12523 after = gen_reg_rtx (used_mode);
12525 else
12527 used_mode = mode;
12528 before = before_param;
12529 after = after_param;
12531 if (before == NULL_RTX)
12532 before = gen_reg_rtx (used_mode);
12533 if (after == NULL_RTX)
12534 after = gen_reg_rtx (used_mode);
12537 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
12538 && used_mode != mode)
12539 the_op = op; /* Computed above. */
12540 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
12541 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
12542 else
12543 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
12545 set_after = gen_rtx_SET (VOIDmode, after, the_op);
12546 set_before = gen_rtx_SET (VOIDmode, before, used_m);
12547 set_atomic = gen_rtx_SET (VOIDmode, used_m,
12548 gen_rtx_UNSPEC (used_mode,
12549 gen_rtvec (1, the_op),
12550 UNSPEC_SYNC_OP));
12551 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
12553 if ((code == PLUS || code == MINUS) && used_mode != mode)
12554 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
12555 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
12556 else
12557 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
12558 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
12560 /* Shift and mask the return values properly. */
12561 if (used_mode != mode && before_param)
12563 emit_insn (gen_lshrsi3 (before, before, shift));
12564 convert_move (before_param, before, 1);
12567 if (used_mode != mode && after_param)
12569 emit_insn (gen_lshrsi3 (after, after, shift));
12570 convert_move (after_param, after, 1);
12573 /* The previous sequence will end with a branch that's dependent on
12574 the conditional store, so placing an isync will ensure that no
12575 other instructions (especially, no load or store instructions)
12576 can start before the atomic operation completes. */
12577 if (sync_p)
12578 emit_insn (gen_isync ());
12581 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12582 COND is true. Mark the jump as unlikely to be taken. */
12584 static void
12585 emit_unlikely_jump (rtx cond, rtx label)
12587 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
12588 rtx x;
12590 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
12591 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
12592 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
12595 /* A subroutine of the atomic operation splitters. Emit a load-locked
12596 instruction in MODE. */
12598 static void
12599 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
12601 rtx (*fn) (rtx, rtx) = NULL;
12602 if (mode == SImode)
12603 fn = gen_load_locked_si;
12604 else if (mode == DImode)
12605 fn = gen_load_locked_di;
12606 emit_insn (fn (reg, mem));
12609 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12610 instruction in MODE. */
12612 static void
12613 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
12615 rtx (*fn) (rtx, rtx, rtx) = NULL;
12616 if (mode == SImode)
12617 fn = gen_store_conditional_si;
12618 else if (mode == DImode)
12619 fn = gen_store_conditional_di;
12621 /* Emit sync before stwcx. to address PPC405 Erratum. */
12622 if (PPC405_ERRATUM77)
12623 emit_insn (gen_memory_barrier ());
12625 emit_insn (fn (res, mem, val));
12628 /* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
12629 to perform. MEM is the memory on which to operate. VAL is the second
12630 operand of the binary operator. BEFORE and AFTER are optional locations to
12631 return the value of MEM either before of after the operation. SCRATCH is
12632 a scratch register. */
12634 void
12635 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
12636 rtx before, rtx after, rtx scratch)
12638 enum machine_mode mode = GET_MODE (mem);
12639 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12641 emit_insn (gen_memory_barrier ());
12643 label = gen_label_rtx ();
12644 emit_label (label);
12645 label = gen_rtx_LABEL_REF (VOIDmode, label);
12647 if (before == NULL_RTX)
12648 before = scratch;
12649 emit_load_locked (mode, before, mem);
12651 if (code == NOT)
12652 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
12653 else if (code == AND)
12654 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
12655 else
12656 x = gen_rtx_fmt_ee (code, mode, before, val);
12658 if (after != NULL_RTX)
12659 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
12660 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
12662 emit_store_conditional (mode, cond, mem, scratch);
12664 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12665 emit_unlikely_jump (x, label);
12667 emit_insn (gen_isync ());
12670 /* Expand an atomic compare and swap operation. MEM is the memory on which
12671 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12672 value to be stored. SCRATCH is a scratch GPR. */
12674 void
12675 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
12676 rtx scratch)
12678 enum machine_mode mode = GET_MODE (mem);
12679 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12681 emit_insn (gen_memory_barrier ());
12683 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12684 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12685 emit_label (XEXP (label1, 0));
12687 emit_load_locked (mode, retval, mem);
12689 x = gen_rtx_COMPARE (CCmode, retval, oldval);
12690 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12692 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12693 emit_unlikely_jump (x, label2);
12695 emit_move_insn (scratch, newval);
12696 emit_store_conditional (mode, cond, mem, scratch);
12698 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12699 emit_unlikely_jump (x, label1);
12701 emit_insn (gen_isync ());
12702 emit_label (XEXP (label2, 0));
12705 /* Expand an atomic test and set operation. MEM is the memory on which
12706 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12708 void
12709 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
12711 enum machine_mode mode = GET_MODE (mem);
12712 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12714 emit_insn (gen_memory_barrier ());
12716 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12717 emit_label (XEXP (label, 0));
12719 emit_load_locked (mode, retval, mem);
12720 emit_move_insn (scratch, val);
12721 emit_store_conditional (mode, cond, mem, scratch);
12723 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12724 emit_unlikely_jump (x, label);
12726 emit_insn (gen_isync ());
12729 void
12730 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
12732 enum machine_mode mode = GET_MODE (mem);
12733 rtx addrSI, align, wdst, shift, mask;
12734 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
12735 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12737 /* Shift amount for subword relative to aligned word. */
12738 addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0)));
12739 shift = gen_reg_rtx (SImode);
12740 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
12741 GEN_INT (shift_mask)));
12742 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
12744 /* Shift and mask old value into position within word. */
12745 oldval = convert_modes (SImode, mode, oldval, 1);
12746 oldval = expand_binop (SImode, and_optab,
12747 oldval, GEN_INT (imask), NULL_RTX,
12748 1, OPTAB_LIB_WIDEN);
12749 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
12751 /* Shift and mask new value into position within word. */
12752 newval = convert_modes (SImode, mode, newval, 1);
12753 newval = expand_binop (SImode, and_optab,
12754 newval, GEN_INT (imask), NULL_RTX,
12755 1, OPTAB_LIB_WIDEN);
12756 emit_insn (gen_ashlsi3 (newval, newval, shift));
12758 /* Mask for insertion. */
12759 mask = gen_reg_rtx (SImode);
12760 emit_move_insn (mask, GEN_INT (imask));
12761 emit_insn (gen_ashlsi3 (mask, mask, shift));
12763 /* Address of aligned word containing subword. */
12764 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
12765 NULL_RTX, 1, OPTAB_LIB_WIDEN);
12766 mem = change_address (mem, SImode, align);
12767 set_mem_align (mem, 32);
12768 MEM_VOLATILE_P (mem) = 1;
12770 wdst = gen_reg_rtx (SImode);
12771 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
12772 oldval, newval, mem));
12774 emit_move_insn (dst, gen_lowpart (mode, wdst));
12777 void
12778 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
12779 rtx oldval, rtx newval, rtx mem,
12780 rtx scratch)
12782 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12784 emit_insn (gen_memory_barrier ());
12785 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12786 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12787 emit_label (XEXP (label1, 0));
12789 emit_load_locked (SImode, scratch, mem);
12791 /* Mask subword within loaded value for comparison with oldval.
12792 Use UNSPEC_AND to avoid clobber.*/
12793 emit_insn (gen_rtx_SET (SImode, dest,
12794 gen_rtx_UNSPEC (SImode,
12795 gen_rtvec (2, scratch, mask),
12796 UNSPEC_AND)));
12798 x = gen_rtx_COMPARE (CCmode, dest, oldval);
12799 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12801 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12802 emit_unlikely_jump (x, label2);
12804 /* Clear subword within loaded value for insertion of new value. */
12805 emit_insn (gen_rtx_SET (SImode, scratch,
12806 gen_rtx_AND (SImode,
12807 gen_rtx_NOT (SImode, mask), scratch)));
12808 emit_insn (gen_iorsi3 (scratch, scratch, newval));
12809 emit_store_conditional (SImode, cond, mem, scratch);
12811 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12812 emit_unlikely_jump (x, label1);
12814 emit_insn (gen_isync ());
12815 emit_label (XEXP (label2, 0));
12819 /* Emit instructions to move SRC to DST. Called by splitters for
12820 multi-register moves. It will emit at most one instruction for
12821 each register that is accessed; that is, it won't emit li/lis pairs
12822 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12823 register. */
12825 void
12826 rs6000_split_multireg_move (rtx dst, rtx src)
12828 /* The register number of the first register being moved. */
12829 int reg;
12830 /* The mode that is to be moved. */
12831 enum machine_mode mode;
12832 /* The mode that the move is being done in, and its size. */
12833 enum machine_mode reg_mode;
12834 int reg_mode_size;
12835 /* The number of registers that will be moved. */
12836 int nregs;
12838 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
12839 mode = GET_MODE (dst);
12840 nregs = hard_regno_nregs[reg][mode];
12841 if (FP_REGNO_P (reg))
12842 reg_mode = DFmode;
12843 else if (ALTIVEC_REGNO_P (reg))
12844 reg_mode = V16QImode;
12845 else if (TARGET_E500_DOUBLE && mode == TFmode)
12846 reg_mode = DFmode;
12847 else
12848 reg_mode = word_mode;
12849 reg_mode_size = GET_MODE_SIZE (reg_mode);
12851 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
12853 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
12855 /* Move register range backwards, if we might have destructive
12856 overlap. */
12857 int i;
12858 for (i = nregs - 1; i >= 0; i--)
12859 emit_insn (gen_rtx_SET (VOIDmode,
12860 simplify_gen_subreg (reg_mode, dst, mode,
12861 i * reg_mode_size),
12862 simplify_gen_subreg (reg_mode, src, mode,
12863 i * reg_mode_size)));
12865 else
12867 int i;
12868 int j = -1;
12869 bool used_update = false;
12871 if (MEM_P (src) && INT_REGNO_P (reg))
12873 rtx breg;
12875 if (GET_CODE (XEXP (src, 0)) == PRE_INC
12876 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
12878 rtx delta_rtx;
12879 breg = XEXP (XEXP (src, 0), 0);
12880 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
12881 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
12882 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
12883 emit_insn (TARGET_32BIT
12884 ? gen_addsi3 (breg, breg, delta_rtx)
12885 : gen_adddi3 (breg, breg, delta_rtx));
12886 src = replace_equiv_address (src, breg);
12888 else if (! rs6000_offsettable_memref_p (src))
12890 rtx basereg;
12891 basereg = gen_rtx_REG (Pmode, reg);
12892 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
12893 src = replace_equiv_address (src, basereg);
12896 breg = XEXP (src, 0);
12897 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
12898 breg = XEXP (breg, 0);
12900 /* If the base register we are using to address memory is
12901 also a destination reg, then change that register last. */
12902 if (REG_P (breg)
12903 && REGNO (breg) >= REGNO (dst)
12904 && REGNO (breg) < REGNO (dst) + nregs)
12905 j = REGNO (breg) - REGNO (dst);
12908 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
12910 rtx breg;
12912 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
12913 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
12915 rtx delta_rtx;
12916 breg = XEXP (XEXP (dst, 0), 0);
12917 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
12918 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
12919 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
12921 /* We have to update the breg before doing the store.
12922 Use store with update, if available. */
12924 if (TARGET_UPDATE)
12926 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
12927 emit_insn (TARGET_32BIT
12928 ? (TARGET_POWERPC64
12929 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
12930 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
12931 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
12932 used_update = true;
12934 else
12935 emit_insn (TARGET_32BIT
12936 ? gen_addsi3 (breg, breg, delta_rtx)
12937 : gen_adddi3 (breg, breg, delta_rtx));
12938 dst = replace_equiv_address (dst, breg);
12940 else
12941 gcc_assert (rs6000_offsettable_memref_p (dst));
12944 for (i = 0; i < nregs; i++)
12946 /* Calculate index to next subword. */
12947 ++j;
12948 if (j == nregs)
12949 j = 0;
12951 /* If compiler already emitted move of first word by
12952 store with update, no need to do anything. */
12953 if (j == 0 && used_update)
12954 continue;
12956 emit_insn (gen_rtx_SET (VOIDmode,
12957 simplify_gen_subreg (reg_mode, dst, mode,
12958 j * reg_mode_size),
12959 simplify_gen_subreg (reg_mode, src, mode,
12960 j * reg_mode_size)));
12966 /* This page contains routines that are used to determine what the
12967 function prologue and epilogue code will do and write them out. */
12969 /* Return the first fixed-point register that is required to be
12970 saved. 32 if none. */
12973 first_reg_to_save (void)
12975 int first_reg;
12977 /* Find lowest numbered live register. */
12978 for (first_reg = 13; first_reg <= 31; first_reg++)
12979 if (regs_ever_live[first_reg]
12980 && (! call_used_regs[first_reg]
12981 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
12982 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
12983 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
12984 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
12985 break;
12987 #if TARGET_MACHO
12988 if (flag_pic
12989 && current_function_uses_pic_offset_table
12990 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
12991 return RS6000_PIC_OFFSET_TABLE_REGNUM;
12992 #endif
12994 return first_reg;
12997 /* Similar, for FP regs. */
13000 first_fp_reg_to_save (void)
13002 int first_reg;
13004 /* Find lowest numbered live register. */
13005 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
13006 if (regs_ever_live[first_reg])
13007 break;
13009 return first_reg;
13012 /* Similar, for AltiVec regs. */
13014 static int
13015 first_altivec_reg_to_save (void)
13017 int i;
13019 /* Stack frame remains as is unless we are in AltiVec ABI. */
13020 if (! TARGET_ALTIVEC_ABI)
13021 return LAST_ALTIVEC_REGNO + 1;
13023 /* On Darwin, the unwind routines are compiled without
13024 TARGET_ALTIVEC, and use save_world to save/restore the
13025 altivec registers when necessary. */
13026 if (DEFAULT_ABI == ABI_DARWIN && current_function_calls_eh_return
13027 && ! TARGET_ALTIVEC)
13028 return FIRST_ALTIVEC_REGNO + 20;
13030 /* Find lowest numbered live register. */
13031 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
13032 if (regs_ever_live[i])
13033 break;
13035 return i;
13038 /* Return a 32-bit mask of the AltiVec registers we need to set in
13039 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
13040 the 32-bit word is 0. */
13042 static unsigned int
13043 compute_vrsave_mask (void)
13045 unsigned int i, mask = 0;
13047 /* On Darwin, the unwind routines are compiled without
13048 TARGET_ALTIVEC, and use save_world to save/restore the
13049 call-saved altivec registers when necessary. */
13050 if (DEFAULT_ABI == ABI_DARWIN && current_function_calls_eh_return
13051 && ! TARGET_ALTIVEC)
13052 mask |= 0xFFF;
13054 /* First, find out if we use _any_ altivec registers. */
13055 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
13056 if (regs_ever_live[i])
13057 mask |= ALTIVEC_REG_BIT (i);
13059 if (mask == 0)
13060 return mask;
13062 /* Next, remove the argument registers from the set. These must
13063 be in the VRSAVE mask set by the caller, so we don't need to add
13064 them in again. More importantly, the mask we compute here is
13065 used to generate CLOBBERs in the set_vrsave insn, and we do not
13066 wish the argument registers to die. */
13067 for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
13068 mask &= ~ALTIVEC_REG_BIT (i);
13070 /* Similarly, remove the return value from the set. */
13072 bool yes = false;
13073 diddle_return_value (is_altivec_return_reg, &yes);
13074 if (yes)
13075 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
13078 return mask;
13081 /* For a very restricted set of circumstances, we can cut down the
13082 size of prologues/epilogues by calling our own save/restore-the-world
13083 routines. */
13085 static void
13086 compute_save_world_info (rs6000_stack_t *info_ptr)
13088 info_ptr->world_save_p = 1;
13089 info_ptr->world_save_p
13090 = (WORLD_SAVE_P (info_ptr)
13091 && DEFAULT_ABI == ABI_DARWIN
13092 && ! (current_function_calls_setjmp && flag_exceptions)
13093 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
13094 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
13095 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
13096 && info_ptr->cr_save_p);
13098 /* This will not work in conjunction with sibcalls. Make sure there
13099 are none. (This check is expensive, but seldom executed.) */
13100 if (WORLD_SAVE_P (info_ptr))
13102 rtx insn;
13103 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
13104 if ( GET_CODE (insn) == CALL_INSN
13105 && SIBLING_CALL_P (insn))
13107 info_ptr->world_save_p = 0;
13108 break;
13112 if (WORLD_SAVE_P (info_ptr))
13114 /* Even if we're not touching VRsave, make sure there's room on the
13115 stack for it, if it looks like we're calling SAVE_WORLD, which
13116 will attempt to save it. */
13117 info_ptr->vrsave_size = 4;
13119 /* "Save" the VRsave register too if we're saving the world. */
13120 if (info_ptr->vrsave_mask == 0)
13121 info_ptr->vrsave_mask = compute_vrsave_mask ();
13123 /* Because the Darwin register save/restore routines only handle
13124 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
13125 check. */
13126 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
13127 && (info_ptr->first_altivec_reg_save
13128 >= FIRST_SAVED_ALTIVEC_REGNO));
13130 return;
13134 static void
13135 is_altivec_return_reg (rtx reg, void *xyes)
13137 bool *yes = (bool *) xyes;
13138 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
13139 *yes = true;
13143 /* Calculate the stack information for the current function. This is
13144 complicated by having two separate calling sequences, the AIX calling
13145 sequence and the V.4 calling sequence.
13147 AIX (and Darwin/Mac OS X) stack frames look like:
13148 32-bit 64-bit
13149 SP----> +---------------------------------------+
13150 | back chain to caller | 0 0
13151 +---------------------------------------+
13152 | saved CR | 4 8 (8-11)
13153 +---------------------------------------+
13154 | saved LR | 8 16
13155 +---------------------------------------+
13156 | reserved for compilers | 12 24
13157 +---------------------------------------+
13158 | reserved for binders | 16 32
13159 +---------------------------------------+
13160 | saved TOC pointer | 20 40
13161 +---------------------------------------+
13162 | Parameter save area (P) | 24 48
13163 +---------------------------------------+
13164 | Alloca space (A) | 24+P etc.
13165 +---------------------------------------+
13166 | Local variable space (L) | 24+P+A
13167 +---------------------------------------+
13168 | Float/int conversion temporary (X) | 24+P+A+L
13169 +---------------------------------------+
13170 | Save area for AltiVec registers (W) | 24+P+A+L+X
13171 +---------------------------------------+
13172 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
13173 +---------------------------------------+
13174 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
13175 +---------------------------------------+
13176 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
13177 +---------------------------------------+
13178 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
13179 +---------------------------------------+
13180 old SP->| back chain to caller's caller |
13181 +---------------------------------------+
13183 The required alignment for AIX configurations is two words (i.e., 8
13184 or 16 bytes).
13187 V.4 stack frames look like:
13189 SP----> +---------------------------------------+
13190 | back chain to caller | 0
13191 +---------------------------------------+
13192 | caller's saved LR | 4
13193 +---------------------------------------+
13194 | Parameter save area (P) | 8
13195 +---------------------------------------+
13196 | Alloca space (A) | 8+P
13197 +---------------------------------------+
13198 | Varargs save area (V) | 8+P+A
13199 +---------------------------------------+
13200 | Local variable space (L) | 8+P+A+V
13201 +---------------------------------------+
13202 | Float/int conversion temporary (X) | 8+P+A+V+L
13203 +---------------------------------------+
13204 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
13205 +---------------------------------------+
13206 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
13207 +---------------------------------------+
13208 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
13209 +---------------------------------------+
13210 | SPE: area for 64-bit GP registers |
13211 +---------------------------------------+
13212 | SPE alignment padding |
13213 +---------------------------------------+
13214 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
13215 +---------------------------------------+
13216 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
13217 +---------------------------------------+
13218 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
13219 +---------------------------------------+
13220 old SP->| back chain to caller's caller |
13221 +---------------------------------------+
13223 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
13224 given. (But note below and in sysv4.h that we require only 8 and
13225 may round up the size of our stack frame anyways. The historical
13226 reason is early versions of powerpc-linux which didn't properly
13227 align the stack at program startup. A happy side-effect is that
13228 -mno-eabi libraries can be used with -meabi programs.)
13230 The EABI configuration defaults to the V.4 layout. However,
13231 the stack alignment requirements may differ. If -mno-eabi is not
13232 given, the required stack alignment is 8 bytes; if -mno-eabi is
13233 given, the required alignment is 16 bytes. (But see V.4 comment
13234 above.) */
13236 #ifndef ABI_STACK_BOUNDARY
13237 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
13238 #endif
13240 static rs6000_stack_t *
13241 rs6000_stack_info (void)
13243 static rs6000_stack_t info;
13244 rs6000_stack_t *info_ptr = &info;
13245 int reg_size = TARGET_32BIT ? 4 : 8;
13246 int ehrd_size;
13247 int save_align;
13248 HOST_WIDE_INT non_fixed_size;
13250 memset (&info, 0, sizeof (info));
13252 if (TARGET_SPE)
13254 /* Cache value so we don't rescan instruction chain over and over. */
13255 if (cfun->machine->insn_chain_scanned_p == 0)
13256 cfun->machine->insn_chain_scanned_p
13257 = spe_func_has_64bit_regs_p () + 1;
13258 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
13261 /* Select which calling sequence. */
13262 info_ptr->abi = DEFAULT_ABI;
13264 /* Calculate which registers need to be saved & save area size. */
13265 info_ptr->first_gp_reg_save = first_reg_to_save ();
13266 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
13267 even if it currently looks like we won't. */
13268 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
13269 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
13270 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
13271 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
13272 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
13273 else
13274 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
13276 /* For the SPE, we have an additional upper 32-bits on each GPR.
13277 Ideally we should save the entire 64-bits only when the upper
13278 half is used in SIMD instructions. Since we only record
13279 registers live (not the size they are used in), this proves
13280 difficult because we'd have to traverse the instruction chain at
13281 the right time, taking reload into account. This is a real pain,
13282 so we opt to save the GPRs in 64-bits always if but one register
13283 gets used in 64-bits. Otherwise, all the registers in the frame
13284 get saved in 32-bits.
13286 So... since when we save all GPRs (except the SP) in 64-bits, the
13287 traditional GP save area will be empty. */
13288 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13289 info_ptr->gp_size = 0;
13291 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
13292 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
13294 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
13295 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
13296 - info_ptr->first_altivec_reg_save);
13298 /* Does this function call anything? */
13299 info_ptr->calls_p = (! current_function_is_leaf
13300 || cfun->machine->ra_needs_full_frame);
13302 /* Determine if we need to save the link register. */
13303 if ((DEFAULT_ABI == ABI_AIX
13304 && current_function_profile
13305 && !TARGET_PROFILE_KERNEL)
13306 #ifdef TARGET_RELOCATABLE
13307 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
13308 #endif
13309 || (info_ptr->first_fp_reg_save != 64
13310 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
13311 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
13312 || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
13313 || info_ptr->calls_p
13314 || rs6000_ra_ever_killed ())
13316 info_ptr->lr_save_p = 1;
13317 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
13320 /* Determine if we need to save the condition code registers. */
13321 if (regs_ever_live[CR2_REGNO]
13322 || regs_ever_live[CR3_REGNO]
13323 || regs_ever_live[CR4_REGNO])
13325 info_ptr->cr_save_p = 1;
13326 if (DEFAULT_ABI == ABI_V4)
13327 info_ptr->cr_size = reg_size;
13330 /* If the current function calls __builtin_eh_return, then we need
13331 to allocate stack space for registers that will hold data for
13332 the exception handler. */
13333 if (current_function_calls_eh_return)
13335 unsigned int i;
13336 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
13337 continue;
13339 /* SPE saves EH registers in 64-bits. */
13340 ehrd_size = i * (TARGET_SPE_ABI
13341 && info_ptr->spe_64bit_regs_used != 0
13342 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
13344 else
13345 ehrd_size = 0;
13347 /* Determine various sizes. */
13348 info_ptr->reg_size = reg_size;
13349 info_ptr->fixed_size = RS6000_SAVE_AREA;
13350 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
13351 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
13352 TARGET_ALTIVEC ? 16 : 8);
13353 if (FRAME_GROWS_DOWNWARD)
13354 info_ptr->vars_size
13355 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
13356 + info_ptr->parm_size,
13357 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
13358 - (info_ptr->fixed_size + info_ptr->vars_size
13359 + info_ptr->parm_size);
13361 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13362 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
13363 else
13364 info_ptr->spe_gp_size = 0;
13366 if (TARGET_ALTIVEC_ABI)
13367 info_ptr->vrsave_mask = compute_vrsave_mask ();
13368 else
13369 info_ptr->vrsave_mask = 0;
13371 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
13372 info_ptr->vrsave_size = 4;
13373 else
13374 info_ptr->vrsave_size = 0;
13376 compute_save_world_info (info_ptr);
13378 /* Calculate the offsets. */
13379 switch (DEFAULT_ABI)
13381 case ABI_NONE:
13382 default:
13383 gcc_unreachable ();
13385 case ABI_AIX:
13386 case ABI_DARWIN:
13387 info_ptr->fp_save_offset = - info_ptr->fp_size;
13388 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
13390 if (TARGET_ALTIVEC_ABI)
13392 info_ptr->vrsave_save_offset
13393 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
13395 /* Align stack so vector save area is on a quadword boundary. */
13396 if (info_ptr->altivec_size != 0)
13397 info_ptr->altivec_padding_size
13398 = (-info_ptr->vrsave_save_offset) % 16;
13399 else
13400 info_ptr->altivec_padding_size = 0;
13402 info_ptr->altivec_save_offset
13403 = info_ptr->vrsave_save_offset
13404 - info_ptr->altivec_padding_size
13405 - info_ptr->altivec_size;
13407 /* Adjust for AltiVec case. */
13408 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
13410 else
13411 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
13412 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
13413 info_ptr->lr_save_offset = 2*reg_size;
13414 break;
13416 case ABI_V4:
13417 info_ptr->fp_save_offset = - info_ptr->fp_size;
13418 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
13419 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
13421 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13423 /* Align stack so SPE GPR save area is aligned on a
13424 double-word boundary. */
13425 if (info_ptr->spe_gp_size != 0)
13426 info_ptr->spe_padding_size
13427 = 8 - (-info_ptr->cr_save_offset % 8);
13428 else
13429 info_ptr->spe_padding_size = 0;
13431 info_ptr->spe_gp_save_offset
13432 = info_ptr->cr_save_offset
13433 - info_ptr->spe_padding_size
13434 - info_ptr->spe_gp_size;
13436 /* Adjust for SPE case. */
13437 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
13439 else if (TARGET_ALTIVEC_ABI)
13441 info_ptr->vrsave_save_offset
13442 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
13444 /* Align stack so vector save area is on a quadword boundary. */
13445 if (info_ptr->altivec_size != 0)
13446 info_ptr->altivec_padding_size
13447 = 16 - (-info_ptr->vrsave_save_offset % 16);
13448 else
13449 info_ptr->altivec_padding_size = 0;
13451 info_ptr->altivec_save_offset
13452 = info_ptr->vrsave_save_offset
13453 - info_ptr->altivec_padding_size
13454 - info_ptr->altivec_size;
13456 /* Adjust for AltiVec case. */
13457 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
13459 else
13460 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
13461 info_ptr->ehrd_offset -= ehrd_size;
13462 info_ptr->lr_save_offset = reg_size;
13463 break;
13466 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
13467 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
13468 + info_ptr->gp_size
13469 + info_ptr->altivec_size
13470 + info_ptr->altivec_padding_size
13471 + info_ptr->spe_gp_size
13472 + info_ptr->spe_padding_size
13473 + ehrd_size
13474 + info_ptr->cr_size
13475 + info_ptr->vrsave_size,
13476 save_align);
13478 non_fixed_size = (info_ptr->vars_size
13479 + info_ptr->parm_size
13480 + info_ptr->save_size);
13482 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
13483 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
13485 /* Determine if we need to allocate any stack frame:
13487 For AIX we need to push the stack if a frame pointer is needed
13488 (because the stack might be dynamically adjusted), if we are
13489 debugging, if we make calls, or if the sum of fp_save, gp_save,
13490 and local variables are more than the space needed to save all
13491 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
13492 + 18*8 = 288 (GPR13 reserved).
13494 For V.4 we don't have the stack cushion that AIX uses, but assume
13495 that the debugger can handle stackless frames. */
13497 if (info_ptr->calls_p)
13498 info_ptr->push_p = 1;
13500 else if (DEFAULT_ABI == ABI_V4)
13501 info_ptr->push_p = non_fixed_size != 0;
13503 else if (frame_pointer_needed)
13504 info_ptr->push_p = 1;
13506 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
13507 info_ptr->push_p = 1;
13509 else
13510 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
13512 /* Zero offsets if we're not saving those registers. */
13513 if (info_ptr->fp_size == 0)
13514 info_ptr->fp_save_offset = 0;
13516 if (info_ptr->gp_size == 0)
13517 info_ptr->gp_save_offset = 0;
13519 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
13520 info_ptr->altivec_save_offset = 0;
13522 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
13523 info_ptr->vrsave_save_offset = 0;
13525 if (! TARGET_SPE_ABI
13526 || info_ptr->spe_64bit_regs_used == 0
13527 || info_ptr->spe_gp_size == 0)
13528 info_ptr->spe_gp_save_offset = 0;
13530 if (! info_ptr->lr_save_p)
13531 info_ptr->lr_save_offset = 0;
13533 if (! info_ptr->cr_save_p)
13534 info_ptr->cr_save_offset = 0;
13536 return info_ptr;
13539 /* Return true if the current function uses any GPRs in 64-bit SIMD
13540 mode. */
13542 static bool
13543 spe_func_has_64bit_regs_p (void)
13545 rtx insns, insn;
13547 /* Functions that save and restore all the call-saved registers will
13548 need to save/restore the registers in 64-bits. */
13549 if (current_function_calls_eh_return
13550 || current_function_calls_setjmp
13551 || current_function_has_nonlocal_goto)
13552 return true;
13554 insns = get_insns ();
13556 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
13558 if (INSN_P (insn))
13560 rtx i;
13562 /* FIXME: This should be implemented with attributes...
13564 (set_attr "spe64" "true")....then,
13565 if (get_spe64(insn)) return true;
13567 It's the only reliable way to do the stuff below. */
13569 i = PATTERN (insn);
13570 if (GET_CODE (i) == SET)
13572 enum machine_mode mode = GET_MODE (SET_SRC (i));
13574 if (SPE_VECTOR_MODE (mode))
13575 return true;
13576 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
13577 return true;
13582 return false;
13585 static void
13586 debug_stack_info (rs6000_stack_t *info)
13588 const char *abi_string;
13590 if (! info)
13591 info = rs6000_stack_info ();
13593 fprintf (stderr, "\nStack information for function %s:\n",
13594 ((current_function_decl && DECL_NAME (current_function_decl))
13595 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
13596 : "<unknown>"));
13598 switch (info->abi)
13600 default: abi_string = "Unknown"; break;
13601 case ABI_NONE: abi_string = "NONE"; break;
13602 case ABI_AIX: abi_string = "AIX"; break;
13603 case ABI_DARWIN: abi_string = "Darwin"; break;
13604 case ABI_V4: abi_string = "V.4"; break;
13607 fprintf (stderr, "\tABI = %5s\n", abi_string);
13609 if (TARGET_ALTIVEC_ABI)
13610 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
13612 if (TARGET_SPE_ABI)
13613 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
13615 if (info->first_gp_reg_save != 32)
13616 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
13618 if (info->first_fp_reg_save != 64)
13619 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
13621 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
13622 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
13623 info->first_altivec_reg_save);
13625 if (info->lr_save_p)
13626 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
13628 if (info->cr_save_p)
13629 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
13631 if (info->vrsave_mask)
13632 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
13634 if (info->push_p)
13635 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
13637 if (info->calls_p)
13638 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
13640 if (info->gp_save_offset)
13641 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
13643 if (info->fp_save_offset)
13644 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
13646 if (info->altivec_save_offset)
13647 fprintf (stderr, "\taltivec_save_offset = %5d\n",
13648 info->altivec_save_offset);
13650 if (info->spe_gp_save_offset)
13651 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
13652 info->spe_gp_save_offset);
13654 if (info->vrsave_save_offset)
13655 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
13656 info->vrsave_save_offset);
13658 if (info->lr_save_offset)
13659 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
13661 if (info->cr_save_offset)
13662 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
13664 if (info->varargs_save_offset)
13665 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
13667 if (info->total_size)
13668 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13669 info->total_size);
13671 if (info->vars_size)
13672 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13673 info->vars_size);
13675 if (info->parm_size)
13676 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
13678 if (info->fixed_size)
13679 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
13681 if (info->gp_size)
13682 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
13684 if (info->spe_gp_size)
13685 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
13687 if (info->fp_size)
13688 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
13690 if (info->altivec_size)
13691 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
13693 if (info->vrsave_size)
13694 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
13696 if (info->altivec_padding_size)
13697 fprintf (stderr, "\taltivec_padding_size= %5d\n",
13698 info->altivec_padding_size);
13700 if (info->spe_padding_size)
13701 fprintf (stderr, "\tspe_padding_size = %5d\n",
13702 info->spe_padding_size);
13704 if (info->cr_size)
13705 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
13707 if (info->save_size)
13708 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
13710 if (info->reg_size != 4)
13711 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
13713 fprintf (stderr, "\n");
13717 rs6000_return_addr (int count, rtx frame)
13719 /* Currently we don't optimize very well between prolog and body
13720 code and for PIC code the code can be actually quite bad, so
13721 don't try to be too clever here. */
13722 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
13724 cfun->machine->ra_needs_full_frame = 1;
13726 return
13727 gen_rtx_MEM
13728 (Pmode,
13729 memory_address
13730 (Pmode,
13731 plus_constant (copy_to_reg
13732 (gen_rtx_MEM (Pmode,
13733 memory_address (Pmode, frame))),
13734 RETURN_ADDRESS_OFFSET)));
13737 cfun->machine->ra_need_lr = 1;
13738 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
13741 /* Say whether a function is a candidate for sibcall handling or not.
13742 We do not allow indirect calls to be optimized into sibling calls.
13743 Also, we can't do it if there are any vector parameters; there's
13744 nowhere to put the VRsave code so it works; note that functions with
13745 vector parameters are required to have a prototype, so the argument
13746 type info must be available here. (The tail recursion case can work
13747 with vector parameters, but there's no way to distinguish here.) */
13748 static bool
13749 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
13751 tree type;
13752 if (decl)
13754 if (TARGET_ALTIVEC_VRSAVE)
13756 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
13757 type; type = TREE_CHAIN (type))
13759 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
13760 return false;
13763 if (DEFAULT_ABI == ABI_DARWIN
13764 || (*targetm.binds_local_p) (decl))
13766 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
13768 if (!lookup_attribute ("longcall", attr_list)
13769 || lookup_attribute ("shortcall", attr_list))
13770 return true;
13773 return false;
13776 /* NULL if INSN insn is valid within a low-overhead loop.
13777 Otherwise return why doloop cannot be applied.
13778 PowerPC uses the COUNT register for branch on table instructions. */
13780 static const char *
13781 rs6000_invalid_within_doloop (rtx insn)
13783 if (CALL_P (insn))
13784 return "Function call in the loop.";
13786 if (JUMP_P (insn)
13787 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
13788 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
13789 return "Computed branch in the loop.";
13791 return NULL;
13794 static int
13795 rs6000_ra_ever_killed (void)
13797 rtx top;
13798 rtx reg;
13799 rtx insn;
13801 if (current_function_is_thunk)
13802 return 0;
13804 /* regs_ever_live has LR marked as used if any sibcalls are present,
13805 but this should not force saving and restoring in the
13806 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13807 clobbers LR, so that is inappropriate. */
13809 /* Also, the prologue can generate a store into LR that
13810 doesn't really count, like this:
13812 move LR->R0
13813 bcl to set PIC register
13814 move LR->R31
13815 move R0->LR
13817 When we're called from the epilogue, we need to avoid counting
13818 this as a store. */
13820 push_topmost_sequence ();
13821 top = get_insns ();
13822 pop_topmost_sequence ();
13823 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
13825 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
13827 if (INSN_P (insn))
13829 if (CALL_P (insn))
13831 if (!SIBLING_CALL_P (insn))
13832 return 1;
13834 else if (find_regno_note (insn, REG_INC, LINK_REGISTER_REGNUM))
13835 return 1;
13836 else if (set_of (reg, insn) != NULL_RTX
13837 && !prologue_epilogue_contains (insn))
13838 return 1;
13841 return 0;
13844 /* Add a REG_MAYBE_DEAD note to the insn. */
13845 static void
13846 rs6000_maybe_dead (rtx insn)
13848 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
13849 const0_rtx,
13850 REG_NOTES (insn));
13853 /* Emit instructions needed to load the TOC register.
13854 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13855 a constant pool; or for SVR4 -fpic. */
13857 void
13858 rs6000_emit_load_toc_table (int fromprolog)
13860 rtx dest, insn;
13861 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
13863 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
13865 char buf[30];
13866 rtx lab, tmp1, tmp2, got, tempLR;
13868 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13869 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13870 if (flag_pic == 2)
13871 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13872 else
13873 got = rs6000_got_sym ();
13874 tmp1 = tmp2 = dest;
13875 if (!fromprolog)
13877 tmp1 = gen_reg_rtx (Pmode);
13878 tmp2 = gen_reg_rtx (Pmode);
13880 tempLR = (fromprolog
13881 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13882 : gen_reg_rtx (Pmode));
13883 insn = emit_insn (gen_load_toc_v4_PIC_1 (tempLR, lab));
13884 if (fromprolog)
13885 rs6000_maybe_dead (insn);
13886 insn = emit_move_insn (tmp1, tempLR);
13887 if (fromprolog)
13888 rs6000_maybe_dead (insn);
13889 insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
13890 if (fromprolog)
13891 rs6000_maybe_dead (insn);
13892 insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
13893 if (fromprolog)
13894 rs6000_maybe_dead (insn);
13896 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
13898 rtx tempLR = (fromprolog
13899 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13900 : gen_reg_rtx (Pmode));
13902 insn = emit_insn (gen_load_toc_v4_pic_si (tempLR));
13903 if (fromprolog)
13904 rs6000_maybe_dead (insn);
13905 insn = emit_move_insn (dest, tempLR);
13906 if (fromprolog)
13907 rs6000_maybe_dead (insn);
13909 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
13911 char buf[30];
13912 rtx tempLR = (fromprolog
13913 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13914 : gen_reg_rtx (Pmode));
13915 rtx temp0 = (fromprolog
13916 ? gen_rtx_REG (Pmode, 0)
13917 : gen_reg_rtx (Pmode));
13919 if (fromprolog)
13921 rtx symF, symL;
13923 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13924 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13926 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
13927 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13929 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
13930 symF)));
13931 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
13932 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
13933 symL,
13934 symF)));
13936 else
13938 rtx tocsym;
13940 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13941 emit_insn (gen_load_toc_v4_PIC_1b (tempLR, tocsym));
13942 emit_move_insn (dest, tempLR);
13943 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
13945 insn = emit_insn (gen_addsi3 (dest, temp0, dest));
13946 if (fromprolog)
13947 rs6000_maybe_dead (insn);
13949 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
13951 /* This is for AIX code running in non-PIC ELF32. */
13952 char buf[30];
13953 rtx realsym;
13954 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
13955 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13957 insn = emit_insn (gen_elf_high (dest, realsym));
13958 if (fromprolog)
13959 rs6000_maybe_dead (insn);
13960 insn = emit_insn (gen_elf_low (dest, dest, realsym));
13961 if (fromprolog)
13962 rs6000_maybe_dead (insn);
13964 else
13966 gcc_assert (DEFAULT_ABI == ABI_AIX);
13968 if (TARGET_32BIT)
13969 insn = emit_insn (gen_load_toc_aix_si (dest));
13970 else
13971 insn = emit_insn (gen_load_toc_aix_di (dest));
13972 if (fromprolog)
13973 rs6000_maybe_dead (insn);
13977 /* Emit instructions to restore the link register after determining where
13978 its value has been stored. */
13980 void
13981 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
13983 rs6000_stack_t *info = rs6000_stack_info ();
13984 rtx operands[2];
13986 operands[0] = source;
13987 operands[1] = scratch;
13989 if (info->lr_save_p)
13991 rtx frame_rtx = stack_pointer_rtx;
13992 HOST_WIDE_INT sp_offset = 0;
13993 rtx tmp;
13995 if (frame_pointer_needed
13996 || current_function_calls_alloca
13997 || info->total_size > 32767)
13999 tmp = gen_frame_mem (Pmode, frame_rtx);
14000 emit_move_insn (operands[1], tmp);
14001 frame_rtx = operands[1];
14003 else if (info->push_p)
14004 sp_offset = info->total_size;
14006 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
14007 tmp = gen_frame_mem (Pmode, tmp);
14008 emit_move_insn (tmp, operands[0]);
14010 else
14011 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
14014 static GTY(()) int set = -1;
14017 get_TOC_alias_set (void)
14019 if (set == -1)
14020 set = new_alias_set ();
14021 return set;
14024 /* This returns nonzero if the current function uses the TOC. This is
14025 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
14026 is generated by the ABI_V4 load_toc_* patterns. */
14027 #if TARGET_ELF
14028 static int
14029 uses_TOC (void)
14031 rtx insn;
14033 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
14034 if (INSN_P (insn))
14036 rtx pat = PATTERN (insn);
14037 int i;
14039 if (GET_CODE (pat) == PARALLEL)
14040 for (i = 0; i < XVECLEN (pat, 0); i++)
14042 rtx sub = XVECEXP (pat, 0, i);
14043 if (GET_CODE (sub) == USE)
14045 sub = XEXP (sub, 0);
14046 if (GET_CODE (sub) == UNSPEC
14047 && XINT (sub, 1) == UNSPEC_TOC)
14048 return 1;
14052 return 0;
14054 #endif
14057 create_TOC_reference (rtx symbol)
14059 if (no_new_pseudos)
14060 regs_ever_live[TOC_REGISTER] = 1;
14061 return gen_rtx_PLUS (Pmode,
14062 gen_rtx_REG (Pmode, TOC_REGISTER),
14063 gen_rtx_CONST (Pmode,
14064 gen_rtx_MINUS (Pmode, symbol,
14065 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
14068 /* If _Unwind_* has been called from within the same module,
14069 toc register is not guaranteed to be saved to 40(1) on function
14070 entry. Save it there in that case. */
14072 void
14073 rs6000_aix_emit_builtin_unwind_init (void)
14075 rtx mem;
14076 rtx stack_top = gen_reg_rtx (Pmode);
14077 rtx opcode_addr = gen_reg_rtx (Pmode);
14078 rtx opcode = gen_reg_rtx (SImode);
14079 rtx tocompare = gen_reg_rtx (SImode);
14080 rtx no_toc_save_needed = gen_label_rtx ();
14082 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
14083 emit_move_insn (stack_top, mem);
14085 mem = gen_frame_mem (Pmode,
14086 gen_rtx_PLUS (Pmode, stack_top,
14087 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
14088 emit_move_insn (opcode_addr, mem);
14089 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
14090 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
14091 : 0xE8410028, SImode));
14093 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
14094 SImode, NULL_RTX, NULL_RTX,
14095 no_toc_save_needed);
14097 mem = gen_frame_mem (Pmode,
14098 gen_rtx_PLUS (Pmode, stack_top,
14099 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
14100 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
14101 emit_label (no_toc_save_needed);
14104 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
14105 and the change to the stack pointer. */
14107 static void
14108 rs6000_emit_stack_tie (void)
14110 rtx mem = gen_frame_mem (BLKmode,
14111 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
14113 emit_insn (gen_stack_tie (mem));
14116 /* Emit the correct code for allocating stack space, as insns.
14117 If COPY_R12, make sure a copy of the old frame is left in r12.
14118 The generated code may use hard register 0 as a temporary. */
14120 static void
14121 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
14123 rtx insn;
14124 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14125 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
14126 rtx todec = gen_int_mode (-size, Pmode);
14128 if (INTVAL (todec) != -size)
14130 warning (0, "stack frame too large");
14131 emit_insn (gen_trap ());
14132 return;
14135 if (current_function_limit_stack)
14137 if (REG_P (stack_limit_rtx)
14138 && REGNO (stack_limit_rtx) > 1
14139 && REGNO (stack_limit_rtx) <= 31)
14141 emit_insn (TARGET_32BIT
14142 ? gen_addsi3 (tmp_reg,
14143 stack_limit_rtx,
14144 GEN_INT (size))
14145 : gen_adddi3 (tmp_reg,
14146 stack_limit_rtx,
14147 GEN_INT (size)));
14149 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
14150 const0_rtx));
14152 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
14153 && TARGET_32BIT
14154 && DEFAULT_ABI == ABI_V4)
14156 rtx toload = gen_rtx_CONST (VOIDmode,
14157 gen_rtx_PLUS (Pmode,
14158 stack_limit_rtx,
14159 GEN_INT (size)));
14161 emit_insn (gen_elf_high (tmp_reg, toload));
14162 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
14163 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
14164 const0_rtx));
14166 else
14167 warning (0, "stack limit expression is not supported");
14170 if (copy_r12 || ! TARGET_UPDATE)
14171 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
14173 if (TARGET_UPDATE)
14175 if (size > 32767)
14177 /* Need a note here so that try_split doesn't get confused. */
14178 if (get_last_insn () == NULL_RTX)
14179 emit_note (NOTE_INSN_DELETED);
14180 insn = emit_move_insn (tmp_reg, todec);
14181 try_split (PATTERN (insn), insn, 0);
14182 todec = tmp_reg;
14185 insn = emit_insn (TARGET_32BIT
14186 ? gen_movsi_update (stack_reg, stack_reg,
14187 todec, stack_reg)
14188 : gen_movdi_di_update (stack_reg, stack_reg,
14189 todec, stack_reg));
14191 else
14193 insn = emit_insn (TARGET_32BIT
14194 ? gen_addsi3 (stack_reg, stack_reg, todec)
14195 : gen_adddi3 (stack_reg, stack_reg, todec));
14196 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
14197 gen_rtx_REG (Pmode, 12));
14200 RTX_FRAME_RELATED_P (insn) = 1;
14201 REG_NOTES (insn) =
14202 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14203 gen_rtx_SET (VOIDmode, stack_reg,
14204 gen_rtx_PLUS (Pmode, stack_reg,
14205 GEN_INT (-size))),
14206 REG_NOTES (insn));
14209 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
14210 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
14211 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
14212 deduce these equivalences by itself so it wasn't necessary to hold
14213 its hand so much. */
14215 static void
14216 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
14217 rtx reg2, rtx rreg)
14219 rtx real, temp;
14221 /* copy_rtx will not make unique copies of registers, so we need to
14222 ensure we don't have unwanted sharing here. */
14223 if (reg == reg2)
14224 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
14226 if (reg == rreg)
14227 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
14229 real = copy_rtx (PATTERN (insn));
14231 if (reg2 != NULL_RTX)
14232 real = replace_rtx (real, reg2, rreg);
14234 real = replace_rtx (real, reg,
14235 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
14236 STACK_POINTER_REGNUM),
14237 GEN_INT (val)));
14239 /* We expect that 'real' is either a SET or a PARALLEL containing
14240 SETs (and possibly other stuff). In a PARALLEL, all the SETs
14241 are important so they all have to be marked RTX_FRAME_RELATED_P. */
14243 if (GET_CODE (real) == SET)
14245 rtx set = real;
14247 temp = simplify_rtx (SET_SRC (set));
14248 if (temp)
14249 SET_SRC (set) = temp;
14250 temp = simplify_rtx (SET_DEST (set));
14251 if (temp)
14252 SET_DEST (set) = temp;
14253 if (GET_CODE (SET_DEST (set)) == MEM)
14255 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
14256 if (temp)
14257 XEXP (SET_DEST (set), 0) = temp;
14260 else
14262 int i;
14264 gcc_assert (GET_CODE (real) == PARALLEL);
14265 for (i = 0; i < XVECLEN (real, 0); i++)
14266 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
14268 rtx set = XVECEXP (real, 0, i);
14270 temp = simplify_rtx (SET_SRC (set));
14271 if (temp)
14272 SET_SRC (set) = temp;
14273 temp = simplify_rtx (SET_DEST (set));
14274 if (temp)
14275 SET_DEST (set) = temp;
14276 if (GET_CODE (SET_DEST (set)) == MEM)
14278 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
14279 if (temp)
14280 XEXP (SET_DEST (set), 0) = temp;
14282 RTX_FRAME_RELATED_P (set) = 1;
14286 if (TARGET_SPE)
14287 real = spe_synthesize_frame_save (real);
14289 RTX_FRAME_RELATED_P (insn) = 1;
14290 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14291 real,
14292 REG_NOTES (insn));
14295 /* Given an SPE frame note, return a PARALLEL of SETs with the
14296 original note, plus a synthetic register save. */
14298 static rtx
14299 spe_synthesize_frame_save (rtx real)
14301 rtx synth, offset, reg, real2;
14303 if (GET_CODE (real) != SET
14304 || GET_MODE (SET_SRC (real)) != V2SImode)
14305 return real;
14307 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
14308 frame related note. The parallel contains a set of the register
14309 being saved, and another set to a synthetic register (n+1200).
14310 This is so we can differentiate between 64-bit and 32-bit saves.
14311 Words cannot describe this nastiness. */
14313 gcc_assert (GET_CODE (SET_DEST (real)) == MEM
14314 && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS
14315 && GET_CODE (SET_SRC (real)) == REG);
14317 /* Transform:
14318 (set (mem (plus (reg x) (const y)))
14319 (reg z))
14320 into:
14321 (set (mem (plus (reg x) (const y+4)))
14322 (reg z+1200))
14325 real2 = copy_rtx (real);
14326 PUT_MODE (SET_DEST (real2), SImode);
14327 reg = SET_SRC (real2);
14328 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
14329 synth = copy_rtx (real2);
14331 if (BYTES_BIG_ENDIAN)
14333 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
14334 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
14337 reg = SET_SRC (synth);
14339 synth = replace_rtx (synth, reg,
14340 gen_rtx_REG (SImode, REGNO (reg) + 1200));
14342 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
14343 synth = replace_rtx (synth, offset,
14344 GEN_INT (INTVAL (offset)
14345 + (BYTES_BIG_ENDIAN ? 0 : 4)));
14347 RTX_FRAME_RELATED_P (synth) = 1;
14348 RTX_FRAME_RELATED_P (real2) = 1;
14349 if (BYTES_BIG_ENDIAN)
14350 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
14351 else
14352 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
14354 return real;
14357 /* Returns an insn that has a vrsave set operation with the
14358 appropriate CLOBBERs. */
14360 static rtx
14361 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
14363 int nclobs, i;
14364 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
14365 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14367 clobs[0]
14368 = gen_rtx_SET (VOIDmode,
14369 vrsave,
14370 gen_rtx_UNSPEC_VOLATILE (SImode,
14371 gen_rtvec (2, reg, vrsave),
14372 UNSPECV_SET_VRSAVE));
14374 nclobs = 1;
14376 /* We need to clobber the registers in the mask so the scheduler
14377 does not move sets to VRSAVE before sets of AltiVec registers.
14379 However, if the function receives nonlocal gotos, reload will set
14380 all call saved registers live. We will end up with:
14382 (set (reg 999) (mem))
14383 (parallel [ (set (reg vrsave) (unspec blah))
14384 (clobber (reg 999))])
14386 The clobber will cause the store into reg 999 to be dead, and
14387 flow will attempt to delete an epilogue insn. In this case, we
14388 need an unspec use/set of the register. */
14390 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
14391 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14393 if (!epiloguep || call_used_regs [i])
14394 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
14395 gen_rtx_REG (V4SImode, i));
14396 else
14398 rtx reg = gen_rtx_REG (V4SImode, i);
14400 clobs[nclobs++]
14401 = gen_rtx_SET (VOIDmode,
14402 reg,
14403 gen_rtx_UNSPEC (V4SImode,
14404 gen_rtvec (1, reg), 27));
14408 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
14410 for (i = 0; i < nclobs; ++i)
14411 XVECEXP (insn, 0, i) = clobs[i];
14413 return insn;
14416 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
14417 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
14419 static void
14420 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
14421 unsigned int regno, int offset, HOST_WIDE_INT total_size)
14423 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
14424 rtx replacea, replaceb;
14426 int_rtx = GEN_INT (offset);
14428 /* Some cases that need register indexed addressing. */
14429 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
14430 || (TARGET_E500_DOUBLE && mode == DFmode)
14431 || (TARGET_SPE_ABI
14432 && SPE_VECTOR_MODE (mode)
14433 && !SPE_CONST_OFFSET_OK (offset)))
14435 /* Whomever calls us must make sure r11 is available in the
14436 flow path of instructions in the prologue. */
14437 offset_rtx = gen_rtx_REG (Pmode, 11);
14438 emit_move_insn (offset_rtx, int_rtx);
14440 replacea = offset_rtx;
14441 replaceb = int_rtx;
14443 else
14445 offset_rtx = int_rtx;
14446 replacea = NULL_RTX;
14447 replaceb = NULL_RTX;
14450 reg = gen_rtx_REG (mode, regno);
14451 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
14452 mem = gen_frame_mem (mode, addr);
14454 insn = emit_move_insn (mem, reg);
14456 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
14459 /* Emit an offset memory reference suitable for a frame store, while
14460 converting to a valid addressing mode. */
14462 static rtx
14463 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
14465 rtx int_rtx, offset_rtx;
14467 int_rtx = GEN_INT (offset);
14469 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
14470 || (TARGET_E500_DOUBLE && mode == DFmode))
14472 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14473 emit_move_insn (offset_rtx, int_rtx);
14475 else
14476 offset_rtx = int_rtx;
14478 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
14481 /* Look for user-defined global regs. We should not save and restore these,
14482 and cannot use stmw/lmw if there are any in its range. */
14484 static bool
14485 no_global_regs_above (int first_greg)
14487 int i;
14488 for (i = 0; i < 32 - first_greg; i++)
14489 if (global_regs[first_greg + i])
14490 return false;
14491 return true;
14494 #ifndef TARGET_FIX_AND_CONTINUE
14495 #define TARGET_FIX_AND_CONTINUE 0
14496 #endif
14498 /* Emit function prologue as insns. */
14500 void
14501 rs6000_emit_prologue (void)
14503 rs6000_stack_t *info = rs6000_stack_info ();
14504 enum machine_mode reg_mode = Pmode;
14505 int reg_size = TARGET_32BIT ? 4 : 8;
14506 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14507 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
14508 rtx frame_reg_rtx = sp_reg_rtx;
14509 rtx cr_save_rtx = NULL_RTX;
14510 rtx insn;
14511 int saving_FPRs_inline;
14512 int using_store_multiple;
14513 HOST_WIDE_INT sp_offset = 0;
14515 if (TARGET_FIX_AND_CONTINUE)
14517 /* gdb on darwin arranges to forward a function from the old
14518 address by modifying the first 5 instructions of the function
14519 to branch to the overriding function. This is necessary to
14520 permit function pointers that point to the old function to
14521 actually forward to the new function. */
14522 emit_insn (gen_nop ());
14523 emit_insn (gen_nop ());
14524 emit_insn (gen_nop ());
14525 emit_insn (gen_nop ());
14526 emit_insn (gen_nop ());
14529 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14531 reg_mode = V2SImode;
14532 reg_size = 8;
14535 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
14536 && (!TARGET_SPE_ABI
14537 || info->spe_64bit_regs_used == 0)
14538 && info->first_gp_reg_save < 31
14539 && no_global_regs_above (info->first_gp_reg_save));
14540 saving_FPRs_inline = (info->first_fp_reg_save == 64
14541 || FP_SAVE_INLINE (info->first_fp_reg_save)
14542 || current_function_calls_eh_return
14543 || cfun->machine->ra_need_lr);
14545 /* For V.4, update stack before we do any saving and set back pointer. */
14546 if (! WORLD_SAVE_P (info)
14547 && info->push_p
14548 && (DEFAULT_ABI == ABI_V4
14549 || current_function_calls_eh_return))
14551 if (info->total_size < 32767)
14552 sp_offset = info->total_size;
14553 else
14554 frame_reg_rtx = frame_ptr_rtx;
14555 rs6000_emit_allocate_stack (info->total_size,
14556 (frame_reg_rtx != sp_reg_rtx
14557 && (info->cr_save_p
14558 || info->lr_save_p
14559 || info->first_fp_reg_save < 64
14560 || info->first_gp_reg_save < 32
14561 )));
14562 if (frame_reg_rtx != sp_reg_rtx)
14563 rs6000_emit_stack_tie ();
14566 /* Handle world saves specially here. */
14567 if (WORLD_SAVE_P (info))
14569 int i, j, sz;
14570 rtx treg;
14571 rtvec p;
14572 rtx reg0;
14574 /* save_world expects lr in r0. */
14575 reg0 = gen_rtx_REG (Pmode, 0);
14576 if (info->lr_save_p)
14578 insn = emit_move_insn (reg0,
14579 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14580 RTX_FRAME_RELATED_P (insn) = 1;
14583 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
14584 assumptions about the offsets of various bits of the stack
14585 frame. */
14586 gcc_assert (info->gp_save_offset == -220
14587 && info->fp_save_offset == -144
14588 && info->lr_save_offset == 8
14589 && info->cr_save_offset == 4
14590 && info->push_p
14591 && info->lr_save_p
14592 && (!current_function_calls_eh_return
14593 || info->ehrd_offset == -432)
14594 && info->vrsave_save_offset == -224
14595 && info->altivec_save_offset == -416);
14597 treg = gen_rtx_REG (SImode, 11);
14598 emit_move_insn (treg, GEN_INT (-info->total_size));
14600 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
14601 in R11. It also clobbers R12, so beware! */
14603 /* Preserve CR2 for save_world prologues */
14604 sz = 5;
14605 sz += 32 - info->first_gp_reg_save;
14606 sz += 64 - info->first_fp_reg_save;
14607 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
14608 p = rtvec_alloc (sz);
14609 j = 0;
14610 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
14611 gen_rtx_REG (Pmode,
14612 LINK_REGISTER_REGNUM));
14613 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
14614 gen_rtx_SYMBOL_REF (Pmode,
14615 "*save_world"));
14616 /* We do floats first so that the instruction pattern matches
14617 properly. */
14618 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14620 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14621 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14622 GEN_INT (info->fp_save_offset
14623 + sp_offset + 8 * i));
14624 rtx mem = gen_frame_mem (DFmode, addr);
14626 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14628 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
14630 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
14631 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14632 GEN_INT (info->altivec_save_offset
14633 + sp_offset + 16 * i));
14634 rtx mem = gen_frame_mem (V4SImode, addr);
14636 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14638 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14640 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14641 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14642 GEN_INT (info->gp_save_offset
14643 + sp_offset + reg_size * i));
14644 rtx mem = gen_frame_mem (reg_mode, addr);
14646 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14650 /* CR register traditionally saved as CR2. */
14651 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14652 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14653 GEN_INT (info->cr_save_offset
14654 + sp_offset));
14655 rtx mem = gen_frame_mem (reg_mode, addr);
14657 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14659 /* Explain about use of R0. */
14660 if (info->lr_save_p)
14662 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14663 GEN_INT (info->lr_save_offset
14664 + sp_offset));
14665 rtx mem = gen_frame_mem (reg_mode, addr);
14667 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
14669 /* Explain what happens to the stack pointer. */
14671 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
14672 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
14675 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14676 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14677 treg, GEN_INT (-info->total_size));
14678 sp_offset = info->total_size;
14681 /* Save AltiVec registers if needed. */
14682 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14684 int i;
14686 /* There should be a non inline version of this, for when we
14687 are saving lots of vector registers. */
14688 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14689 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14691 rtx areg, savereg, mem;
14692 int offset;
14694 offset = info->altivec_save_offset + sp_offset
14695 + 16 * (i - info->first_altivec_reg_save);
14697 savereg = gen_rtx_REG (V4SImode, i);
14699 areg = gen_rtx_REG (Pmode, 0);
14700 emit_move_insn (areg, GEN_INT (offset));
14702 /* AltiVec addressing mode is [reg+reg]. */
14703 mem = gen_frame_mem (V4SImode,
14704 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
14706 insn = emit_move_insn (mem, savereg);
14708 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14709 areg, GEN_INT (offset));
14713 /* VRSAVE is a bit vector representing which AltiVec registers
14714 are used. The OS uses this to determine which vector
14715 registers to save on a context switch. We need to save
14716 VRSAVE on the stack frame, add whatever AltiVec registers we
14717 used in this function, and do the corresponding magic in the
14718 epilogue. */
14720 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14721 && info->vrsave_mask != 0)
14723 rtx reg, mem, vrsave;
14724 int offset;
14726 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14727 as frame_reg_rtx and r11 as the static chain pointer for
14728 nested functions. */
14729 reg = gen_rtx_REG (SImode, 0);
14730 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14731 if (TARGET_MACHO)
14732 emit_insn (gen_get_vrsave_internal (reg));
14733 else
14734 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
14736 if (!WORLD_SAVE_P (info))
14738 /* Save VRSAVE. */
14739 offset = info->vrsave_save_offset + sp_offset;
14740 mem = gen_frame_mem (SImode,
14741 gen_rtx_PLUS (Pmode, frame_reg_rtx,
14742 GEN_INT (offset)));
14743 insn = emit_move_insn (mem, reg);
14746 /* Include the registers in the mask. */
14747 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
14749 insn = emit_insn (generate_set_vrsave (reg, info, 0));
14752 /* If we use the link register, get it into r0. */
14753 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14755 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14756 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14757 RTX_FRAME_RELATED_P (insn) = 1;
14760 /* If we need to save CR, put it into r12. */
14761 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
14763 rtx set;
14765 cr_save_rtx = gen_rtx_REG (SImode, 12);
14766 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14767 RTX_FRAME_RELATED_P (insn) = 1;
14768 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14769 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14770 But that's OK. All we have to do is specify that _one_ condition
14771 code register is saved in this stack slot. The thrower's epilogue
14772 will then restore all the call-saved registers.
14773 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14774 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
14775 gen_rtx_REG (SImode, CR2_REGNO));
14776 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14777 set,
14778 REG_NOTES (insn));
14781 /* Do any required saving of fpr's. If only one or two to save, do
14782 it ourselves. Otherwise, call function. */
14783 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
14785 int i;
14786 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14787 if ((regs_ever_live[info->first_fp_reg_save+i]
14788 && ! call_used_regs[info->first_fp_reg_save+i]))
14789 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
14790 info->first_fp_reg_save + i,
14791 info->fp_save_offset + sp_offset + 8 * i,
14792 info->total_size);
14794 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
14796 int i;
14797 char rname[30];
14798 const char *alloc_rname;
14799 rtvec p;
14800 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
14802 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
14803 gen_rtx_REG (Pmode,
14804 LINK_REGISTER_REGNUM));
14805 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
14806 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
14807 alloc_rname = ggc_strdup (rname);
14808 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
14809 gen_rtx_SYMBOL_REF (Pmode,
14810 alloc_rname));
14811 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14813 rtx addr, reg, mem;
14814 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14815 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14816 GEN_INT (info->fp_save_offset
14817 + sp_offset + 8*i));
14818 mem = gen_frame_mem (DFmode, addr);
14820 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
14822 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14823 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14824 NULL_RTX, NULL_RTX);
14827 /* Save GPRs. This is done as a PARALLEL if we are using
14828 the store-multiple instructions. */
14829 if (!WORLD_SAVE_P (info) && using_store_multiple)
14831 rtvec p;
14832 int i;
14833 p = rtvec_alloc (32 - info->first_gp_reg_save);
14834 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14836 rtx addr, reg, mem;
14837 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14838 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14839 GEN_INT (info->gp_save_offset
14840 + sp_offset
14841 + reg_size * i));
14842 mem = gen_frame_mem (reg_mode, addr);
14844 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
14846 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14847 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14848 NULL_RTX, NULL_RTX);
14850 else if (!WORLD_SAVE_P (info))
14852 int i;
14853 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14854 if ((regs_ever_live[info->first_gp_reg_save + i]
14855 && (!call_used_regs[info->first_gp_reg_save + i]
14856 || (i + info->first_gp_reg_save
14857 == RS6000_PIC_OFFSET_TABLE_REGNUM
14858 && TARGET_TOC && TARGET_MINIMAL_TOC)))
14859 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14860 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14861 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
14863 rtx addr, reg, mem;
14864 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14866 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14868 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
14869 rtx b;
14871 if (!SPE_CONST_OFFSET_OK (offset))
14873 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14874 emit_move_insn (b, GEN_INT (offset));
14876 else
14877 b = GEN_INT (offset);
14879 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
14880 mem = gen_frame_mem (V2SImode, addr);
14881 insn = emit_move_insn (mem, reg);
14883 if (GET_CODE (b) == CONST_INT)
14884 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14885 NULL_RTX, NULL_RTX);
14886 else
14887 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14888 b, GEN_INT (offset));
14890 else
14892 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14893 GEN_INT (info->gp_save_offset
14894 + sp_offset
14895 + reg_size * i));
14896 mem = gen_frame_mem (reg_mode, addr);
14898 insn = emit_move_insn (mem, reg);
14899 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14900 NULL_RTX, NULL_RTX);
14905 /* ??? There's no need to emit actual instructions here, but it's the
14906 easiest way to get the frame unwind information emitted. */
14907 if (current_function_calls_eh_return)
14909 unsigned int i, regno;
14911 /* In AIX ABI we need to pretend we save r2 here. */
14912 if (TARGET_AIX)
14914 rtx addr, reg, mem;
14916 reg = gen_rtx_REG (reg_mode, 2);
14917 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14918 GEN_INT (sp_offset + 5 * reg_size));
14919 mem = gen_frame_mem (reg_mode, addr);
14921 insn = emit_move_insn (mem, reg);
14922 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14923 NULL_RTX, NULL_RTX);
14924 PATTERN (insn) = gen_blockage ();
14927 for (i = 0; ; ++i)
14929 regno = EH_RETURN_DATA_REGNO (i);
14930 if (regno == INVALID_REGNUM)
14931 break;
14933 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14934 info->ehrd_offset + sp_offset
14935 + reg_size * (int) i,
14936 info->total_size);
14940 /* Save lr if we used it. */
14941 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14943 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14944 GEN_INT (info->lr_save_offset + sp_offset));
14945 rtx reg = gen_rtx_REG (Pmode, 0);
14946 rtx mem = gen_rtx_MEM (Pmode, addr);
14947 /* This should not be of frame_alias_set, because of
14948 __builtin_return_address. */
14950 insn = emit_move_insn (mem, reg);
14951 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14952 NULL_RTX, NULL_RTX);
14955 /* Save CR if we use any that must be preserved. */
14956 if (!WORLD_SAVE_P (info) && info->cr_save_p)
14958 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14959 GEN_INT (info->cr_save_offset + sp_offset));
14960 rtx mem = gen_frame_mem (SImode, addr);
14961 /* See the large comment above about why CR2_REGNO is used. */
14962 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
14964 /* If r12 was used to hold the original sp, copy cr into r0 now
14965 that it's free. */
14966 if (REGNO (frame_reg_rtx) == 12)
14968 rtx set;
14970 cr_save_rtx = gen_rtx_REG (SImode, 0);
14971 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14972 RTX_FRAME_RELATED_P (insn) = 1;
14973 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
14974 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14975 set,
14976 REG_NOTES (insn));
14979 insn = emit_move_insn (mem, cr_save_rtx);
14981 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14982 NULL_RTX, NULL_RTX);
14985 /* Update stack and set back pointer unless this is V.4,
14986 for which it was done previously. */
14987 if (!WORLD_SAVE_P (info) && info->push_p
14988 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
14989 rs6000_emit_allocate_stack (info->total_size, FALSE);
14991 /* Set frame pointer, if needed. */
14992 if (frame_pointer_needed)
14994 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
14995 sp_reg_rtx);
14996 RTX_FRAME_RELATED_P (insn) = 1;
14999 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
15000 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
15001 || (DEFAULT_ABI == ABI_V4
15002 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
15003 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
15005 /* If emit_load_toc_table will use the link register, we need to save
15006 it. We use R12 for this purpose because emit_load_toc_table
15007 can use register 0. This allows us to use a plain 'blr' to return
15008 from the procedure more often. */
15009 int save_LR_around_toc_setup = (TARGET_ELF
15010 && DEFAULT_ABI != ABI_AIX
15011 && flag_pic
15012 && ! info->lr_save_p
15013 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
15014 if (save_LR_around_toc_setup)
15016 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
15018 insn = emit_move_insn (frame_ptr_rtx, lr);
15019 rs6000_maybe_dead (insn);
15020 RTX_FRAME_RELATED_P (insn) = 1;
15022 rs6000_emit_load_toc_table (TRUE);
15024 insn = emit_move_insn (lr, frame_ptr_rtx);
15025 rs6000_maybe_dead (insn);
15026 RTX_FRAME_RELATED_P (insn) = 1;
15028 else
15029 rs6000_emit_load_toc_table (TRUE);
15032 #if TARGET_MACHO
15033 if (DEFAULT_ABI == ABI_DARWIN
15034 && flag_pic && current_function_uses_pic_offset_table)
15036 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
15037 rtx src = machopic_function_base_sym ();
15039 /* Save and restore LR locally around this call (in R0). */
15040 if (!info->lr_save_p)
15041 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode, 0), lr));
15043 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr, src)));
15045 insn = emit_move_insn (gen_rtx_REG (Pmode,
15046 RS6000_PIC_OFFSET_TABLE_REGNUM),
15047 lr);
15048 rs6000_maybe_dead (insn);
15050 if (!info->lr_save_p)
15051 rs6000_maybe_dead (emit_move_insn (lr, gen_rtx_REG (Pmode, 0)));
15053 #endif
15056 /* Write function prologue. */
15058 static void
15059 rs6000_output_function_prologue (FILE *file,
15060 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
15062 rs6000_stack_t *info = rs6000_stack_info ();
15064 if (TARGET_DEBUG_STACK)
15065 debug_stack_info (info);
15067 /* Write .extern for any function we will call to save and restore
15068 fp values. */
15069 if (info->first_fp_reg_save < 64
15070 && !FP_SAVE_INLINE (info->first_fp_reg_save))
15071 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
15072 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
15073 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
15074 RESTORE_FP_SUFFIX);
15076 /* Write .extern for AIX common mode routines, if needed. */
15077 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
15079 fputs ("\t.extern __mulh\n", file);
15080 fputs ("\t.extern __mull\n", file);
15081 fputs ("\t.extern __divss\n", file);
15082 fputs ("\t.extern __divus\n", file);
15083 fputs ("\t.extern __quoss\n", file);
15084 fputs ("\t.extern __quous\n", file);
15085 common_mode_defined = 1;
15088 if (! HAVE_prologue)
15090 start_sequence ();
15092 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
15093 the "toplevel" insn chain. */
15094 emit_note (NOTE_INSN_DELETED);
15095 rs6000_emit_prologue ();
15096 emit_note (NOTE_INSN_DELETED);
15098 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15100 rtx insn;
15101 unsigned addr = 0;
15102 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15104 INSN_ADDRESSES_NEW (insn, addr);
15105 addr += 4;
15109 if (TARGET_DEBUG_STACK)
15110 debug_rtx_list (get_insns (), 100);
15111 final (get_insns (), file, FALSE);
15112 end_sequence ();
15115 rs6000_pic_labelno++;
15118 /* Emit function epilogue as insns.
15120 At present, dwarf2out_frame_debug_expr doesn't understand
15121 register restores, so we don't bother setting RTX_FRAME_RELATED_P
15122 anywhere in the epilogue. Most of the insns below would in any case
15123 need special notes to explain where r11 is in relation to the stack. */
15125 void
15126 rs6000_emit_epilogue (int sibcall)
15128 rs6000_stack_t *info;
15129 int restoring_FPRs_inline;
15130 int using_load_multiple;
15131 int using_mtcr_multiple;
15132 int use_backchain_to_restore_sp;
15133 int sp_offset = 0;
15134 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
15135 rtx frame_reg_rtx = sp_reg_rtx;
15136 enum machine_mode reg_mode = Pmode;
15137 int reg_size = TARGET_32BIT ? 4 : 8;
15138 int i;
15140 info = rs6000_stack_info ();
15142 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15144 reg_mode = V2SImode;
15145 reg_size = 8;
15148 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
15149 && (!TARGET_SPE_ABI
15150 || info->spe_64bit_regs_used == 0)
15151 && info->first_gp_reg_save < 31
15152 && no_global_regs_above (info->first_gp_reg_save));
15153 restoring_FPRs_inline = (sibcall
15154 || current_function_calls_eh_return
15155 || info->first_fp_reg_save == 64
15156 || FP_SAVE_INLINE (info->first_fp_reg_save));
15157 use_backchain_to_restore_sp = (frame_pointer_needed
15158 || current_function_calls_alloca
15159 || info->total_size > 32767);
15160 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
15161 || rs6000_cpu == PROCESSOR_PPC603
15162 || rs6000_cpu == PROCESSOR_PPC750
15163 || optimize_size);
15165 if (WORLD_SAVE_P (info))
15167 int i, j;
15168 char rname[30];
15169 const char *alloc_rname;
15170 rtvec p;
15172 /* eh_rest_world_r10 will return to the location saved in the LR
15173 stack slot (which is not likely to be our caller.)
15174 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
15175 rest_world is similar, except any R10 parameter is ignored.
15176 The exception-handling stuff that was here in 2.95 is no
15177 longer necessary. */
15179 p = rtvec_alloc (9
15181 + 32 - info->first_gp_reg_save
15182 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
15183 + 63 + 1 - info->first_fp_reg_save);
15185 strcpy (rname, ((current_function_calls_eh_return) ?
15186 "*eh_rest_world_r10" : "*rest_world"));
15187 alloc_rname = ggc_strdup (rname);
15189 j = 0;
15190 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
15191 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
15192 gen_rtx_REG (Pmode,
15193 LINK_REGISTER_REGNUM));
15194 RTVEC_ELT (p, j++)
15195 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
15196 /* The instruction pattern requires a clobber here;
15197 it is shared with the restVEC helper. */
15198 RTVEC_ELT (p, j++)
15199 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
15202 /* CR register traditionally saved as CR2. */
15203 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
15204 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15205 GEN_INT (info->cr_save_offset));
15206 rtx mem = gen_frame_mem (reg_mode, addr);
15208 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15211 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15213 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15214 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15215 GEN_INT (info->gp_save_offset
15216 + reg_size * i));
15217 rtx mem = gen_frame_mem (reg_mode, addr);
15219 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15221 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
15223 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
15224 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15225 GEN_INT (info->altivec_save_offset
15226 + 16 * i));
15227 rtx mem = gen_frame_mem (V4SImode, addr);
15229 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15231 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
15233 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15234 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15235 GEN_INT (info->fp_save_offset
15236 + 8 * i));
15237 rtx mem = gen_frame_mem (DFmode, addr);
15239 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15241 RTVEC_ELT (p, j++)
15242 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
15243 RTVEC_ELT (p, j++)
15244 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
15245 RTVEC_ELT (p, j++)
15246 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
15247 RTVEC_ELT (p, j++)
15248 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
15249 RTVEC_ELT (p, j++)
15250 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
15251 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15253 return;
15256 /* If we have a frame pointer, a call to alloca, or a large stack
15257 frame, restore the old stack pointer using the backchain. Otherwise,
15258 we know what size to update it with. */
15259 if (use_backchain_to_restore_sp)
15261 /* Under V.4, don't reset the stack pointer until after we're done
15262 loading the saved registers. */
15263 if (DEFAULT_ABI == ABI_V4)
15264 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
15266 emit_move_insn (frame_reg_rtx,
15267 gen_rtx_MEM (Pmode, sp_reg_rtx));
15269 else if (info->push_p)
15271 if (DEFAULT_ABI == ABI_V4
15272 || current_function_calls_eh_return)
15273 sp_offset = info->total_size;
15274 else
15276 emit_insn (TARGET_32BIT
15277 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15278 GEN_INT (info->total_size))
15279 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15280 GEN_INT (info->total_size)));
15284 /* Restore AltiVec registers if needed. */
15285 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
15287 int i;
15289 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
15290 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
15292 rtx addr, areg, mem;
15294 areg = gen_rtx_REG (Pmode, 0);
15295 emit_move_insn
15296 (areg, GEN_INT (info->altivec_save_offset
15297 + sp_offset
15298 + 16 * (i - info->first_altivec_reg_save)));
15300 /* AltiVec addressing mode is [reg+reg]. */
15301 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
15302 mem = gen_frame_mem (V4SImode, addr);
15304 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
15308 /* Restore VRSAVE if needed. */
15309 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
15310 && info->vrsave_mask != 0)
15312 rtx addr, mem, reg;
15314 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15315 GEN_INT (info->vrsave_save_offset + sp_offset));
15316 mem = gen_frame_mem (SImode, addr);
15317 reg = gen_rtx_REG (SImode, 12);
15318 emit_move_insn (reg, mem);
15320 emit_insn (generate_set_vrsave (reg, info, 1));
15323 /* Get the old lr if we saved it. */
15324 if (info->lr_save_p)
15326 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
15327 info->lr_save_offset + sp_offset);
15329 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
15332 /* Get the old cr if we saved it. */
15333 if (info->cr_save_p)
15335 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15336 GEN_INT (info->cr_save_offset + sp_offset));
15337 rtx mem = gen_frame_mem (SImode, addr);
15339 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
15342 /* Set LR here to try to overlap restores below. */
15343 if (info->lr_save_p)
15344 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
15345 gen_rtx_REG (Pmode, 0));
15347 /* Load exception handler data registers, if needed. */
15348 if (current_function_calls_eh_return)
15350 unsigned int i, regno;
15352 if (TARGET_AIX)
15354 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15355 GEN_INT (sp_offset + 5 * reg_size));
15356 rtx mem = gen_frame_mem (reg_mode, addr);
15358 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
15361 for (i = 0; ; ++i)
15363 rtx mem;
15365 regno = EH_RETURN_DATA_REGNO (i);
15366 if (regno == INVALID_REGNUM)
15367 break;
15369 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
15370 info->ehrd_offset + sp_offset
15371 + reg_size * (int) i);
15373 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
15377 /* Restore GPRs. This is done as a PARALLEL if we are using
15378 the load-multiple instructions. */
15379 if (using_load_multiple)
15381 rtvec p;
15382 p = rtvec_alloc (32 - info->first_gp_reg_save);
15383 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15385 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15386 GEN_INT (info->gp_save_offset
15387 + sp_offset
15388 + reg_size * i));
15389 rtx mem = gen_frame_mem (reg_mode, addr);
15391 RTVEC_ELT (p, i) =
15392 gen_rtx_SET (VOIDmode,
15393 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
15394 mem);
15396 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15398 else
15399 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15400 if ((regs_ever_live[info->first_gp_reg_save + i]
15401 && (!call_used_regs[info->first_gp_reg_save + i]
15402 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
15403 && TARGET_TOC && TARGET_MINIMAL_TOC)))
15404 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
15405 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
15406 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
15408 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15409 GEN_INT (info->gp_save_offset
15410 + sp_offset
15411 + reg_size * i));
15412 rtx mem = gen_frame_mem (reg_mode, addr);
15414 /* Restore 64-bit quantities for SPE. */
15415 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15417 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
15418 rtx b;
15420 if (!SPE_CONST_OFFSET_OK (offset))
15422 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
15423 emit_move_insn (b, GEN_INT (offset));
15425 else
15426 b = GEN_INT (offset);
15428 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
15429 mem = gen_frame_mem (V2SImode, addr);
15432 emit_move_insn (gen_rtx_REG (reg_mode,
15433 info->first_gp_reg_save + i), mem);
15436 /* Restore fpr's if we need to do it without calling a function. */
15437 if (restoring_FPRs_inline)
15438 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15439 if ((regs_ever_live[info->first_fp_reg_save+i]
15440 && ! call_used_regs[info->first_fp_reg_save+i]))
15442 rtx addr, mem;
15443 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15444 GEN_INT (info->fp_save_offset
15445 + sp_offset
15446 + 8 * i));
15447 mem = gen_frame_mem (DFmode, addr);
15449 emit_move_insn (gen_rtx_REG (DFmode,
15450 info->first_fp_reg_save + i),
15451 mem);
15454 /* If we saved cr, restore it here. Just those that were used. */
15455 if (info->cr_save_p)
15457 rtx r12_rtx = gen_rtx_REG (SImode, 12);
15458 int count = 0;
15460 if (using_mtcr_multiple)
15462 for (i = 0; i < 8; i++)
15463 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15464 count++;
15465 gcc_assert (count);
15468 if (using_mtcr_multiple && count > 1)
15470 rtvec p;
15471 int ndx;
15473 p = rtvec_alloc (count);
15475 ndx = 0;
15476 for (i = 0; i < 8; i++)
15477 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15479 rtvec r = rtvec_alloc (2);
15480 RTVEC_ELT (r, 0) = r12_rtx;
15481 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
15482 RTVEC_ELT (p, ndx) =
15483 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
15484 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
15485 ndx++;
15487 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15488 gcc_assert (ndx == count);
15490 else
15491 for (i = 0; i < 8; i++)
15492 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15494 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
15495 CR0_REGNO+i),
15496 r12_rtx));
15500 /* If this is V.4, unwind the stack pointer after all of the loads
15501 have been done. */
15502 if (frame_reg_rtx != sp_reg_rtx)
15504 /* This blockage is needed so that sched doesn't decide to move
15505 the sp change before the register restores. */
15506 rs6000_emit_stack_tie ();
15507 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
15509 else if (sp_offset != 0)
15510 emit_insn (TARGET_32BIT
15511 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15512 GEN_INT (sp_offset))
15513 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15514 GEN_INT (sp_offset)));
15516 if (current_function_calls_eh_return)
15518 rtx sa = EH_RETURN_STACKADJ_RTX;
15519 emit_insn (TARGET_32BIT
15520 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
15521 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
15524 if (!sibcall)
15526 rtvec p;
15527 if (! restoring_FPRs_inline)
15528 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
15529 else
15530 p = rtvec_alloc (2);
15532 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
15533 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
15534 gen_rtx_REG (Pmode,
15535 LINK_REGISTER_REGNUM));
15537 /* If we have to restore more than two FP registers, branch to the
15538 restore function. It will return to our caller. */
15539 if (! restoring_FPRs_inline)
15541 int i;
15542 char rname[30];
15543 const char *alloc_rname;
15545 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
15546 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
15547 alloc_rname = ggc_strdup (rname);
15548 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
15549 gen_rtx_SYMBOL_REF (Pmode,
15550 alloc_rname));
15552 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15554 rtx addr, mem;
15555 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
15556 GEN_INT (info->fp_save_offset + 8*i));
15557 mem = gen_frame_mem (DFmode, addr);
15559 RTVEC_ELT (p, i+3) =
15560 gen_rtx_SET (VOIDmode,
15561 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
15562 mem);
15566 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15570 /* Write function epilogue. */
15572 static void
15573 rs6000_output_function_epilogue (FILE *file,
15574 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
15576 if (! HAVE_epilogue)
15578 rtx insn = get_last_insn ();
15579 /* If the last insn was a BARRIER, we don't have to write anything except
15580 the trace table. */
15581 if (GET_CODE (insn) == NOTE)
15582 insn = prev_nonnote_insn (insn);
15583 if (insn == 0 || GET_CODE (insn) != BARRIER)
15585 /* This is slightly ugly, but at least we don't have two
15586 copies of the epilogue-emitting code. */
15587 start_sequence ();
15589 /* A NOTE_INSN_DELETED is supposed to be at the start
15590 and end of the "toplevel" insn chain. */
15591 emit_note (NOTE_INSN_DELETED);
15592 rs6000_emit_epilogue (FALSE);
15593 emit_note (NOTE_INSN_DELETED);
15595 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15597 rtx insn;
15598 unsigned addr = 0;
15599 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15601 INSN_ADDRESSES_NEW (insn, addr);
15602 addr += 4;
15606 if (TARGET_DEBUG_STACK)
15607 debug_rtx_list (get_insns (), 100);
15608 final (get_insns (), file, FALSE);
15609 end_sequence ();
15613 #if TARGET_MACHO
15614 macho_branch_islands ();
15615 /* Mach-O doesn't support labels at the end of objects, so if
15616 it looks like we might want one, insert a NOP. */
15618 rtx insn = get_last_insn ();
15619 while (insn
15620 && NOTE_P (insn)
15621 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL)
15622 insn = PREV_INSN (insn);
15623 if (insn
15624 && (LABEL_P (insn)
15625 || (NOTE_P (insn)
15626 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
15627 fputs ("\tnop\n", file);
15629 #endif
15631 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15632 on its format.
15634 We don't output a traceback table if -finhibit-size-directive was
15635 used. The documentation for -finhibit-size-directive reads
15636 ``don't output a @code{.size} assembler directive, or anything
15637 else that would cause trouble if the function is split in the
15638 middle, and the two halves are placed at locations far apart in
15639 memory.'' The traceback table has this property, since it
15640 includes the offset from the start of the function to the
15641 traceback table itself.
15643 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15644 different traceback table. */
15645 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
15646 && rs6000_traceback != traceback_none && !current_function_is_thunk)
15648 const char *fname = NULL;
15649 const char *language_string = lang_hooks.name;
15650 int fixed_parms = 0, float_parms = 0, parm_info = 0;
15651 int i;
15652 int optional_tbtab;
15653 rs6000_stack_t *info = rs6000_stack_info ();
15655 if (rs6000_traceback == traceback_full)
15656 optional_tbtab = 1;
15657 else if (rs6000_traceback == traceback_part)
15658 optional_tbtab = 0;
15659 else
15660 optional_tbtab = !optimize_size && !TARGET_ELF;
15662 if (optional_tbtab)
15664 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
15665 while (*fname == '.') /* V.4 encodes . in the name */
15666 fname++;
15668 /* Need label immediately before tbtab, so we can compute
15669 its offset from the function start. */
15670 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15671 ASM_OUTPUT_LABEL (file, fname);
15674 /* The .tbtab pseudo-op can only be used for the first eight
15675 expressions, since it can't handle the possibly variable
15676 length fields that follow. However, if you omit the optional
15677 fields, the assembler outputs zeros for all optional fields
15678 anyways, giving each variable length field is minimum length
15679 (as defined in sys/debug.h). Thus we can not use the .tbtab
15680 pseudo-op at all. */
15682 /* An all-zero word flags the start of the tbtab, for debuggers
15683 that have to find it by searching forward from the entry
15684 point or from the current pc. */
15685 fputs ("\t.long 0\n", file);
15687 /* Tbtab format type. Use format type 0. */
15688 fputs ("\t.byte 0,", file);
15690 /* Language type. Unfortunately, there does not seem to be any
15691 official way to discover the language being compiled, so we
15692 use language_string.
15693 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15694 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
15695 a number, so for now use 9. */
15696 if (! strcmp (language_string, "GNU C"))
15697 i = 0;
15698 else if (! strcmp (language_string, "GNU F77")
15699 || ! strcmp (language_string, "GNU F95"))
15700 i = 1;
15701 else if (! strcmp (language_string, "GNU Pascal"))
15702 i = 2;
15703 else if (! strcmp (language_string, "GNU Ada"))
15704 i = 3;
15705 else if (! strcmp (language_string, "GNU C++")
15706 || ! strcmp (language_string, "GNU Objective-C++"))
15707 i = 9;
15708 else if (! strcmp (language_string, "GNU Java"))
15709 i = 13;
15710 else if (! strcmp (language_string, "GNU Objective-C"))
15711 i = 14;
15712 else
15713 gcc_unreachable ();
15714 fprintf (file, "%d,", i);
15716 /* 8 single bit fields: global linkage (not set for C extern linkage,
15717 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15718 from start of procedure stored in tbtab, internal function, function
15719 has controlled storage, function has no toc, function uses fp,
15720 function logs/aborts fp operations. */
15721 /* Assume that fp operations are used if any fp reg must be saved. */
15722 fprintf (file, "%d,",
15723 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
15725 /* 6 bitfields: function is interrupt handler, name present in
15726 proc table, function calls alloca, on condition directives
15727 (controls stack walks, 3 bits), saves condition reg, saves
15728 link reg. */
15729 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15730 set up as a frame pointer, even when there is no alloca call. */
15731 fprintf (file, "%d,",
15732 ((optional_tbtab << 6)
15733 | ((optional_tbtab & frame_pointer_needed) << 5)
15734 | (info->cr_save_p << 1)
15735 | (info->lr_save_p)));
15737 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15738 (6 bits). */
15739 fprintf (file, "%d,",
15740 (info->push_p << 7) | (64 - info->first_fp_reg_save));
15742 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15743 fprintf (file, "%d,", (32 - first_reg_to_save ()));
15745 if (optional_tbtab)
15747 /* Compute the parameter info from the function decl argument
15748 list. */
15749 tree decl;
15750 int next_parm_info_bit = 31;
15752 for (decl = DECL_ARGUMENTS (current_function_decl);
15753 decl; decl = TREE_CHAIN (decl))
15755 rtx parameter = DECL_INCOMING_RTL (decl);
15756 enum machine_mode mode = GET_MODE (parameter);
15758 if (GET_CODE (parameter) == REG)
15760 if (SCALAR_FLOAT_MODE_P (mode))
15762 int bits;
15764 float_parms++;
15766 switch (mode)
15768 case SFmode:
15769 bits = 0x2;
15770 break;
15772 case DFmode:
15773 case TFmode:
15774 bits = 0x3;
15775 break;
15777 default:
15778 gcc_unreachable ();
15781 /* If only one bit will fit, don't or in this entry. */
15782 if (next_parm_info_bit > 0)
15783 parm_info |= (bits << (next_parm_info_bit - 1));
15784 next_parm_info_bit -= 2;
15786 else
15788 fixed_parms += ((GET_MODE_SIZE (mode)
15789 + (UNITS_PER_WORD - 1))
15790 / UNITS_PER_WORD);
15791 next_parm_info_bit -= 1;
15797 /* Number of fixed point parameters. */
15798 /* This is actually the number of words of fixed point parameters; thus
15799 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15800 fprintf (file, "%d,", fixed_parms);
15802 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15803 all on stack. */
15804 /* This is actually the number of fp registers that hold parameters;
15805 and thus the maximum value is 13. */
15806 /* Set parameters on stack bit if parameters are not in their original
15807 registers, regardless of whether they are on the stack? Xlc
15808 seems to set the bit when not optimizing. */
15809 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
15811 if (! optional_tbtab)
15812 return;
15814 /* Optional fields follow. Some are variable length. */
15816 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15817 11 double float. */
15818 /* There is an entry for each parameter in a register, in the order that
15819 they occur in the parameter list. Any intervening arguments on the
15820 stack are ignored. If the list overflows a long (max possible length
15821 34 bits) then completely leave off all elements that don't fit. */
15822 /* Only emit this long if there was at least one parameter. */
15823 if (fixed_parms || float_parms)
15824 fprintf (file, "\t.long %d\n", parm_info);
15826 /* Offset from start of code to tb table. */
15827 fputs ("\t.long ", file);
15828 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15829 if (TARGET_AIX)
15830 RS6000_OUTPUT_BASENAME (file, fname);
15831 else
15832 assemble_name (file, fname);
15833 putc ('-', file);
15834 rs6000_output_function_entry (file, fname);
15835 putc ('\n', file);
15837 /* Interrupt handler mask. */
15838 /* Omit this long, since we never set the interrupt handler bit
15839 above. */
15841 /* Number of CTL (controlled storage) anchors. */
15842 /* Omit this long, since the has_ctl bit is never set above. */
15844 /* Displacement into stack of each CTL anchor. */
15845 /* Omit this list of longs, because there are no CTL anchors. */
15847 /* Length of function name. */
15848 if (*fname == '*')
15849 ++fname;
15850 fprintf (file, "\t.short %d\n", (int) strlen (fname));
15852 /* Function name. */
15853 assemble_string (fname, strlen (fname));
15855 /* Register for alloca automatic storage; this is always reg 31.
15856 Only emit this if the alloca bit was set above. */
15857 if (frame_pointer_needed)
15858 fputs ("\t.byte 31\n", file);
15860 fputs ("\t.align 2\n", file);
15864 /* A C compound statement that outputs the assembler code for a thunk
15865 function, used to implement C++ virtual function calls with
15866 multiple inheritance. The thunk acts as a wrapper around a virtual
15867 function, adjusting the implicit object parameter before handing
15868 control off to the real function.
15870 First, emit code to add the integer DELTA to the location that
15871 contains the incoming first argument. Assume that this argument
15872 contains a pointer, and is the one used to pass the `this' pointer
15873 in C++. This is the incoming argument *before* the function
15874 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15875 values of all other incoming arguments.
15877 After the addition, emit code to jump to FUNCTION, which is a
15878 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15879 not touch the return address. Hence returning from FUNCTION will
15880 return to whoever called the current `thunk'.
15882 The effect must be as if FUNCTION had been called directly with the
15883 adjusted first argument. This macro is responsible for emitting
15884 all of the code for a thunk function; output_function_prologue()
15885 and output_function_epilogue() are not invoked.
15887 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15888 been extracted from it.) It might possibly be useful on some
15889 targets, but probably not.
15891 If you do not define this macro, the target-independent code in the
15892 C++ frontend will generate a less efficient heavyweight thunk that
15893 calls FUNCTION instead of jumping to it. The generic approach does
15894 not support varargs. */
15896 static void
15897 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
15898 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
15899 tree function)
15901 rtx this, insn, funexp;
15903 reload_completed = 1;
15904 epilogue_completed = 1;
15905 no_new_pseudos = 1;
15906 reset_block_changes ();
15908 /* Mark the end of the (empty) prologue. */
15909 emit_note (NOTE_INSN_PROLOGUE_END);
15911 /* Find the "this" pointer. If the function returns a structure,
15912 the structure return pointer is in r3. */
15913 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
15914 this = gen_rtx_REG (Pmode, 4);
15915 else
15916 this = gen_rtx_REG (Pmode, 3);
15918 /* Apply the constant offset, if required. */
15919 if (delta)
15921 rtx delta_rtx = GEN_INT (delta);
15922 emit_insn (TARGET_32BIT
15923 ? gen_addsi3 (this, this, delta_rtx)
15924 : gen_adddi3 (this, this, delta_rtx));
15927 /* Apply the offset from the vtable, if required. */
15928 if (vcall_offset)
15930 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
15931 rtx tmp = gen_rtx_REG (Pmode, 12);
15933 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
15934 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
15936 emit_insn (TARGET_32BIT
15937 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
15938 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
15939 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
15941 else
15943 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
15945 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
15947 emit_insn (TARGET_32BIT
15948 ? gen_addsi3 (this, this, tmp)
15949 : gen_adddi3 (this, this, tmp));
15952 /* Generate a tail call to the target function. */
15953 if (!TREE_USED (function))
15955 assemble_external (function);
15956 TREE_USED (function) = 1;
15958 funexp = XEXP (DECL_RTL (function), 0);
15959 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
15961 #if TARGET_MACHO
15962 if (MACHOPIC_INDIRECT)
15963 funexp = machopic_indirect_call_target (funexp);
15964 #endif
15966 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
15967 generate sibcall RTL explicitly. */
15968 insn = emit_call_insn (
15969 gen_rtx_PARALLEL (VOIDmode,
15970 gen_rtvec (4,
15971 gen_rtx_CALL (VOIDmode,
15972 funexp, const0_rtx),
15973 gen_rtx_USE (VOIDmode, const0_rtx),
15974 gen_rtx_USE (VOIDmode,
15975 gen_rtx_REG (SImode,
15976 LINK_REGISTER_REGNUM)),
15977 gen_rtx_RETURN (VOIDmode))));
15978 SIBLING_CALL_P (insn) = 1;
15979 emit_barrier ();
15981 /* Run just enough of rest_of_compilation to get the insns emitted.
15982 There's not really enough bulk here to make other passes such as
15983 instruction scheduling worth while. Note that use_thunk calls
15984 assemble_start_function and assemble_end_function. */
15985 insn = get_insns ();
15986 insn_locators_initialize ();
15987 shorten_branches (insn);
15988 final_start_function (insn, file, 1);
15989 final (insn, file, 1);
15990 final_end_function ();
15992 reload_completed = 0;
15993 epilogue_completed = 0;
15994 no_new_pseudos = 0;
15997 /* A quick summary of the various types of 'constant-pool tables'
15998 under PowerPC:
16000 Target Flags Name One table per
16001 AIX (none) AIX TOC object file
16002 AIX -mfull-toc AIX TOC object file
16003 AIX -mminimal-toc AIX minimal TOC translation unit
16004 SVR4/EABI (none) SVR4 SDATA object file
16005 SVR4/EABI -fpic SVR4 pic object file
16006 SVR4/EABI -fPIC SVR4 PIC translation unit
16007 SVR4/EABI -mrelocatable EABI TOC function
16008 SVR4/EABI -maix AIX TOC object file
16009 SVR4/EABI -maix -mminimal-toc
16010 AIX minimal TOC translation unit
16012 Name Reg. Set by entries contains:
16013 made by addrs? fp? sum?
16015 AIX TOC 2 crt0 as Y option option
16016 AIX minimal TOC 30 prolog gcc Y Y option
16017 SVR4 SDATA 13 crt0 gcc N Y N
16018 SVR4 pic 30 prolog ld Y not yet N
16019 SVR4 PIC 30 prolog gcc Y option option
16020 EABI TOC 30 prolog gcc Y option option
16024 /* Hash functions for the hash table. */
16026 static unsigned
16027 rs6000_hash_constant (rtx k)
16029 enum rtx_code code = GET_CODE (k);
16030 enum machine_mode mode = GET_MODE (k);
16031 unsigned result = (code << 3) ^ mode;
16032 const char *format;
16033 int flen, fidx;
16035 format = GET_RTX_FORMAT (code);
16036 flen = strlen (format);
16037 fidx = 0;
16039 switch (code)
16041 case LABEL_REF:
16042 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
16044 case CONST_DOUBLE:
16045 if (mode != VOIDmode)
16046 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
16047 flen = 2;
16048 break;
16050 case CODE_LABEL:
16051 fidx = 3;
16052 break;
16054 default:
16055 break;
16058 for (; fidx < flen; fidx++)
16059 switch (format[fidx])
16061 case 's':
16063 unsigned i, len;
16064 const char *str = XSTR (k, fidx);
16065 len = strlen (str);
16066 result = result * 613 + len;
16067 for (i = 0; i < len; i++)
16068 result = result * 613 + (unsigned) str[i];
16069 break;
16071 case 'u':
16072 case 'e':
16073 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
16074 break;
16075 case 'i':
16076 case 'n':
16077 result = result * 613 + (unsigned) XINT (k, fidx);
16078 break;
16079 case 'w':
16080 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
16081 result = result * 613 + (unsigned) XWINT (k, fidx);
16082 else
16084 size_t i;
16085 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
16086 result = result * 613 + (unsigned) (XWINT (k, fidx)
16087 >> CHAR_BIT * i);
16089 break;
16090 case '0':
16091 break;
16092 default:
16093 gcc_unreachable ();
16096 return result;
16099 static unsigned
16100 toc_hash_function (const void *hash_entry)
16102 const struct toc_hash_struct *thc =
16103 (const struct toc_hash_struct *) hash_entry;
16104 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
16107 /* Compare H1 and H2 for equivalence. */
16109 static int
16110 toc_hash_eq (const void *h1, const void *h2)
16112 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
16113 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
16115 if (((const struct toc_hash_struct *) h1)->key_mode
16116 != ((const struct toc_hash_struct *) h2)->key_mode)
16117 return 0;
16119 return rtx_equal_p (r1, r2);
16122 /* These are the names given by the C++ front-end to vtables, and
16123 vtable-like objects. Ideally, this logic should not be here;
16124 instead, there should be some programmatic way of inquiring as
16125 to whether or not an object is a vtable. */
16127 #define VTABLE_NAME_P(NAME) \
16128 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
16129 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
16130 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
16131 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
16132 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
16134 void
16135 rs6000_output_symbol_ref (FILE *file, rtx x)
16137 /* Currently C++ toc references to vtables can be emitted before it
16138 is decided whether the vtable is public or private. If this is
16139 the case, then the linker will eventually complain that there is
16140 a reference to an unknown section. Thus, for vtables only,
16141 we emit the TOC reference to reference the symbol and not the
16142 section. */
16143 const char *name = XSTR (x, 0);
16145 if (VTABLE_NAME_P (name))
16147 RS6000_OUTPUT_BASENAME (file, name);
16149 else
16150 assemble_name (file, name);
16153 /* Output a TOC entry. We derive the entry name from what is being
16154 written. */
16156 void
16157 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
16159 char buf[256];
16160 const char *name = buf;
16161 const char *real_name;
16162 rtx base = x;
16163 HOST_WIDE_INT offset = 0;
16165 gcc_assert (!TARGET_NO_TOC);
16167 /* When the linker won't eliminate them, don't output duplicate
16168 TOC entries (this happens on AIX if there is any kind of TOC,
16169 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
16170 CODE_LABELs. */
16171 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
16173 struct toc_hash_struct *h;
16174 void * * found;
16176 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
16177 time because GGC is not initialized at that point. */
16178 if (toc_hash_table == NULL)
16179 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
16180 toc_hash_eq, NULL);
16182 h = ggc_alloc (sizeof (*h));
16183 h->key = x;
16184 h->key_mode = mode;
16185 h->labelno = labelno;
16187 found = htab_find_slot (toc_hash_table, h, 1);
16188 if (*found == NULL)
16189 *found = h;
16190 else /* This is indeed a duplicate.
16191 Set this label equal to that label. */
16193 fputs ("\t.set ", file);
16194 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
16195 fprintf (file, "%d,", labelno);
16196 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
16197 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
16198 found)->labelno));
16199 return;
16203 /* If we're going to put a double constant in the TOC, make sure it's
16204 aligned properly when strict alignment is on. */
16205 if (GET_CODE (x) == CONST_DOUBLE
16206 && STRICT_ALIGNMENT
16207 && GET_MODE_BITSIZE (mode) >= 64
16208 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
16209 ASM_OUTPUT_ALIGN (file, 3);
16212 (*targetm.asm_out.internal_label) (file, "LC", labelno);
16214 /* Handle FP constants specially. Note that if we have a minimal
16215 TOC, things we put here aren't actually in the TOC, so we can allow
16216 FP constants. */
16217 if (GET_CODE (x) == CONST_DOUBLE &&
16218 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
16220 REAL_VALUE_TYPE rv;
16221 long k[4];
16223 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16224 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16225 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
16226 else
16227 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
16229 if (TARGET_64BIT)
16231 if (TARGET_MINIMAL_TOC)
16232 fputs (DOUBLE_INT_ASM_OP, file);
16233 else
16234 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16235 k[0] & 0xffffffff, k[1] & 0xffffffff,
16236 k[2] & 0xffffffff, k[3] & 0xffffffff);
16237 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
16238 k[0] & 0xffffffff, k[1] & 0xffffffff,
16239 k[2] & 0xffffffff, k[3] & 0xffffffff);
16240 return;
16242 else
16244 if (TARGET_MINIMAL_TOC)
16245 fputs ("\t.long ", file);
16246 else
16247 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16248 k[0] & 0xffffffff, k[1] & 0xffffffff,
16249 k[2] & 0xffffffff, k[3] & 0xffffffff);
16250 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
16251 k[0] & 0xffffffff, k[1] & 0xffffffff,
16252 k[2] & 0xffffffff, k[3] & 0xffffffff);
16253 return;
16256 else if (GET_CODE (x) == CONST_DOUBLE &&
16257 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
16259 REAL_VALUE_TYPE rv;
16260 long k[2];
16262 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16264 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16265 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
16266 else
16267 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
16269 if (TARGET_64BIT)
16271 if (TARGET_MINIMAL_TOC)
16272 fputs (DOUBLE_INT_ASM_OP, file);
16273 else
16274 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
16275 k[0] & 0xffffffff, k[1] & 0xffffffff);
16276 fprintf (file, "0x%lx%08lx\n",
16277 k[0] & 0xffffffff, k[1] & 0xffffffff);
16278 return;
16280 else
16282 if (TARGET_MINIMAL_TOC)
16283 fputs ("\t.long ", file);
16284 else
16285 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
16286 k[0] & 0xffffffff, k[1] & 0xffffffff);
16287 fprintf (file, "0x%lx,0x%lx\n",
16288 k[0] & 0xffffffff, k[1] & 0xffffffff);
16289 return;
16292 else if (GET_CODE (x) == CONST_DOUBLE &&
16293 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
16295 REAL_VALUE_TYPE rv;
16296 long l;
16298 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16299 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16300 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
16301 else
16302 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
16304 if (TARGET_64BIT)
16306 if (TARGET_MINIMAL_TOC)
16307 fputs (DOUBLE_INT_ASM_OP, file);
16308 else
16309 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
16310 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
16311 return;
16313 else
16315 if (TARGET_MINIMAL_TOC)
16316 fputs ("\t.long ", file);
16317 else
16318 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
16319 fprintf (file, "0x%lx\n", l & 0xffffffff);
16320 return;
16323 else if (GET_MODE (x) == VOIDmode
16324 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
16326 unsigned HOST_WIDE_INT low;
16327 HOST_WIDE_INT high;
16329 if (GET_CODE (x) == CONST_DOUBLE)
16331 low = CONST_DOUBLE_LOW (x);
16332 high = CONST_DOUBLE_HIGH (x);
16334 else
16335 #if HOST_BITS_PER_WIDE_INT == 32
16337 low = INTVAL (x);
16338 high = (low & 0x80000000) ? ~0 : 0;
16340 #else
16342 low = INTVAL (x) & 0xffffffff;
16343 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
16345 #endif
16347 /* TOC entries are always Pmode-sized, but since this
16348 is a bigendian machine then if we're putting smaller
16349 integer constants in the TOC we have to pad them.
16350 (This is still a win over putting the constants in
16351 a separate constant pool, because then we'd have
16352 to have both a TOC entry _and_ the actual constant.)
16354 For a 32-bit target, CONST_INT values are loaded and shifted
16355 entirely within `low' and can be stored in one TOC entry. */
16357 /* It would be easy to make this work, but it doesn't now. */
16358 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
16360 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
16362 #if HOST_BITS_PER_WIDE_INT == 32
16363 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
16364 POINTER_SIZE, &low, &high, 0);
16365 #else
16366 low |= high << 32;
16367 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
16368 high = (HOST_WIDE_INT) low >> 32;
16369 low &= 0xffffffff;
16370 #endif
16373 if (TARGET_64BIT)
16375 if (TARGET_MINIMAL_TOC)
16376 fputs (DOUBLE_INT_ASM_OP, file);
16377 else
16378 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
16379 (long) high & 0xffffffff, (long) low & 0xffffffff);
16380 fprintf (file, "0x%lx%08lx\n",
16381 (long) high & 0xffffffff, (long) low & 0xffffffff);
16382 return;
16384 else
16386 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
16388 if (TARGET_MINIMAL_TOC)
16389 fputs ("\t.long ", file);
16390 else
16391 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
16392 (long) high & 0xffffffff, (long) low & 0xffffffff);
16393 fprintf (file, "0x%lx,0x%lx\n",
16394 (long) high & 0xffffffff, (long) low & 0xffffffff);
16396 else
16398 if (TARGET_MINIMAL_TOC)
16399 fputs ("\t.long ", file);
16400 else
16401 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
16402 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
16404 return;
16408 if (GET_CODE (x) == CONST)
16410 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
16412 base = XEXP (XEXP (x, 0), 0);
16413 offset = INTVAL (XEXP (XEXP (x, 0), 1));
16416 switch (GET_CODE (base))
16418 case SYMBOL_REF:
16419 name = XSTR (base, 0);
16420 break;
16422 case LABEL_REF:
16423 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
16424 CODE_LABEL_NUMBER (XEXP (base, 0)));
16425 break;
16427 case CODE_LABEL:
16428 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
16429 break;
16431 default:
16432 gcc_unreachable ();
16435 real_name = (*targetm.strip_name_encoding) (name);
16436 if (TARGET_MINIMAL_TOC)
16437 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
16438 else
16440 fprintf (file, "\t.tc %s", real_name);
16442 if (offset < 0)
16443 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
16444 else if (offset)
16445 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
16447 fputs ("[TC],", file);
16450 /* Currently C++ toc references to vtables can be emitted before it
16451 is decided whether the vtable is public or private. If this is
16452 the case, then the linker will eventually complain that there is
16453 a TOC reference to an unknown section. Thus, for vtables only,
16454 we emit the TOC reference to reference the symbol and not the
16455 section. */
16456 if (VTABLE_NAME_P (name))
16458 RS6000_OUTPUT_BASENAME (file, name);
16459 if (offset < 0)
16460 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
16461 else if (offset > 0)
16462 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
16464 else
16465 output_addr_const (file, x);
16466 putc ('\n', file);
16469 /* Output an assembler pseudo-op to write an ASCII string of N characters
16470 starting at P to FILE.
16472 On the RS/6000, we have to do this using the .byte operation and
16473 write out special characters outside the quoted string.
16474 Also, the assembler is broken; very long strings are truncated,
16475 so we must artificially break them up early. */
16477 void
16478 output_ascii (FILE *file, const char *p, int n)
16480 char c;
16481 int i, count_string;
16482 const char *for_string = "\t.byte \"";
16483 const char *for_decimal = "\t.byte ";
16484 const char *to_close = NULL;
16486 count_string = 0;
16487 for (i = 0; i < n; i++)
16489 c = *p++;
16490 if (c >= ' ' && c < 0177)
16492 if (for_string)
16493 fputs (for_string, file);
16494 putc (c, file);
16496 /* Write two quotes to get one. */
16497 if (c == '"')
16499 putc (c, file);
16500 ++count_string;
16503 for_string = NULL;
16504 for_decimal = "\"\n\t.byte ";
16505 to_close = "\"\n";
16506 ++count_string;
16508 if (count_string >= 512)
16510 fputs (to_close, file);
16512 for_string = "\t.byte \"";
16513 for_decimal = "\t.byte ";
16514 to_close = NULL;
16515 count_string = 0;
16518 else
16520 if (for_decimal)
16521 fputs (for_decimal, file);
16522 fprintf (file, "%d", c);
16524 for_string = "\n\t.byte \"";
16525 for_decimal = ", ";
16526 to_close = "\n";
16527 count_string = 0;
16531 /* Now close the string if we have written one. Then end the line. */
16532 if (to_close)
16533 fputs (to_close, file);
16536 /* Generate a unique section name for FILENAME for a section type
16537 represented by SECTION_DESC. Output goes into BUF.
16539 SECTION_DESC can be any string, as long as it is different for each
16540 possible section type.
16542 We name the section in the same manner as xlc. The name begins with an
16543 underscore followed by the filename (after stripping any leading directory
16544 names) with the last period replaced by the string SECTION_DESC. If
16545 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16546 the name. */
16548 void
16549 rs6000_gen_section_name (char **buf, const char *filename,
16550 const char *section_desc)
16552 const char *q, *after_last_slash, *last_period = 0;
16553 char *p;
16554 int len;
16556 after_last_slash = filename;
16557 for (q = filename; *q; q++)
16559 if (*q == '/')
16560 after_last_slash = q + 1;
16561 else if (*q == '.')
16562 last_period = q;
16565 len = strlen (after_last_slash) + strlen (section_desc) + 2;
16566 *buf = (char *) xmalloc (len);
16568 p = *buf;
16569 *p++ = '_';
16571 for (q = after_last_slash; *q; q++)
16573 if (q == last_period)
16575 strcpy (p, section_desc);
16576 p += strlen (section_desc);
16577 break;
16580 else if (ISALNUM (*q))
16581 *p++ = *q;
16584 if (last_period == 0)
16585 strcpy (p, section_desc);
16586 else
16587 *p = '\0';
16590 /* Emit profile function. */
16592 void
16593 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
16595 /* Non-standard profiling for kernels, which just saves LR then calls
16596 _mcount without worrying about arg saves. The idea is to change
16597 the function prologue as little as possible as it isn't easy to
16598 account for arg save/restore code added just for _mcount. */
16599 if (TARGET_PROFILE_KERNEL)
16600 return;
16602 if (DEFAULT_ABI == ABI_AIX)
16604 #ifndef NO_PROFILE_COUNTERS
16605 # define NO_PROFILE_COUNTERS 0
16606 #endif
16607 if (NO_PROFILE_COUNTERS)
16608 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
16609 else
16611 char buf[30];
16612 const char *label_name;
16613 rtx fun;
16615 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16616 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
16617 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
16619 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
16620 fun, Pmode);
16623 else if (DEFAULT_ABI == ABI_DARWIN)
16625 const char *mcount_name = RS6000_MCOUNT;
16626 int caller_addr_regno = LINK_REGISTER_REGNUM;
16628 /* Be conservative and always set this, at least for now. */
16629 current_function_uses_pic_offset_table = 1;
16631 #if TARGET_MACHO
16632 /* For PIC code, set up a stub and collect the caller's address
16633 from r0, which is where the prologue puts it. */
16634 if (MACHOPIC_INDIRECT
16635 && current_function_uses_pic_offset_table)
16636 caller_addr_regno = 0;
16637 #endif
16638 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
16639 0, VOIDmode, 1,
16640 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
16644 /* Write function profiler code. */
16646 void
16647 output_function_profiler (FILE *file, int labelno)
16649 char buf[100];
16651 switch (DEFAULT_ABI)
16653 default:
16654 gcc_unreachable ();
16656 case ABI_V4:
16657 if (!TARGET_32BIT)
16659 warning (0, "no profiling of 64-bit code for this ABI");
16660 return;
16662 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16663 fprintf (file, "\tmflr %s\n", reg_names[0]);
16664 if (NO_PROFILE_COUNTERS)
16666 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16667 reg_names[0], reg_names[1]);
16669 else if (TARGET_SECURE_PLT && flag_pic)
16671 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16672 reg_names[0], reg_names[1]);
16673 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16674 asm_fprintf (file, "\t{cau|addis} %s,%s,",
16675 reg_names[12], reg_names[12]);
16676 assemble_name (file, buf);
16677 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
16678 assemble_name (file, buf);
16679 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
16681 else if (flag_pic == 1)
16683 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
16684 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16685 reg_names[0], reg_names[1]);
16686 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16687 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
16688 assemble_name (file, buf);
16689 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
16691 else if (flag_pic > 1)
16693 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16694 reg_names[0], reg_names[1]);
16695 /* Now, we need to get the address of the label. */
16696 fputs ("\tbcl 20,31,1f\n\t.long ", file);
16697 assemble_name (file, buf);
16698 fputs ("-.\n1:", file);
16699 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
16700 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
16701 reg_names[0], reg_names[11]);
16702 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
16703 reg_names[0], reg_names[0], reg_names[11]);
16705 else
16707 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
16708 assemble_name (file, buf);
16709 fputs ("@ha\n", file);
16710 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16711 reg_names[0], reg_names[1]);
16712 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
16713 assemble_name (file, buf);
16714 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
16717 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16718 fprintf (file, "\tbl %s%s\n",
16719 RS6000_MCOUNT, flag_pic ? "@plt" : "");
16720 break;
16722 case ABI_AIX:
16723 case ABI_DARWIN:
16724 if (!TARGET_PROFILE_KERNEL)
16726 /* Don't do anything, done in output_profile_hook (). */
16728 else
16730 gcc_assert (!TARGET_32BIT);
16732 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
16733 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
16735 if (cfun->static_chain_decl != NULL)
16737 asm_fprintf (file, "\tstd %s,24(%s)\n",
16738 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16739 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16740 asm_fprintf (file, "\tld %s,24(%s)\n",
16741 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16743 else
16744 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16746 break;
16752 /* The following variable value is the last issued insn. */
16754 static rtx last_scheduled_insn;
16756 /* The following variable helps to balance issuing of load and
16757 store instructions */
16759 static int load_store_pendulum;
16761 /* Power4 load update and store update instructions are cracked into a
16762 load or store and an integer insn which are executed in the same cycle.
16763 Branches have their own dispatch slot which does not count against the
16764 GCC issue rate, but it changes the program flow so there are no other
16765 instructions to issue in this cycle. */
16767 static int
16768 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
16769 int verbose ATTRIBUTE_UNUSED,
16770 rtx insn, int more)
16772 last_scheduled_insn = insn;
16773 if (GET_CODE (PATTERN (insn)) == USE
16774 || GET_CODE (PATTERN (insn)) == CLOBBER)
16776 cached_can_issue_more = more;
16777 return cached_can_issue_more;
16780 if (insn_terminates_group_p (insn, current_group))
16782 cached_can_issue_more = 0;
16783 return cached_can_issue_more;
16786 /* If no reservation, but reach here */
16787 if (recog_memoized (insn) < 0)
16788 return more;
16790 if (rs6000_sched_groups)
16792 if (is_microcoded_insn (insn))
16793 cached_can_issue_more = 0;
16794 else if (is_cracked_insn (insn))
16795 cached_can_issue_more = more > 2 ? more - 2 : 0;
16796 else
16797 cached_can_issue_more = more - 1;
16799 return cached_can_issue_more;
16802 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
16803 return 0;
16805 cached_can_issue_more = more - 1;
16806 return cached_can_issue_more;
16809 /* Adjust the cost of a scheduling dependency. Return the new cost of
16810 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16812 static int
16813 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
16815 enum attr_type attr_type;
16817 if (! recog_memoized (insn))
16818 return 0;
16820 switch (REG_NOTE_KIND (link))
16822 case REG_DEP_TRUE:
16824 /* Data dependency; DEP_INSN writes a register that INSN reads
16825 some cycles later. */
16827 /* Separate a load from a narrower, dependent store. */
16828 if (rs6000_sched_groups
16829 && GET_CODE (PATTERN (insn)) == SET
16830 && GET_CODE (PATTERN (dep_insn)) == SET
16831 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
16832 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
16833 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
16834 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
16835 return cost + 14;
16837 attr_type = get_attr_type (insn);
16839 switch (attr_type)
16841 case TYPE_JMPREG:
16842 /* Tell the first scheduling pass about the latency between
16843 a mtctr and bctr (and mtlr and br/blr). The first
16844 scheduling pass will not know about this latency since
16845 the mtctr instruction, which has the latency associated
16846 to it, will be generated by reload. */
16847 return TARGET_POWER ? 5 : 4;
16848 case TYPE_BRANCH:
16849 /* Leave some extra cycles between a compare and its
16850 dependent branch, to inhibit expensive mispredicts. */
16851 if ((rs6000_cpu_attr == CPU_PPC603
16852 || rs6000_cpu_attr == CPU_PPC604
16853 || rs6000_cpu_attr == CPU_PPC604E
16854 || rs6000_cpu_attr == CPU_PPC620
16855 || rs6000_cpu_attr == CPU_PPC630
16856 || rs6000_cpu_attr == CPU_PPC750
16857 || rs6000_cpu_attr == CPU_PPC7400
16858 || rs6000_cpu_attr == CPU_PPC7450
16859 || rs6000_cpu_attr == CPU_POWER4
16860 || rs6000_cpu_attr == CPU_POWER5
16861 || rs6000_cpu_attr == CPU_CELL)
16862 && recog_memoized (dep_insn)
16863 && (INSN_CODE (dep_insn) >= 0))
16865 switch (get_attr_type (dep_insn))
16867 case TYPE_CMP:
16868 case TYPE_COMPARE:
16869 case TYPE_DELAYED_COMPARE:
16870 case TYPE_IMUL_COMPARE:
16871 case TYPE_LMUL_COMPARE:
16872 case TYPE_FPCOMPARE:
16873 case TYPE_CR_LOGICAL:
16874 case TYPE_DELAYED_CR:
16875 return cost + 2;
16876 default:
16877 break;
16879 break;
16881 case TYPE_STORE:
16882 case TYPE_STORE_U:
16883 case TYPE_STORE_UX:
16884 case TYPE_FPSTORE:
16885 case TYPE_FPSTORE_U:
16886 case TYPE_FPSTORE_UX:
16887 if ((rs6000_cpu == PROCESSOR_POWER6)
16888 && recog_memoized (dep_insn)
16889 && (INSN_CODE (dep_insn) >= 0))
16892 if (GET_CODE (PATTERN (insn)) != SET)
16893 /* If this happens, we have to extend this to schedule
16894 optimally. Return default for now. */
16895 return cost;
16897 /* Adjust the cost for the case where the value written
16898 by a fixed point operation is used as the address
16899 gen value on a store. */
16900 switch (get_attr_type (dep_insn))
16902 case TYPE_LOAD:
16903 case TYPE_LOAD_U:
16904 case TYPE_LOAD_UX:
16905 case TYPE_CNTLZ:
16907 if (! store_data_bypass_p (dep_insn, insn))
16908 return 4;
16909 break;
16911 case TYPE_LOAD_EXT:
16912 case TYPE_LOAD_EXT_U:
16913 case TYPE_LOAD_EXT_UX:
16914 case TYPE_VAR_SHIFT_ROTATE:
16915 case TYPE_VAR_DELAYED_COMPARE:
16917 if (! store_data_bypass_p (dep_insn, insn))
16918 return 6;
16919 break;
16921 case TYPE_INTEGER:
16922 case TYPE_COMPARE:
16923 case TYPE_FAST_COMPARE:
16924 case TYPE_EXTS:
16925 case TYPE_SHIFT:
16926 case TYPE_INSERT_WORD:
16927 case TYPE_INSERT_DWORD:
16928 case TYPE_FPLOAD_U:
16929 case TYPE_FPLOAD_UX:
16930 case TYPE_STORE_U:
16931 case TYPE_STORE_UX:
16932 case TYPE_FPSTORE_U:
16933 case TYPE_FPSTORE_UX:
16935 if (! store_data_bypass_p (dep_insn, insn))
16936 return 3;
16937 break;
16939 case TYPE_IMUL:
16940 case TYPE_IMUL2:
16941 case TYPE_IMUL3:
16942 case TYPE_LMUL:
16943 case TYPE_IMUL_COMPARE:
16944 case TYPE_LMUL_COMPARE:
16946 if (! store_data_bypass_p (dep_insn, insn))
16947 return 17;
16948 break;
16950 case TYPE_IDIV:
16952 if (! store_data_bypass_p (dep_insn, insn))
16953 return 45;
16954 break;
16956 case TYPE_LDIV:
16958 if (! store_data_bypass_p (dep_insn, insn))
16959 return 57;
16960 break;
16962 default:
16963 break;
16966 break;
16968 case TYPE_LOAD:
16969 case TYPE_LOAD_U:
16970 case TYPE_LOAD_UX:
16971 case TYPE_LOAD_EXT:
16972 case TYPE_LOAD_EXT_U:
16973 case TYPE_LOAD_EXT_UX:
16974 if ((rs6000_cpu == PROCESSOR_POWER6)
16975 && recog_memoized (dep_insn)
16976 && (INSN_CODE (dep_insn) >= 0))
16979 /* Adjust the cost for the case where the value written
16980 by a fixed point instruction is used within the address
16981 gen portion of a subsequent load(u)(x) */
16982 switch (get_attr_type (dep_insn))
16984 case TYPE_LOAD:
16985 case TYPE_LOAD_U:
16986 case TYPE_LOAD_UX:
16987 case TYPE_CNTLZ:
16989 if (set_to_load_agen (dep_insn, insn))
16990 return 4;
16991 break;
16993 case TYPE_LOAD_EXT:
16994 case TYPE_LOAD_EXT_U:
16995 case TYPE_LOAD_EXT_UX:
16996 case TYPE_VAR_SHIFT_ROTATE:
16997 case TYPE_VAR_DELAYED_COMPARE:
16999 if (set_to_load_agen (dep_insn, insn))
17000 return 6;
17001 break;
17003 case TYPE_INTEGER:
17004 case TYPE_COMPARE:
17005 case TYPE_FAST_COMPARE:
17006 case TYPE_EXTS:
17007 case TYPE_SHIFT:
17008 case TYPE_INSERT_WORD:
17009 case TYPE_INSERT_DWORD:
17010 case TYPE_FPLOAD_U:
17011 case TYPE_FPLOAD_UX:
17012 case TYPE_STORE_U:
17013 case TYPE_STORE_UX:
17014 case TYPE_FPSTORE_U:
17015 case TYPE_FPSTORE_UX:
17017 if (set_to_load_agen (dep_insn, insn))
17018 return 3;
17019 break;
17021 case TYPE_IMUL:
17022 case TYPE_IMUL2:
17023 case TYPE_IMUL3:
17024 case TYPE_LMUL:
17025 case TYPE_IMUL_COMPARE:
17026 case TYPE_LMUL_COMPARE:
17028 if (set_to_load_agen (dep_insn, insn))
17029 return 17;
17030 break;
17032 case TYPE_IDIV:
17034 if (set_to_load_agen (dep_insn, insn))
17035 return 45;
17036 break;
17038 case TYPE_LDIV:
17040 if (set_to_load_agen (dep_insn, insn))
17041 return 57;
17042 break;
17044 default:
17045 break;
17048 break;
17050 case TYPE_FPLOAD:
17051 if ((rs6000_cpu == PROCESSOR_POWER6)
17052 && recog_memoized (dep_insn)
17053 && (INSN_CODE (dep_insn) >= 0)
17054 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
17055 return 2;
17057 default:
17058 break;
17061 /* Fall out to return default cost. */
17063 break;
17065 case REG_DEP_OUTPUT:
17066 /* Output dependency; DEP_INSN writes a register that INSN writes some
17067 cycles later. */
17068 if ((rs6000_cpu == PROCESSOR_POWER6)
17069 && recog_memoized (dep_insn)
17070 && (INSN_CODE (dep_insn) >= 0))
17072 attr_type = get_attr_type (insn);
17074 switch (attr_type)
17076 case TYPE_FP:
17077 if (get_attr_type (dep_insn) == TYPE_FP)
17078 return 1;
17079 break;
17080 case TYPE_FPLOAD:
17081 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
17082 return 2;
17083 break;
17084 default:
17085 break;
17088 case REG_DEP_ANTI:
17089 /* Anti dependency; DEP_INSN reads a register that INSN writes some
17090 cycles later. */
17091 return 0;
17093 default:
17094 gcc_unreachable ();
17097 return cost;
17100 /* The function returns a true if INSN is microcoded.
17101 Return false otherwise. */
17103 static bool
17104 is_microcoded_insn (rtx insn)
17106 if (!insn || !INSN_P (insn)
17107 || GET_CODE (PATTERN (insn)) == USE
17108 || GET_CODE (PATTERN (insn)) == CLOBBER)
17109 return false;
17111 if (rs6000_cpu_attr == CPU_CELL)
17112 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
17114 if (rs6000_sched_groups)
17116 enum attr_type type = get_attr_type (insn);
17117 if (type == TYPE_LOAD_EXT_U
17118 || type == TYPE_LOAD_EXT_UX
17119 || type == TYPE_LOAD_UX
17120 || type == TYPE_STORE_UX
17121 || type == TYPE_MFCR)
17122 return true;
17125 return false;
17128 /* The function returns true if INSN is cracked into 2 instructions
17129 by the processor (and therefore occupies 2 issue slots). */
17131 static bool
17132 is_cracked_insn (rtx insn)
17134 if (!insn || !INSN_P (insn)
17135 || GET_CODE (PATTERN (insn)) == USE
17136 || GET_CODE (PATTERN (insn)) == CLOBBER)
17137 return false;
17139 if (rs6000_sched_groups)
17141 enum attr_type type = get_attr_type (insn);
17142 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
17143 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
17144 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
17145 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
17146 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
17147 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
17148 || type == TYPE_IDIV || type == TYPE_LDIV
17149 || type == TYPE_INSERT_WORD)
17150 return true;
17153 return false;
17156 /* The function returns true if INSN can be issued only from
17157 the branch slot. */
17159 static bool
17160 is_branch_slot_insn (rtx insn)
17162 if (!insn || !INSN_P (insn)
17163 || GET_CODE (PATTERN (insn)) == USE
17164 || GET_CODE (PATTERN (insn)) == CLOBBER)
17165 return false;
17167 if (rs6000_sched_groups)
17169 enum attr_type type = get_attr_type (insn);
17170 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
17171 return true;
17172 return false;
17175 return false;
17178 /* The function returns true if out_inst sets a value that is
17179 used in the address generation computation of in_insn */
17180 static bool
17181 set_to_load_agen (rtx out_insn, rtx in_insn)
17183 rtx out_set, in_set;
17185 /* For performance reasons, only handle the simple case where
17186 both loads are a single_set. */
17187 out_set = single_set (out_insn);
17188 if (out_set)
17190 in_set = single_set (in_insn);
17191 if (in_set)
17192 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
17195 return false;
17198 /* The function returns true if the target storage location of
17199 out_insn is adjacent to the target storage location of in_insn */
17200 /* Return 1 if memory locations are adjacent. */
17202 static bool
17203 adjacent_mem_locations (rtx insn1, rtx insn2)
17206 rtx a = get_store_dest (PATTERN (insn1));
17207 rtx b = get_store_dest (PATTERN (insn2));
17209 if ((GET_CODE (XEXP (a, 0)) == REG
17210 || (GET_CODE (XEXP (a, 0)) == PLUS
17211 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
17212 && (GET_CODE (XEXP (b, 0)) == REG
17213 || (GET_CODE (XEXP (b, 0)) == PLUS
17214 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
17216 HOST_WIDE_INT val0 = 0, val1 = 0;
17217 rtx reg0, reg1;
17218 int val_diff;
17220 if (GET_CODE (XEXP (a, 0)) == PLUS)
17222 reg0 = XEXP (XEXP (a, 0), 0);
17223 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
17225 else
17226 reg0 = XEXP (a, 0);
17228 if (GET_CODE (XEXP (b, 0)) == PLUS)
17230 reg1 = XEXP (XEXP (b, 0), 0);
17231 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
17233 else
17234 reg1 = XEXP (b, 0);
17236 val_diff = val1 - val0;
17238 return ((REGNO (reg0) == REGNO (reg1))
17239 && (val_diff == INTVAL (MEM_SIZE (a))
17240 || val_diff == -INTVAL (MEM_SIZE (b))));
17243 return false;
17246 /* A C statement (sans semicolon) to update the integer scheduling
17247 priority INSN_PRIORITY (INSN). Increase the priority to execute the
17248 INSN earlier, reduce the priority to execute INSN later. Do not
17249 define this macro if you do not need to adjust the scheduling
17250 priorities of insns. */
17252 static int
17253 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
17255 /* On machines (like the 750) which have asymmetric integer units,
17256 where one integer unit can do multiply and divides and the other
17257 can't, reduce the priority of multiply/divide so it is scheduled
17258 before other integer operations. */
17260 #if 0
17261 if (! INSN_P (insn))
17262 return priority;
17264 if (GET_CODE (PATTERN (insn)) == USE)
17265 return priority;
17267 switch (rs6000_cpu_attr) {
17268 case CPU_PPC750:
17269 switch (get_attr_type (insn))
17271 default:
17272 break;
17274 case TYPE_IMUL:
17275 case TYPE_IDIV:
17276 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
17277 priority, priority);
17278 if (priority >= 0 && priority < 0x01000000)
17279 priority >>= 3;
17280 break;
17283 #endif
17285 if (insn_must_be_first_in_group (insn)
17286 && reload_completed
17287 && current_sched_info->sched_max_insns_priority
17288 && rs6000_sched_restricted_insns_priority)
17291 /* Prioritize insns that can be dispatched only in the first
17292 dispatch slot. */
17293 if (rs6000_sched_restricted_insns_priority == 1)
17294 /* Attach highest priority to insn. This means that in
17295 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
17296 precede 'priority' (critical path) considerations. */
17297 return current_sched_info->sched_max_insns_priority;
17298 else if (rs6000_sched_restricted_insns_priority == 2)
17299 /* Increase priority of insn by a minimal amount. This means that in
17300 haifa-sched.c:ready_sort(), only 'priority' (critical path)
17301 considerations precede dispatch-slot restriction considerations. */
17302 return (priority + 1);
17305 if (rs6000_cpu == PROCESSOR_POWER6
17306 && ((load_store_pendulum == -2 && is_load_insn (insn))
17307 || (load_store_pendulum == 2 && is_store_insn (insn))))
17308 /* Attach highest priority to insn if the scheduler has just issued two
17309 stores and this instruction is a load, or two loads and this instruction
17310 is a store. Power6 wants loads and stores scheduled alternately
17311 when possible */
17312 return current_sched_info->sched_max_insns_priority;
17314 return priority;
17317 /* Return true if the instruction is nonpipelined on the Cell. */
17318 static bool
17319 is_nonpipeline_insn (rtx insn)
17321 enum attr_type type;
17322 if (!insn || !INSN_P (insn)
17323 || GET_CODE (PATTERN (insn)) == USE
17324 || GET_CODE (PATTERN (insn)) == CLOBBER)
17325 return false;
17327 type = get_attr_type (insn);
17328 if (type == TYPE_IMUL
17329 || type == TYPE_IMUL2
17330 || type == TYPE_IMUL3
17331 || type == TYPE_LMUL
17332 || type == TYPE_IDIV
17333 || type == TYPE_LDIV
17334 || type == TYPE_SDIV
17335 || type == TYPE_DDIV
17336 || type == TYPE_SSQRT
17337 || type == TYPE_DSQRT
17338 || type == TYPE_MFCR
17339 || type == TYPE_MFCRF
17340 || type == TYPE_MFJMPR)
17342 return true;
17344 return false;
17348 /* Return how many instructions the machine can issue per cycle. */
17350 static int
17351 rs6000_issue_rate (void)
17353 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
17354 if (!reload_completed)
17355 return 1;
17357 switch (rs6000_cpu_attr) {
17358 case CPU_RIOS1: /* ? */
17359 case CPU_RS64A:
17360 case CPU_PPC601: /* ? */
17361 case CPU_PPC7450:
17362 return 3;
17363 case CPU_PPC440:
17364 case CPU_PPC603:
17365 case CPU_PPC750:
17366 case CPU_PPC7400:
17367 case CPU_PPC8540:
17368 case CPU_CELL:
17369 return 2;
17370 case CPU_RIOS2:
17371 case CPU_PPC604:
17372 case CPU_PPC604E:
17373 case CPU_PPC620:
17374 case CPU_PPC630:
17375 return 4;
17376 case CPU_POWER4:
17377 case CPU_POWER5:
17378 case CPU_POWER6:
17379 return 5;
17380 default:
17381 return 1;
17385 /* Return how many instructions to look ahead for better insn
17386 scheduling. */
17388 static int
17389 rs6000_use_sched_lookahead (void)
17391 if (rs6000_cpu_attr == CPU_PPC8540)
17392 return 4;
17393 if (rs6000_cpu_attr == CPU_CELL)
17394 return (reload_completed ? 8 : 0);
17395 return 0;
17398 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
17399 static int
17400 rs6000_use_sched_lookahead_guard (rtx insn)
17402 if (rs6000_cpu_attr != CPU_CELL)
17403 return 1;
17405 if (insn == NULL_RTX || !INSN_P (insn))
17406 abort ();
17408 if (!reload_completed
17409 || is_nonpipeline_insn (insn)
17410 || is_microcoded_insn (insn))
17411 return 0;
17413 return 1;
17416 /* Determine is PAT refers to memory. */
17418 static bool
17419 is_mem_ref (rtx pat)
17421 const char * fmt;
17422 int i, j;
17423 bool ret = false;
17425 if (GET_CODE (pat) == MEM)
17426 return true;
17428 /* Recursively process the pattern. */
17429 fmt = GET_RTX_FORMAT (GET_CODE (pat));
17431 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
17433 if (fmt[i] == 'e')
17434 ret |= is_mem_ref (XEXP (pat, i));
17435 else if (fmt[i] == 'E')
17436 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
17437 ret |= is_mem_ref (XVECEXP (pat, i, j));
17440 return ret;
17443 /* Determine if PAT is a PATTERN of a load insn. */
17445 static bool
17446 is_load_insn1 (rtx pat)
17448 if (!pat || pat == NULL_RTX)
17449 return false;
17451 if (GET_CODE (pat) == SET)
17452 return is_mem_ref (SET_SRC (pat));
17454 if (GET_CODE (pat) == PARALLEL)
17456 int i;
17458 for (i = 0; i < XVECLEN (pat, 0); i++)
17459 if (is_load_insn1 (XVECEXP (pat, 0, i)))
17460 return true;
17463 return false;
17466 /* Determine if INSN loads from memory. */
17468 static bool
17469 is_load_insn (rtx insn)
17471 if (!insn || !INSN_P (insn))
17472 return false;
17474 if (GET_CODE (insn) == CALL_INSN)
17475 return false;
17477 return is_load_insn1 (PATTERN (insn));
17480 /* Determine if PAT is a PATTERN of a store insn. */
17482 static bool
17483 is_store_insn1 (rtx pat)
17485 if (!pat || pat == NULL_RTX)
17486 return false;
17488 if (GET_CODE (pat) == SET)
17489 return is_mem_ref (SET_DEST (pat));
17491 if (GET_CODE (pat) == PARALLEL)
17493 int i;
17495 for (i = 0; i < XVECLEN (pat, 0); i++)
17496 if (is_store_insn1 (XVECEXP (pat, 0, i)))
17497 return true;
17500 return false;
17503 /* Determine if INSN stores to memory. */
17505 static bool
17506 is_store_insn (rtx insn)
17508 if (!insn || !INSN_P (insn))
17509 return false;
17511 return is_store_insn1 (PATTERN (insn));
17514 /* Return the dest of a store insn. */
17516 static rtx
17517 get_store_dest (rtx pat)
17519 gcc_assert (is_store_insn1 (pat));
17521 if (GET_CODE (pat) == SET)
17522 return SET_DEST (pat);
17523 else if (GET_CODE (pat) == PARALLEL)
17525 int i;
17527 for (i = 0; i < XVECLEN (pat, 0); i++)
17529 rtx inner_pat = XVECEXP (pat, 0, i);
17530 if (GET_CODE (inner_pat) == SET
17531 && is_mem_ref (SET_DEST (inner_pat)))
17532 return inner_pat;
17535 /* We shouldn't get here, because we should have either a simple
17536 store insn or a store with update which are covered above. */
17537 gcc_unreachable();
17540 /* Returns whether the dependence between INSN and NEXT is considered
17541 costly by the given target. */
17543 static bool
17544 rs6000_is_costly_dependence (rtx insn, rtx next, rtx link, int cost,
17545 int distance)
17547 /* If the flag is not enabled - no dependence is considered costly;
17548 allow all dependent insns in the same group.
17549 This is the most aggressive option. */
17550 if (rs6000_sched_costly_dep == no_dep_costly)
17551 return false;
17553 /* If the flag is set to 1 - a dependence is always considered costly;
17554 do not allow dependent instructions in the same group.
17555 This is the most conservative option. */
17556 if (rs6000_sched_costly_dep == all_deps_costly)
17557 return true;
17559 if (rs6000_sched_costly_dep == store_to_load_dep_costly
17560 && is_load_insn (next)
17561 && is_store_insn (insn))
17562 /* Prevent load after store in the same group. */
17563 return true;
17565 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
17566 && is_load_insn (next)
17567 && is_store_insn (insn)
17568 && (!link || (int) REG_NOTE_KIND (link) == 0))
17569 /* Prevent load after store in the same group if it is a true
17570 dependence. */
17571 return true;
17573 /* The flag is set to X; dependences with latency >= X are considered costly,
17574 and will not be scheduled in the same group. */
17575 if (rs6000_sched_costly_dep <= max_dep_latency
17576 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
17577 return true;
17579 return false;
17582 /* Return the next insn after INSN that is found before TAIL is reached,
17583 skipping any "non-active" insns - insns that will not actually occupy
17584 an issue slot. Return NULL_RTX if such an insn is not found. */
17586 static rtx
17587 get_next_active_insn (rtx insn, rtx tail)
17589 if (insn == NULL_RTX || insn == tail)
17590 return NULL_RTX;
17592 while (1)
17594 insn = NEXT_INSN (insn);
17595 if (insn == NULL_RTX || insn == tail)
17596 return NULL_RTX;
17598 if (CALL_P (insn)
17599 || JUMP_P (insn)
17600 || (NONJUMP_INSN_P (insn)
17601 && GET_CODE (PATTERN (insn)) != USE
17602 && GET_CODE (PATTERN (insn)) != CLOBBER
17603 && INSN_CODE (insn) != CODE_FOR_stack_tie))
17604 break;
17606 return insn;
17609 /* We are about to begin issuing insns for this clock cycle. */
17611 static int
17612 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
17613 rtx *ready ATTRIBUTE_UNUSED,
17614 int *pn_ready ATTRIBUTE_UNUSED,
17615 int clock_var ATTRIBUTE_UNUSED)
17617 int n_ready = *pn_ready;
17619 if (sched_verbose)
17620 fprintf (dump, "// rs6000_sched_reorder :\n");
17622 /* Reorder the ready list, if the second to last ready insn
17623 is a nonepipeline insn. */
17624 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
17626 if (is_nonpipeline_insn (ready[n_ready - 1])
17627 && (recog_memoized (ready[n_ready - 2]) > 0))
17628 /* Simply swap first two insns. */
17630 rtx tmp = ready[n_ready - 1];
17631 ready[n_ready - 1] = ready[n_ready - 2];
17632 ready[n_ready - 2] = tmp;
17636 if (rs6000_cpu == PROCESSOR_POWER6)
17637 load_store_pendulum = 0;
17639 return rs6000_issue_rate ();
17642 /* Like rs6000_sched_reorder, but called after issuing each insn. */
17644 static int
17645 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
17646 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
17648 if (sched_verbose)
17649 fprintf (dump, "// rs6000_sched_reorder2 :\n");
17651 /* For Power6, we need to handle some special cases to try and keep the
17652 store queue from overflowing and triggering expensive flushes.
17654 This code monitors how load and store instructions are being issued
17655 and skews the ready list one way or the other to increase the likelihood
17656 that a desired instruction is issued at the proper time.
17658 A couple of things are done. First, we maintain a "load_store_pendulum"
17659 to track the current state of load/store issue.
17661 - If the pendulum is at zero, then no loads or stores have been
17662 issued in the current cycle so we do nothing.
17664 - If the pendulum is 1, then a single load has been issued in this
17665 cycle and we attempt to locate another load in the ready list to
17666 issue with it.
17668 - If the pendulum is -2, then two stores have already been
17669 issued in this cycle, so we increase the priority of the first load
17670 in the ready list to increase it's likelihood of being chosen first
17671 in the next cycle.
17673 - If the pendulum is -1, then a single store has been issued in this
17674 cycle and we attempt to locate another store in the ready list to
17675 issue with it, preferring a store to an adjacent memory location to
17676 facilitate store pairing in the store queue.
17678 - If the pendulum is 2, then two loads have already been
17679 issued in this cycle, so we increase the priority of the first store
17680 in the ready list to increase it's likelihood of being chosen first
17681 in the next cycle.
17683 - If the pendulum < -2 or > 2, then do nothing.
17685 Note: This code covers the most common scenarios. There exist non
17686 load/store instructions which make use of the LSU and which
17687 would need to be accounted for to strictly model the behavior
17688 of the machine. Those instructions are currently unaccounted
17689 for to help minimize compile time overhead of this code.
17691 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
17693 int pos;
17694 int i;
17695 rtx tmp;
17697 if (is_store_insn (last_scheduled_insn))
17698 /* Issuing a store, swing the load_store_pendulum to the left */
17699 load_store_pendulum--;
17700 else if (is_load_insn (last_scheduled_insn))
17701 /* Issuing a load, swing the load_store_pendulum to the right */
17702 load_store_pendulum++;
17703 else
17704 return cached_can_issue_more;
17706 /* If the pendulum is balanced, or there is only one instruction on
17707 the ready list, then all is well, so return. */
17708 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
17709 return cached_can_issue_more;
17711 if (load_store_pendulum == 1)
17713 /* A load has been issued in this cycle. Scan the ready list
17714 for another load to issue with it */
17715 pos = *pn_ready-1;
17717 while (pos >= 0)
17719 if (is_load_insn (ready[pos]))
17721 /* Found a load. Move it to the head of the ready list,
17722 and adjust it's priority so that it is more likely to
17723 stay there */
17724 tmp = ready[pos];
17725 for (i=pos; i<*pn_ready-1; i++)
17726 ready[i] = ready[i + 1];
17727 ready[*pn_ready-1] = tmp;
17728 if INSN_PRIORITY_KNOWN (tmp)
17729 INSN_PRIORITY (tmp)++;
17730 break;
17732 pos--;
17735 else if (load_store_pendulum == -2)
17737 /* Two stores have been issued in this cycle. Increase the
17738 priority of the first load in the ready list to favor it for
17739 issuing in the next cycle. */
17740 pos = *pn_ready-1;
17742 while (pos >= 0)
17744 if (is_load_insn (ready[pos])
17745 && INSN_PRIORITY_KNOWN (ready[pos]))
17747 INSN_PRIORITY (ready[pos])++;
17749 /* Adjust the pendulum to account for the fact that a load
17750 was found and increased in priority. This is to prevent
17751 increasing the priority of multiple loads */
17752 load_store_pendulum--;
17754 break;
17756 pos--;
17759 else if (load_store_pendulum == -1)
17761 /* A store has been issued in this cycle. Scan the ready list for
17762 another store to issue with it, preferring a store to an adjacent
17763 memory location */
17764 int first_store_pos = -1;
17766 pos = *pn_ready-1;
17768 while (pos >= 0)
17770 if (is_store_insn (ready[pos]))
17772 /* Maintain the index of the first store found on the
17773 list */
17774 if (first_store_pos == -1)
17775 first_store_pos = pos;
17777 if (is_store_insn (last_scheduled_insn)
17778 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
17780 /* Found an adjacent store. Move it to the head of the
17781 ready list, and adjust it's priority so that it is
17782 more likely to stay there */
17783 tmp = ready[pos];
17784 for (i=pos; i<*pn_ready-1; i++)
17785 ready[i] = ready[i + 1];
17786 ready[*pn_ready-1] = tmp;
17787 if INSN_PRIORITY_KNOWN (tmp)
17788 INSN_PRIORITY (tmp)++;
17789 first_store_pos = -1;
17791 break;
17794 pos--;
17797 if (first_store_pos >= 0)
17799 /* An adjacent store wasn't found, but a non-adjacent store was,
17800 so move the non-adjacent store to the front of the ready
17801 list, and adjust its priority so that it is more likely to
17802 stay there. */
17803 tmp = ready[first_store_pos];
17804 for (i=first_store_pos; i<*pn_ready-1; i++)
17805 ready[i] = ready[i + 1];
17806 ready[*pn_ready-1] = tmp;
17807 if INSN_PRIORITY_KNOWN (tmp)
17808 INSN_PRIORITY (tmp)++;
17811 else if (load_store_pendulum == 2)
17813 /* Two loads have been issued in this cycle. Increase the priority
17814 of the first store in the ready list to favor it for issuing in
17815 the next cycle. */
17816 pos = *pn_ready-1;
17818 while (pos >= 0)
17820 if (is_store_insn (ready[pos])
17821 && INSN_PRIORITY_KNOWN (ready[pos]))
17823 INSN_PRIORITY (ready[pos])++;
17825 /* Adjust the pendulum to account for the fact that a store
17826 was found and increased in priority. This is to prevent
17827 increasing the priority of multiple stores */
17828 load_store_pendulum++;
17830 break;
17832 pos--;
17837 return cached_can_issue_more;
17840 /* Return whether the presence of INSN causes a dispatch group termination
17841 of group WHICH_GROUP.
17843 If WHICH_GROUP == current_group, this function will return true if INSN
17844 causes the termination of the current group (i.e, the dispatch group to
17845 which INSN belongs). This means that INSN will be the last insn in the
17846 group it belongs to.
17848 If WHICH_GROUP == previous_group, this function will return true if INSN
17849 causes the termination of the previous group (i.e, the dispatch group that
17850 precedes the group to which INSN belongs). This means that INSN will be
17851 the first insn in the group it belongs to). */
17853 static bool
17854 insn_terminates_group_p (rtx insn, enum group_termination which_group)
17856 bool first, last;
17858 if (! insn)
17859 return false;
17861 first = insn_must_be_first_in_group (insn);
17862 last = insn_must_be_last_in_group (insn);
17864 if (first && last)
17865 return true;
17867 if (which_group == current_group)
17868 return last;
17869 else if (which_group == previous_group)
17870 return first;
17872 return false;
17876 static bool
17877 insn_must_be_first_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)
17890 case PROCESSOR_POWER5:
17891 if (is_cracked_insn (insn))
17892 return true;
17893 case PROCESSOR_POWER4:
17894 if (is_microcoded_insn (insn))
17895 return true;
17897 if (!rs6000_sched_groups)
17898 return false;
17900 type = get_attr_type (insn);
17902 switch (type)
17904 case TYPE_MFCR:
17905 case TYPE_MFCRF:
17906 case TYPE_MTCR:
17907 case TYPE_DELAYED_CR:
17908 case TYPE_CR_LOGICAL:
17909 case TYPE_MTJMPR:
17910 case TYPE_MFJMPR:
17911 case TYPE_IDIV:
17912 case TYPE_LDIV:
17913 case TYPE_LOAD_L:
17914 case TYPE_STORE_C:
17915 case TYPE_ISYNC:
17916 case TYPE_SYNC:
17917 return true;
17918 default:
17919 break;
17921 break;
17922 case PROCESSOR_POWER6:
17923 type = get_attr_type (insn);
17925 switch (type)
17927 case TYPE_INSERT_DWORD:
17928 case TYPE_EXTS:
17929 case TYPE_CNTLZ:
17930 case TYPE_SHIFT:
17931 case TYPE_VAR_SHIFT_ROTATE:
17932 case TYPE_TRAP:
17933 case TYPE_IMUL:
17934 case TYPE_IMUL2:
17935 case TYPE_IMUL3:
17936 case TYPE_LMUL:
17937 case TYPE_IDIV:
17938 case TYPE_INSERT_WORD:
17939 case TYPE_DELAYED_COMPARE:
17940 case TYPE_IMUL_COMPARE:
17941 case TYPE_LMUL_COMPARE:
17942 case TYPE_FPCOMPARE:
17943 case TYPE_MFCR:
17944 case TYPE_MTCR:
17945 case TYPE_MFJMPR:
17946 case TYPE_MTJMPR:
17947 case TYPE_ISYNC:
17948 case TYPE_SYNC:
17949 case TYPE_LOAD_L:
17950 case TYPE_STORE_C:
17951 case TYPE_LOAD_U:
17952 case TYPE_LOAD_UX:
17953 case TYPE_LOAD_EXT_UX:
17954 case TYPE_STORE_U:
17955 case TYPE_STORE_UX:
17956 case TYPE_FPLOAD_U:
17957 case TYPE_FPLOAD_UX:
17958 case TYPE_FPSTORE_U:
17959 case TYPE_FPSTORE_UX:
17960 return true;
17961 default:
17962 break;
17964 break;
17965 default:
17966 break;
17969 return false;
17972 static bool
17973 insn_must_be_last_in_group (rtx insn)
17975 enum attr_type type;
17977 if (!insn
17978 || insn == NULL_RTX
17979 || GET_CODE (insn) == NOTE
17980 || GET_CODE (PATTERN (insn)) == USE
17981 || GET_CODE (PATTERN (insn)) == CLOBBER)
17982 return false;
17984 switch (rs6000_cpu) {
17985 case PROCESSOR_POWER4:
17986 case PROCESSOR_POWER5:
17987 if (is_microcoded_insn (insn))
17988 return true;
17990 if (is_branch_slot_insn (insn))
17991 return true;
17993 break;
17994 case PROCESSOR_POWER6:
17995 type = get_attr_type (insn);
17997 switch (type)
17999 case TYPE_EXTS:
18000 case TYPE_CNTLZ:
18001 case TYPE_SHIFT:
18002 case TYPE_VAR_SHIFT_ROTATE:
18003 case TYPE_TRAP:
18004 case TYPE_IMUL:
18005 case TYPE_IMUL2:
18006 case TYPE_IMUL3:
18007 case TYPE_LMUL:
18008 case TYPE_IDIV:
18009 case TYPE_DELAYED_COMPARE:
18010 case TYPE_IMUL_COMPARE:
18011 case TYPE_LMUL_COMPARE:
18012 case TYPE_FPCOMPARE:
18013 case TYPE_MFCR:
18014 case TYPE_MTCR:
18015 case TYPE_MFJMPR:
18016 case TYPE_MTJMPR:
18017 case TYPE_ISYNC:
18018 case TYPE_SYNC:
18019 case TYPE_LOAD_L:
18020 case TYPE_STORE_C:
18021 return true;
18022 default:
18023 break;
18025 break;
18026 default:
18027 break;
18030 return false;
18033 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
18034 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
18036 static bool
18037 is_costly_group (rtx *group_insns, rtx next_insn)
18039 int i;
18040 rtx link;
18041 int cost;
18042 int issue_rate = rs6000_issue_rate ();
18044 for (i = 0; i < issue_rate; i++)
18046 rtx insn = group_insns[i];
18047 if (!insn)
18048 continue;
18049 for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
18051 rtx next = XEXP (link, 0);
18052 if (next == next_insn)
18054 cost = insn_cost (insn, link, next_insn);
18055 if (rs6000_is_costly_dependence (insn, next_insn, link, cost, 0))
18056 return true;
18061 return false;
18064 /* Utility of the function redefine_groups.
18065 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
18066 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
18067 to keep it "far" (in a separate group) from GROUP_INSNS, following
18068 one of the following schemes, depending on the value of the flag
18069 -minsert_sched_nops = X:
18070 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
18071 in order to force NEXT_INSN into a separate group.
18072 (2) X < sched_finish_regroup_exact: insert exactly X nops.
18073 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
18074 insertion (has a group just ended, how many vacant issue slots remain in the
18075 last group, and how many dispatch groups were encountered so far). */
18077 static int
18078 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
18079 rtx next_insn, bool *group_end, int can_issue_more,
18080 int *group_count)
18082 rtx nop;
18083 bool force;
18084 int issue_rate = rs6000_issue_rate ();
18085 bool end = *group_end;
18086 int i;
18088 if (next_insn == NULL_RTX)
18089 return can_issue_more;
18091 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
18092 return can_issue_more;
18094 force = is_costly_group (group_insns, next_insn);
18095 if (!force)
18096 return can_issue_more;
18098 if (sched_verbose > 6)
18099 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
18100 *group_count ,can_issue_more);
18102 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
18104 if (*group_end)
18105 can_issue_more = 0;
18107 /* Since only a branch can be issued in the last issue_slot, it is
18108 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
18109 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
18110 in this case the last nop will start a new group and the branch
18111 will be forced to the new group. */
18112 if (can_issue_more && !is_branch_slot_insn (next_insn))
18113 can_issue_more--;
18115 while (can_issue_more > 0)
18117 nop = gen_nop ();
18118 emit_insn_before (nop, next_insn);
18119 can_issue_more--;
18122 *group_end = true;
18123 return 0;
18126 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
18128 int n_nops = rs6000_sched_insert_nops;
18130 /* Nops can't be issued from the branch slot, so the effective
18131 issue_rate for nops is 'issue_rate - 1'. */
18132 if (can_issue_more == 0)
18133 can_issue_more = issue_rate;
18134 can_issue_more--;
18135 if (can_issue_more == 0)
18137 can_issue_more = issue_rate - 1;
18138 (*group_count)++;
18139 end = true;
18140 for (i = 0; i < issue_rate; i++)
18142 group_insns[i] = 0;
18146 while (n_nops > 0)
18148 nop = gen_nop ();
18149 emit_insn_before (nop, next_insn);
18150 if (can_issue_more == issue_rate - 1) /* new group begins */
18151 end = false;
18152 can_issue_more--;
18153 if (can_issue_more == 0)
18155 can_issue_more = issue_rate - 1;
18156 (*group_count)++;
18157 end = true;
18158 for (i = 0; i < issue_rate; i++)
18160 group_insns[i] = 0;
18163 n_nops--;
18166 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
18167 can_issue_more++;
18169 /* Is next_insn going to start a new group? */
18170 *group_end
18171 = (end
18172 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
18173 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
18174 || (can_issue_more < issue_rate &&
18175 insn_terminates_group_p (next_insn, previous_group)));
18176 if (*group_end && end)
18177 (*group_count)--;
18179 if (sched_verbose > 6)
18180 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
18181 *group_count, can_issue_more);
18182 return can_issue_more;
18185 return can_issue_more;
18188 /* This function tries to synch the dispatch groups that the compiler "sees"
18189 with the dispatch groups that the processor dispatcher is expected to
18190 form in practice. It tries to achieve this synchronization by forcing the
18191 estimated processor grouping on the compiler (as opposed to the function
18192 'pad_goups' which tries to force the scheduler's grouping on the processor).
18194 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
18195 examines the (estimated) dispatch groups that will be formed by the processor
18196 dispatcher. It marks these group boundaries to reflect the estimated
18197 processor grouping, overriding the grouping that the scheduler had marked.
18198 Depending on the value of the flag '-minsert-sched-nops' this function can
18199 force certain insns into separate groups or force a certain distance between
18200 them by inserting nops, for example, if there exists a "costly dependence"
18201 between the insns.
18203 The function estimates the group boundaries that the processor will form as
18204 follows: It keeps track of how many vacant issue slots are available after
18205 each insn. A subsequent insn will start a new group if one of the following
18206 4 cases applies:
18207 - no more vacant issue slots remain in the current dispatch group.
18208 - only the last issue slot, which is the branch slot, is vacant, but the next
18209 insn is not a branch.
18210 - only the last 2 or less issue slots, including the branch slot, are vacant,
18211 which means that a cracked insn (which occupies two issue slots) can't be
18212 issued in this group.
18213 - less than 'issue_rate' slots are vacant, and the next insn always needs to
18214 start a new group. */
18216 static int
18217 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
18219 rtx insn, next_insn;
18220 int issue_rate;
18221 int can_issue_more;
18222 int slot, i;
18223 bool group_end;
18224 int group_count = 0;
18225 rtx *group_insns;
18227 /* Initialize. */
18228 issue_rate = rs6000_issue_rate ();
18229 group_insns = alloca (issue_rate * sizeof (rtx));
18230 for (i = 0; i < issue_rate; i++)
18232 group_insns[i] = 0;
18234 can_issue_more = issue_rate;
18235 slot = 0;
18236 insn = get_next_active_insn (prev_head_insn, tail);
18237 group_end = false;
18239 while (insn != NULL_RTX)
18241 slot = (issue_rate - can_issue_more);
18242 group_insns[slot] = insn;
18243 can_issue_more =
18244 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
18245 if (insn_terminates_group_p (insn, current_group))
18246 can_issue_more = 0;
18248 next_insn = get_next_active_insn (insn, tail);
18249 if (next_insn == NULL_RTX)
18250 return group_count + 1;
18252 /* Is next_insn going to start a new group? */
18253 group_end
18254 = (can_issue_more == 0
18255 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
18256 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
18257 || (can_issue_more < issue_rate &&
18258 insn_terminates_group_p (next_insn, previous_group)));
18260 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
18261 next_insn, &group_end, can_issue_more,
18262 &group_count);
18264 if (group_end)
18266 group_count++;
18267 can_issue_more = 0;
18268 for (i = 0; i < issue_rate; i++)
18270 group_insns[i] = 0;
18274 if (GET_MODE (next_insn) == TImode && can_issue_more)
18275 PUT_MODE (next_insn, VOIDmode);
18276 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
18277 PUT_MODE (next_insn, TImode);
18279 insn = next_insn;
18280 if (can_issue_more == 0)
18281 can_issue_more = issue_rate;
18282 } /* while */
18284 return group_count;
18287 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
18288 dispatch group boundaries that the scheduler had marked. Pad with nops
18289 any dispatch groups which have vacant issue slots, in order to force the
18290 scheduler's grouping on the processor dispatcher. The function
18291 returns the number of dispatch groups found. */
18293 static int
18294 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
18296 rtx insn, next_insn;
18297 rtx nop;
18298 int issue_rate;
18299 int can_issue_more;
18300 int group_end;
18301 int group_count = 0;
18303 /* Initialize issue_rate. */
18304 issue_rate = rs6000_issue_rate ();
18305 can_issue_more = issue_rate;
18307 insn = get_next_active_insn (prev_head_insn, tail);
18308 next_insn = get_next_active_insn (insn, tail);
18310 while (insn != NULL_RTX)
18312 can_issue_more =
18313 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
18315 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
18317 if (next_insn == NULL_RTX)
18318 break;
18320 if (group_end)
18322 /* If the scheduler had marked group termination at this location
18323 (between insn and next_indn), and neither insn nor next_insn will
18324 force group termination, pad the group with nops to force group
18325 termination. */
18326 if (can_issue_more
18327 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
18328 && !insn_terminates_group_p (insn, current_group)
18329 && !insn_terminates_group_p (next_insn, previous_group))
18331 if (!is_branch_slot_insn (next_insn))
18332 can_issue_more--;
18334 while (can_issue_more)
18336 nop = gen_nop ();
18337 emit_insn_before (nop, next_insn);
18338 can_issue_more--;
18342 can_issue_more = issue_rate;
18343 group_count++;
18346 insn = next_insn;
18347 next_insn = get_next_active_insn (insn, tail);
18350 return group_count;
18353 /* We're beginning a new block. Initialize data structures as necessary. */
18355 static void
18356 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
18357 int sched_verbose ATTRIBUTE_UNUSED,
18358 int max_ready ATTRIBUTE_UNUSED)
18360 last_scheduled_insn = NULL_RTX;
18361 load_store_pendulum = 0;
18364 /* The following function is called at the end of scheduling BB.
18365 After reload, it inserts nops at insn group bundling. */
18367 static void
18368 rs6000_sched_finish (FILE *dump, int sched_verbose)
18370 int n_groups;
18372 if (sched_verbose)
18373 fprintf (dump, "=== Finishing schedule.\n");
18375 if (reload_completed && rs6000_sched_groups)
18377 if (rs6000_sched_insert_nops == sched_finish_none)
18378 return;
18380 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
18381 n_groups = pad_groups (dump, sched_verbose,
18382 current_sched_info->prev_head,
18383 current_sched_info->next_tail);
18384 else
18385 n_groups = redefine_groups (dump, sched_verbose,
18386 current_sched_info->prev_head,
18387 current_sched_info->next_tail);
18389 if (sched_verbose >= 6)
18391 fprintf (dump, "ngroups = %d\n", n_groups);
18392 print_rtl (dump, current_sched_info->prev_head);
18393 fprintf (dump, "Done finish_sched\n");
18398 /* Length in units of the trampoline for entering a nested function. */
18401 rs6000_trampoline_size (void)
18403 int ret = 0;
18405 switch (DEFAULT_ABI)
18407 default:
18408 gcc_unreachable ();
18410 case ABI_AIX:
18411 ret = (TARGET_32BIT) ? 12 : 24;
18412 break;
18414 case ABI_DARWIN:
18415 case ABI_V4:
18416 ret = (TARGET_32BIT) ? 40 : 48;
18417 break;
18420 return ret;
18423 /* Emit RTL insns to initialize the variable parts of a trampoline.
18424 FNADDR is an RTX for the address of the function's pure code.
18425 CXT is an RTX for the static chain value for the function. */
18427 void
18428 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
18430 int regsize = (TARGET_32BIT) ? 4 : 8;
18431 rtx ctx_reg = force_reg (Pmode, cxt);
18433 switch (DEFAULT_ABI)
18435 default:
18436 gcc_unreachable ();
18438 /* Macros to shorten the code expansions below. */
18439 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
18440 #define MEM_PLUS(addr,offset) \
18441 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
18443 /* Under AIX, just build the 3 word function descriptor */
18444 case ABI_AIX:
18446 rtx fn_reg = gen_reg_rtx (Pmode);
18447 rtx toc_reg = gen_reg_rtx (Pmode);
18448 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
18449 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
18450 emit_move_insn (MEM_DEREF (addr), fn_reg);
18451 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
18452 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
18454 break;
18456 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
18457 case ABI_DARWIN:
18458 case ABI_V4:
18459 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
18460 FALSE, VOIDmode, 4,
18461 addr, Pmode,
18462 GEN_INT (rs6000_trampoline_size ()), SImode,
18463 fnaddr, Pmode,
18464 ctx_reg, Pmode);
18465 break;
18468 return;
18472 /* Table of valid machine attributes. */
18474 const struct attribute_spec rs6000_attribute_table[] =
18476 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
18477 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
18478 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
18479 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
18480 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
18481 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
18482 #ifdef SUBTARGET_ATTRIBUTE_TABLE
18483 SUBTARGET_ATTRIBUTE_TABLE,
18484 #endif
18485 { NULL, 0, 0, false, false, false, NULL }
18488 /* Handle the "altivec" attribute. The attribute may have
18489 arguments as follows:
18491 __attribute__((altivec(vector__)))
18492 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
18493 __attribute__((altivec(bool__))) (always followed by 'unsigned')
18495 and may appear more than once (e.g., 'vector bool char') in a
18496 given declaration. */
18498 static tree
18499 rs6000_handle_altivec_attribute (tree *node,
18500 tree name ATTRIBUTE_UNUSED,
18501 tree args,
18502 int flags ATTRIBUTE_UNUSED,
18503 bool *no_add_attrs)
18505 tree type = *node, result = NULL_TREE;
18506 enum machine_mode mode;
18507 int unsigned_p;
18508 char altivec_type
18509 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
18510 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
18511 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
18512 : '?');
18514 while (POINTER_TYPE_P (type)
18515 || TREE_CODE (type) == FUNCTION_TYPE
18516 || TREE_CODE (type) == METHOD_TYPE
18517 || TREE_CODE (type) == ARRAY_TYPE)
18518 type = TREE_TYPE (type);
18520 mode = TYPE_MODE (type);
18522 /* Check for invalid AltiVec type qualifiers. */
18523 if (type == long_unsigned_type_node || type == long_integer_type_node)
18525 if (TARGET_64BIT)
18526 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
18527 else if (rs6000_warn_altivec_long)
18528 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
18530 else if (type == long_long_unsigned_type_node
18531 || type == long_long_integer_type_node)
18532 error ("use of %<long long%> in AltiVec types is invalid");
18533 else if (type == double_type_node)
18534 error ("use of %<double%> in AltiVec types is invalid");
18535 else if (type == long_double_type_node)
18536 error ("use of %<long double%> in AltiVec types is invalid");
18537 else if (type == boolean_type_node)
18538 error ("use of boolean types in AltiVec types is invalid");
18539 else if (TREE_CODE (type) == COMPLEX_TYPE)
18540 error ("use of %<complex%> in AltiVec types is invalid");
18541 else if (DECIMAL_FLOAT_MODE_P (mode))
18542 error ("use of decimal floating point types in AltiVec types is invalid");
18544 switch (altivec_type)
18546 case 'v':
18547 unsigned_p = TYPE_UNSIGNED (type);
18548 switch (mode)
18550 case SImode:
18551 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
18552 break;
18553 case HImode:
18554 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
18555 break;
18556 case QImode:
18557 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
18558 break;
18559 case SFmode: result = V4SF_type_node; break;
18560 /* If the user says 'vector int bool', we may be handed the 'bool'
18561 attribute _before_ the 'vector' attribute, and so select the
18562 proper type in the 'b' case below. */
18563 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
18564 result = type;
18565 default: break;
18567 break;
18568 case 'b':
18569 switch (mode)
18571 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
18572 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
18573 case QImode: case V16QImode: result = bool_V16QI_type_node;
18574 default: break;
18576 break;
18577 case 'p':
18578 switch (mode)
18580 case V8HImode: result = pixel_V8HI_type_node;
18581 default: break;
18583 default: break;
18586 if (result && result != type && TYPE_READONLY (type))
18587 result = build_qualified_type (result, TYPE_QUAL_CONST);
18589 *no_add_attrs = true; /* No need to hang on to the attribute. */
18591 if (result)
18592 *node = reconstruct_complex_type (*node, result);
18594 return NULL_TREE;
18597 /* AltiVec defines four built-in scalar types that serve as vector
18598 elements; we must teach the compiler how to mangle them. */
18600 static const char *
18601 rs6000_mangle_fundamental_type (tree type)
18603 if (type == bool_char_type_node) return "U6__boolc";
18604 if (type == bool_short_type_node) return "U6__bools";
18605 if (type == pixel_type_node) return "u7__pixel";
18606 if (type == bool_int_type_node) return "U6__booli";
18608 /* Mangle IBM extended float long double as `g' (__float128) on
18609 powerpc*-linux where long-double-64 previously was the default. */
18610 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
18611 && TARGET_ELF
18612 && TARGET_LONG_DOUBLE_128
18613 && !TARGET_IEEEQUAD)
18614 return "g";
18616 /* For all other types, use normal C++ mangling. */
18617 return NULL;
18620 /* Handle a "longcall" or "shortcall" attribute; arguments as in
18621 struct attribute_spec.handler. */
18623 static tree
18624 rs6000_handle_longcall_attribute (tree *node, tree name,
18625 tree args ATTRIBUTE_UNUSED,
18626 int flags ATTRIBUTE_UNUSED,
18627 bool *no_add_attrs)
18629 if (TREE_CODE (*node) != FUNCTION_TYPE
18630 && TREE_CODE (*node) != FIELD_DECL
18631 && TREE_CODE (*node) != TYPE_DECL)
18633 warning (OPT_Wattributes, "%qs attribute only applies to functions",
18634 IDENTIFIER_POINTER (name));
18635 *no_add_attrs = true;
18638 return NULL_TREE;
18641 /* Set longcall attributes on all functions declared when
18642 rs6000_default_long_calls is true. */
18643 static void
18644 rs6000_set_default_type_attributes (tree type)
18646 if (rs6000_default_long_calls
18647 && (TREE_CODE (type) == FUNCTION_TYPE
18648 || TREE_CODE (type) == METHOD_TYPE))
18649 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
18650 NULL_TREE,
18651 TYPE_ATTRIBUTES (type));
18653 #if TARGET_MACHO
18654 darwin_set_default_type_attributes (type);
18655 #endif
18658 /* Return a reference suitable for calling a function with the
18659 longcall attribute. */
18662 rs6000_longcall_ref (rtx call_ref)
18664 const char *call_name;
18665 tree node;
18667 if (GET_CODE (call_ref) != SYMBOL_REF)
18668 return call_ref;
18670 /* System V adds '.' to the internal name, so skip them. */
18671 call_name = XSTR (call_ref, 0);
18672 if (*call_name == '.')
18674 while (*call_name == '.')
18675 call_name++;
18677 node = get_identifier (call_name);
18678 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
18681 return force_reg (Pmode, call_ref);
18684 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
18685 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
18686 #endif
18688 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
18689 struct attribute_spec.handler. */
18690 static tree
18691 rs6000_handle_struct_attribute (tree *node, tree name,
18692 tree args ATTRIBUTE_UNUSED,
18693 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
18695 tree *type = NULL;
18696 if (DECL_P (*node))
18698 if (TREE_CODE (*node) == TYPE_DECL)
18699 type = &TREE_TYPE (*node);
18701 else
18702 type = node;
18704 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
18705 || TREE_CODE (*type) == UNION_TYPE)))
18707 warning (OPT_Wattributes, "%qs attribute ignored", IDENTIFIER_POINTER (name));
18708 *no_add_attrs = true;
18711 else if ((is_attribute_p ("ms_struct", name)
18712 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
18713 || ((is_attribute_p ("gcc_struct", name)
18714 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
18716 warning (OPT_Wattributes, "%qs incompatible attribute ignored",
18717 IDENTIFIER_POINTER (name));
18718 *no_add_attrs = true;
18721 return NULL_TREE;
18724 static bool
18725 rs6000_ms_bitfield_layout_p (tree record_type)
18727 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
18728 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
18729 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
18732 #ifdef USING_ELFOS_H
18734 /* A get_unnamed_section callback, used for switching to toc_section. */
18736 static void
18737 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
18739 if (DEFAULT_ABI == ABI_AIX
18740 && TARGET_MINIMAL_TOC
18741 && !TARGET_RELOCATABLE)
18743 if (!toc_initialized)
18745 toc_initialized = 1;
18746 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
18747 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
18748 fprintf (asm_out_file, "\t.tc ");
18749 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
18750 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18751 fprintf (asm_out_file, "\n");
18753 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18754 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18755 fprintf (asm_out_file, " = .+32768\n");
18757 else
18758 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18760 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
18761 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
18762 else
18764 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18765 if (!toc_initialized)
18767 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18768 fprintf (asm_out_file, " = .+32768\n");
18769 toc_initialized = 1;
18774 /* Implement TARGET_ASM_INIT_SECTIONS. */
18776 static void
18777 rs6000_elf_asm_init_sections (void)
18779 toc_section
18780 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
18782 sdata2_section
18783 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
18784 SDATA2_SECTION_ASM_OP);
18787 /* Implement TARGET_SELECT_RTX_SECTION. */
18789 static section *
18790 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
18791 unsigned HOST_WIDE_INT align)
18793 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
18794 return toc_section;
18795 else
18796 return default_elf_select_rtx_section (mode, x, align);
18799 /* Implement TARGET_ASM_SELECT_SECTION for ELF targets. */
18801 static section *
18802 rs6000_elf_select_section (tree decl, int reloc,
18803 unsigned HOST_WIDE_INT align)
18805 /* Pretend that we're always building for a shared library when
18806 ABI_AIX, because otherwise we end up with dynamic relocations
18807 in read-only sections. This happens for function pointers,
18808 references to vtables in typeinfo, and probably other cases. */
18809 return default_elf_select_section_1 (decl, reloc, align,
18810 flag_pic || DEFAULT_ABI == ABI_AIX);
18813 /* A C statement to build up a unique section name, expressed as a
18814 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
18815 RELOC indicates whether the initial value of EXP requires
18816 link-time relocations. If you do not define this macro, GCC will use
18817 the symbol name prefixed by `.' as the section name. Note - this
18818 macro can now be called for uninitialized data items as well as
18819 initialized data and functions. */
18821 static void
18822 rs6000_elf_unique_section (tree decl, int reloc)
18824 /* As above, pretend that we're always building for a shared library
18825 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
18826 default_unique_section_1 (decl, reloc,
18827 flag_pic || DEFAULT_ABI == ABI_AIX);
18830 /* For a SYMBOL_REF, set generic flags and then perform some
18831 target-specific processing.
18833 When the AIX ABI is requested on a non-AIX system, replace the
18834 function name with the real name (with a leading .) rather than the
18835 function descriptor name. This saves a lot of overriding code to
18836 read the prefixes. */
18838 static void
18839 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
18841 default_encode_section_info (decl, rtl, first);
18843 if (first
18844 && TREE_CODE (decl) == FUNCTION_DECL
18845 && !TARGET_AIX
18846 && DEFAULT_ABI == ABI_AIX)
18848 rtx sym_ref = XEXP (rtl, 0);
18849 size_t len = strlen (XSTR (sym_ref, 0));
18850 char *str = alloca (len + 2);
18851 str[0] = '.';
18852 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
18853 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
18857 bool
18858 rs6000_elf_in_small_data_p (tree decl)
18860 if (rs6000_sdata == SDATA_NONE)
18861 return false;
18863 /* We want to merge strings, so we never consider them small data. */
18864 if (TREE_CODE (decl) == STRING_CST)
18865 return false;
18867 /* Functions are never in the small data area. */
18868 if (TREE_CODE (decl) == FUNCTION_DECL)
18869 return false;
18871 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
18873 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
18874 if (strcmp (section, ".sdata") == 0
18875 || strcmp (section, ".sdata2") == 0
18876 || strcmp (section, ".sbss") == 0
18877 || strcmp (section, ".sbss2") == 0
18878 || strcmp (section, ".PPC.EMB.sdata0") == 0
18879 || strcmp (section, ".PPC.EMB.sbss0") == 0)
18880 return true;
18882 else
18884 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
18886 if (size > 0
18887 && (unsigned HOST_WIDE_INT) size <= g_switch_value
18888 /* If it's not public, and we're not going to reference it there,
18889 there's no need to put it in the small data section. */
18890 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
18891 return true;
18894 return false;
18897 #endif /* USING_ELFOS_H */
18899 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
18901 static bool
18902 rs6000_use_blocks_for_constant_p (enum machine_mode mode, rtx x)
18904 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
18907 /* Return a REG that occurs in ADDR with coefficient 1.
18908 ADDR can be effectively incremented by incrementing REG.
18910 r0 is special and we must not select it as an address
18911 register by this routine since our caller will try to
18912 increment the returned register via an "la" instruction. */
18915 find_addr_reg (rtx addr)
18917 while (GET_CODE (addr) == PLUS)
18919 if (GET_CODE (XEXP (addr, 0)) == REG
18920 && REGNO (XEXP (addr, 0)) != 0)
18921 addr = XEXP (addr, 0);
18922 else if (GET_CODE (XEXP (addr, 1)) == REG
18923 && REGNO (XEXP (addr, 1)) != 0)
18924 addr = XEXP (addr, 1);
18925 else if (CONSTANT_P (XEXP (addr, 0)))
18926 addr = XEXP (addr, 1);
18927 else if (CONSTANT_P (XEXP (addr, 1)))
18928 addr = XEXP (addr, 0);
18929 else
18930 gcc_unreachable ();
18932 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
18933 return addr;
18936 void
18937 rs6000_fatal_bad_address (rtx op)
18939 fatal_insn ("bad address", op);
18942 #if TARGET_MACHO
18944 static tree branch_island_list = 0;
18946 /* Remember to generate a branch island for far calls to the given
18947 function. */
18949 static void
18950 add_compiler_branch_island (tree label_name, tree function_name,
18951 int line_number)
18953 tree branch_island = build_tree_list (function_name, label_name);
18954 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
18955 TREE_CHAIN (branch_island) = branch_island_list;
18956 branch_island_list = branch_island;
18959 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
18960 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
18961 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
18962 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
18964 /* Generate far-jump branch islands for everything on the
18965 branch_island_list. Invoked immediately after the last instruction
18966 of the epilogue has been emitted; the branch-islands must be
18967 appended to, and contiguous with, the function body. Mach-O stubs
18968 are generated in machopic_output_stub(). */
18970 static void
18971 macho_branch_islands (void)
18973 char tmp_buf[512];
18974 tree branch_island;
18976 for (branch_island = branch_island_list;
18977 branch_island;
18978 branch_island = TREE_CHAIN (branch_island))
18980 const char *label =
18981 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
18982 const char *name =
18983 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
18984 char name_buf[512];
18985 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
18986 if (name[0] == '*' || name[0] == '&')
18987 strcpy (name_buf, name+1);
18988 else
18990 name_buf[0] = '_';
18991 strcpy (name_buf+1, name);
18993 strcpy (tmp_buf, "\n");
18994 strcat (tmp_buf, label);
18995 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
18996 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
18997 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
18998 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
18999 if (flag_pic)
19001 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
19002 strcat (tmp_buf, label);
19003 strcat (tmp_buf, "_pic\n");
19004 strcat (tmp_buf, label);
19005 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
19007 strcat (tmp_buf, "\taddis r11,r11,ha16(");
19008 strcat (tmp_buf, name_buf);
19009 strcat (tmp_buf, " - ");
19010 strcat (tmp_buf, label);
19011 strcat (tmp_buf, "_pic)\n");
19013 strcat (tmp_buf, "\tmtlr r0\n");
19015 strcat (tmp_buf, "\taddi r12,r11,lo16(");
19016 strcat (tmp_buf, name_buf);
19017 strcat (tmp_buf, " - ");
19018 strcat (tmp_buf, label);
19019 strcat (tmp_buf, "_pic)\n");
19021 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
19023 else
19025 strcat (tmp_buf, ":\nlis r12,hi16(");
19026 strcat (tmp_buf, name_buf);
19027 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
19028 strcat (tmp_buf, name_buf);
19029 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
19031 output_asm_insn (tmp_buf, 0);
19032 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
19033 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
19034 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
19035 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
19038 branch_island_list = 0;
19041 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
19042 already there or not. */
19044 static int
19045 no_previous_def (tree function_name)
19047 tree branch_island;
19048 for (branch_island = branch_island_list;
19049 branch_island;
19050 branch_island = TREE_CHAIN (branch_island))
19051 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
19052 return 0;
19053 return 1;
19056 /* GET_PREV_LABEL gets the label name from the previous definition of
19057 the function. */
19059 static tree
19060 get_prev_label (tree function_name)
19062 tree branch_island;
19063 for (branch_island = branch_island_list;
19064 branch_island;
19065 branch_island = TREE_CHAIN (branch_island))
19066 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
19067 return BRANCH_ISLAND_LABEL_NAME (branch_island);
19068 return 0;
19071 /* INSN is either a function call or a millicode call. It may have an
19072 unconditional jump in its delay slot.
19074 CALL_DEST is the routine we are calling. */
19076 char *
19077 output_call (rtx insn, rtx *operands, int dest_operand_number,
19078 int cookie_operand_number)
19080 static char buf[256];
19081 if (GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
19082 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
19084 tree labelname;
19085 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
19087 if (no_previous_def (funname))
19089 int line_number = 0;
19090 rtx label_rtx = gen_label_rtx ();
19091 char *label_buf, temp_buf[256];
19092 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
19093 CODE_LABEL_NUMBER (label_rtx));
19094 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
19095 labelname = get_identifier (label_buf);
19096 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
19097 if (insn)
19098 line_number = NOTE_LINE_NUMBER (insn);
19099 add_compiler_branch_island (labelname, funname, line_number);
19101 else
19102 labelname = get_prev_label (funname);
19104 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
19105 instruction will reach 'foo', otherwise link as 'bl L42'".
19106 "L42" should be a 'branch island', that will do a far jump to
19107 'foo'. Branch islands are generated in
19108 macho_branch_islands(). */
19109 sprintf (buf, "jbsr %%z%d,%.246s",
19110 dest_operand_number, IDENTIFIER_POINTER (labelname));
19112 else
19113 sprintf (buf, "bl %%z%d", dest_operand_number);
19114 return buf;
19117 /* Generate PIC and indirect symbol stubs. */
19119 void
19120 machopic_output_stub (FILE *file, const char *symb, const char *stub)
19122 unsigned int length;
19123 char *symbol_name, *lazy_ptr_name;
19124 char *local_label_0;
19125 static int label = 0;
19127 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
19128 symb = (*targetm.strip_name_encoding) (symb);
19131 length = strlen (symb);
19132 symbol_name = alloca (length + 32);
19133 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
19135 lazy_ptr_name = alloca (length + 32);
19136 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
19138 if (flag_pic == 2)
19139 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
19140 else
19141 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
19143 if (flag_pic == 2)
19145 fprintf (file, "\t.align 5\n");
19147 fprintf (file, "%s:\n", stub);
19148 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19150 label++;
19151 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
19152 sprintf (local_label_0, "\"L%011d$spb\"", label);
19154 fprintf (file, "\tmflr r0\n");
19155 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
19156 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
19157 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
19158 lazy_ptr_name, local_label_0);
19159 fprintf (file, "\tmtlr r0\n");
19160 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
19161 (TARGET_64BIT ? "ldu" : "lwzu"),
19162 lazy_ptr_name, local_label_0);
19163 fprintf (file, "\tmtctr r12\n");
19164 fprintf (file, "\tbctr\n");
19166 else
19168 fprintf (file, "\t.align 4\n");
19170 fprintf (file, "%s:\n", stub);
19171 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19173 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
19174 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
19175 (TARGET_64BIT ? "ldu" : "lwzu"),
19176 lazy_ptr_name);
19177 fprintf (file, "\tmtctr r12\n");
19178 fprintf (file, "\tbctr\n");
19181 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
19182 fprintf (file, "%s:\n", lazy_ptr_name);
19183 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19184 fprintf (file, "%sdyld_stub_binding_helper\n",
19185 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
19188 /* Legitimize PIC addresses. If the address is already
19189 position-independent, we return ORIG. Newly generated
19190 position-independent addresses go into a reg. This is REG if non
19191 zero, otherwise we allocate register(s) as necessary. */
19193 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
19196 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
19197 rtx reg)
19199 rtx base, offset;
19201 if (reg == NULL && ! reload_in_progress && ! reload_completed)
19202 reg = gen_reg_rtx (Pmode);
19204 if (GET_CODE (orig) == CONST)
19206 rtx reg_temp;
19208 if (GET_CODE (XEXP (orig, 0)) == PLUS
19209 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
19210 return orig;
19212 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
19214 /* Use a different reg for the intermediate value, as
19215 it will be marked UNCHANGING. */
19216 reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
19217 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
19218 Pmode, reg_temp);
19219 offset =
19220 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
19221 Pmode, reg);
19223 if (GET_CODE (offset) == CONST_INT)
19225 if (SMALL_INT (offset))
19226 return plus_constant (base, INTVAL (offset));
19227 else if (! reload_in_progress && ! reload_completed)
19228 offset = force_reg (Pmode, offset);
19229 else
19231 rtx mem = force_const_mem (Pmode, orig);
19232 return machopic_legitimize_pic_address (mem, Pmode, reg);
19235 return gen_rtx_PLUS (Pmode, base, offset);
19238 /* Fall back on generic machopic code. */
19239 return machopic_legitimize_pic_address (orig, mode, reg);
19242 /* Output a .machine directive for the Darwin assembler, and call
19243 the generic start_file routine. */
19245 static void
19246 rs6000_darwin_file_start (void)
19248 static const struct
19250 const char *arg;
19251 const char *name;
19252 int if_set;
19253 } mapping[] = {
19254 { "ppc64", "ppc64", MASK_64BIT },
19255 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
19256 { "power4", "ppc970", 0 },
19257 { "G5", "ppc970", 0 },
19258 { "7450", "ppc7450", 0 },
19259 { "7400", "ppc7400", MASK_ALTIVEC },
19260 { "G4", "ppc7400", 0 },
19261 { "750", "ppc750", 0 },
19262 { "740", "ppc750", 0 },
19263 { "G3", "ppc750", 0 },
19264 { "604e", "ppc604e", 0 },
19265 { "604", "ppc604", 0 },
19266 { "603e", "ppc603", 0 },
19267 { "603", "ppc603", 0 },
19268 { "601", "ppc601", 0 },
19269 { NULL, "ppc", 0 } };
19270 const char *cpu_id = "";
19271 size_t i;
19273 rs6000_file_start ();
19274 darwin_file_start ();
19276 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
19277 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
19278 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
19279 && rs6000_select[i].string[0] != '\0')
19280 cpu_id = rs6000_select[i].string;
19282 /* Look through the mapping array. Pick the first name that either
19283 matches the argument, has a bit set in IF_SET that is also set
19284 in the target flags, or has a NULL name. */
19286 i = 0;
19287 while (mapping[i].arg != NULL
19288 && strcmp (mapping[i].arg, cpu_id) != 0
19289 && (mapping[i].if_set & target_flags) == 0)
19290 i++;
19292 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
19295 #endif /* TARGET_MACHO */
19297 #if TARGET_ELF
19298 static unsigned int
19299 rs6000_elf_section_type_flags (tree decl, const char *name, int reloc)
19301 return default_section_type_flags_1 (decl, name, reloc,
19302 flag_pic || DEFAULT_ABI == ABI_AIX);
19305 /* Record an element in the table of global constructors. SYMBOL is
19306 a SYMBOL_REF of the function to be called; PRIORITY is a number
19307 between 0 and MAX_INIT_PRIORITY.
19309 This differs from default_named_section_asm_out_constructor in
19310 that we have special handling for -mrelocatable. */
19312 static void
19313 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
19315 const char *section = ".ctors";
19316 char buf[16];
19318 if (priority != DEFAULT_INIT_PRIORITY)
19320 sprintf (buf, ".ctors.%.5u",
19321 /* Invert the numbering so the linker puts us in the proper
19322 order; constructors are run from right to left, and the
19323 linker sorts in increasing order. */
19324 MAX_INIT_PRIORITY - priority);
19325 section = buf;
19328 switch_to_section (get_section (section, SECTION_WRITE, NULL));
19329 assemble_align (POINTER_SIZE);
19331 if (TARGET_RELOCATABLE)
19333 fputs ("\t.long (", asm_out_file);
19334 output_addr_const (asm_out_file, symbol);
19335 fputs (")@fixup\n", asm_out_file);
19337 else
19338 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
19341 static void
19342 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
19344 const char *section = ".dtors";
19345 char buf[16];
19347 if (priority != DEFAULT_INIT_PRIORITY)
19349 sprintf (buf, ".dtors.%.5u",
19350 /* Invert the numbering so the linker puts us in the proper
19351 order; constructors are run from right to left, and the
19352 linker sorts in increasing order. */
19353 MAX_INIT_PRIORITY - priority);
19354 section = buf;
19357 switch_to_section (get_section (section, SECTION_WRITE, NULL));
19358 assemble_align (POINTER_SIZE);
19360 if (TARGET_RELOCATABLE)
19362 fputs ("\t.long (", asm_out_file);
19363 output_addr_const (asm_out_file, symbol);
19364 fputs (")@fixup\n", asm_out_file);
19366 else
19367 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
19370 void
19371 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
19373 if (TARGET_64BIT)
19375 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
19376 ASM_OUTPUT_LABEL (file, name);
19377 fputs (DOUBLE_INT_ASM_OP, file);
19378 rs6000_output_function_entry (file, name);
19379 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
19380 if (DOT_SYMBOLS)
19382 fputs ("\t.size\t", file);
19383 assemble_name (file, name);
19384 fputs (",24\n\t.type\t.", file);
19385 assemble_name (file, name);
19386 fputs (",@function\n", file);
19387 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
19389 fputs ("\t.globl\t.", file);
19390 assemble_name (file, name);
19391 putc ('\n', file);
19394 else
19395 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
19396 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
19397 rs6000_output_function_entry (file, name);
19398 fputs (":\n", file);
19399 return;
19402 if (TARGET_RELOCATABLE
19403 && !TARGET_SECURE_PLT
19404 && (get_pool_size () != 0 || current_function_profile)
19405 && uses_TOC ())
19407 char buf[256];
19409 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
19411 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19412 fprintf (file, "\t.long ");
19413 assemble_name (file, buf);
19414 putc ('-', file);
19415 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19416 assemble_name (file, buf);
19417 putc ('\n', file);
19420 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
19421 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
19423 if (DEFAULT_ABI == ABI_AIX)
19425 const char *desc_name, *orig_name;
19427 orig_name = (*targetm.strip_name_encoding) (name);
19428 desc_name = orig_name;
19429 while (*desc_name == '.')
19430 desc_name++;
19432 if (TREE_PUBLIC (decl))
19433 fprintf (file, "\t.globl %s\n", desc_name);
19435 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
19436 fprintf (file, "%s:\n", desc_name);
19437 fprintf (file, "\t.long %s\n", orig_name);
19438 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
19439 if (DEFAULT_ABI == ABI_AIX)
19440 fputs ("\t.long 0\n", file);
19441 fprintf (file, "\t.previous\n");
19443 ASM_OUTPUT_LABEL (file, name);
19446 static void
19447 rs6000_elf_end_indicate_exec_stack (void)
19449 if (TARGET_32BIT)
19450 file_end_indicate_exec_stack ();
19452 #endif
19454 #if TARGET_XCOFF
19455 static void
19456 rs6000_xcoff_asm_output_anchor (rtx symbol)
19458 char buffer[100];
19460 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
19461 SYMBOL_REF_BLOCK_OFFSET (symbol));
19462 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
19465 static void
19466 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
19468 fputs (GLOBAL_ASM_OP, stream);
19469 RS6000_OUTPUT_BASENAME (stream, name);
19470 putc ('\n', stream);
19473 /* A get_unnamed_decl callback, used for read-only sections. PTR
19474 points to the section string variable. */
19476 static void
19477 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
19479 fprintf (asm_out_file, "\t.csect %s[RO],3\n",
19480 *(const char *const *) directive);
19483 /* Likewise for read-write sections. */
19485 static void
19486 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
19488 fprintf (asm_out_file, "\t.csect %s[RW],3\n",
19489 *(const char *const *) directive);
19492 /* A get_unnamed_section callback, used for switching to toc_section. */
19494 static void
19495 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
19497 if (TARGET_MINIMAL_TOC)
19499 /* toc_section is always selected at least once from
19500 rs6000_xcoff_file_start, so this is guaranteed to
19501 always be defined once and only once in each file. */
19502 if (!toc_initialized)
19504 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
19505 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
19506 toc_initialized = 1;
19508 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
19509 (TARGET_32BIT ? "" : ",3"));
19511 else
19512 fputs ("\t.toc\n", asm_out_file);
19515 /* Implement TARGET_ASM_INIT_SECTIONS. */
19517 static void
19518 rs6000_xcoff_asm_init_sections (void)
19520 read_only_data_section
19521 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
19522 &xcoff_read_only_section_name);
19524 private_data_section
19525 = get_unnamed_section (SECTION_WRITE,
19526 rs6000_xcoff_output_readwrite_section_asm_op,
19527 &xcoff_private_data_section_name);
19529 read_only_private_data_section
19530 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
19531 &xcoff_private_data_section_name);
19533 toc_section
19534 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
19536 readonly_data_section = read_only_data_section;
19537 exception_section = data_section;
19540 static void
19541 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
19542 tree decl ATTRIBUTE_UNUSED)
19544 int smclass;
19545 static const char * const suffix[3] = { "PR", "RO", "RW" };
19547 if (flags & SECTION_CODE)
19548 smclass = 0;
19549 else if (flags & SECTION_WRITE)
19550 smclass = 2;
19551 else
19552 smclass = 1;
19554 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
19555 (flags & SECTION_CODE) ? "." : "",
19556 name, suffix[smclass], flags & SECTION_ENTSIZE);
19559 static section *
19560 rs6000_xcoff_select_section (tree decl, int reloc,
19561 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
19563 if (decl_readonly_section_1 (decl, reloc, 1))
19565 if (TREE_PUBLIC (decl))
19566 return read_only_data_section;
19567 else
19568 return read_only_private_data_section;
19570 else
19572 if (TREE_PUBLIC (decl))
19573 return data_section;
19574 else
19575 return private_data_section;
19579 static void
19580 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
19582 const char *name;
19584 /* Use select_section for private and uninitialized data. */
19585 if (!TREE_PUBLIC (decl)
19586 || DECL_COMMON (decl)
19587 || DECL_INITIAL (decl) == NULL_TREE
19588 || DECL_INITIAL (decl) == error_mark_node
19589 || (flag_zero_initialized_in_bss
19590 && initializer_zerop (DECL_INITIAL (decl))))
19591 return;
19593 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
19594 name = (*targetm.strip_name_encoding) (name);
19595 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
19598 /* Select section for constant in constant pool.
19600 On RS/6000, all constants are in the private read-only data area.
19601 However, if this is being placed in the TOC it must be output as a
19602 toc entry. */
19604 static section *
19605 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
19606 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
19608 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
19609 return toc_section;
19610 else
19611 return read_only_private_data_section;
19614 /* Remove any trailing [DS] or the like from the symbol name. */
19616 static const char *
19617 rs6000_xcoff_strip_name_encoding (const char *name)
19619 size_t len;
19620 if (*name == '*')
19621 name++;
19622 len = strlen (name);
19623 if (name[len - 1] == ']')
19624 return ggc_alloc_string (name, len - 4);
19625 else
19626 return name;
19629 /* Section attributes. AIX is always PIC. */
19631 static unsigned int
19632 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
19634 unsigned int align;
19635 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
19637 /* Align to at least UNIT size. */
19638 if (flags & SECTION_CODE)
19639 align = MIN_UNITS_PER_WORD;
19640 else
19641 /* Increase alignment of large objects if not already stricter. */
19642 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
19643 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
19644 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
19646 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
19649 /* Output at beginning of assembler file.
19651 Initialize the section names for the RS/6000 at this point.
19653 Specify filename, including full path, to assembler.
19655 We want to go into the TOC section so at least one .toc will be emitted.
19656 Also, in order to output proper .bs/.es pairs, we need at least one static
19657 [RW] section emitted.
19659 Finally, declare mcount when profiling to make the assembler happy. */
19661 static void
19662 rs6000_xcoff_file_start (void)
19664 rs6000_gen_section_name (&xcoff_bss_section_name,
19665 main_input_filename, ".bss_");
19666 rs6000_gen_section_name (&xcoff_private_data_section_name,
19667 main_input_filename, ".rw_");
19668 rs6000_gen_section_name (&xcoff_read_only_section_name,
19669 main_input_filename, ".ro_");
19671 fputs ("\t.file\t", asm_out_file);
19672 output_quoted_string (asm_out_file, main_input_filename);
19673 fputc ('\n', asm_out_file);
19674 if (write_symbols != NO_DEBUG)
19675 switch_to_section (private_data_section);
19676 switch_to_section (text_section);
19677 if (profile_flag)
19678 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
19679 rs6000_file_start ();
19682 /* Output at end of assembler file.
19683 On the RS/6000, referencing data should automatically pull in text. */
19685 static void
19686 rs6000_xcoff_file_end (void)
19688 switch_to_section (text_section);
19689 fputs ("_section_.text:\n", asm_out_file);
19690 switch_to_section (data_section);
19691 fputs (TARGET_32BIT
19692 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
19693 asm_out_file);
19695 #endif /* TARGET_XCOFF */
19697 /* Compute a (partial) cost for rtx X. Return true if the complete
19698 cost has been computed, and false if subexpressions should be
19699 scanned. In either case, *TOTAL contains the cost result. */
19701 static bool
19702 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
19704 enum machine_mode mode = GET_MODE (x);
19706 switch (code)
19708 /* On the RS/6000, if it is valid in the insn, it is free. */
19709 case CONST_INT:
19710 if (((outer_code == SET
19711 || outer_code == PLUS
19712 || outer_code == MINUS)
19713 && (satisfies_constraint_I (x)
19714 || satisfies_constraint_L (x)))
19715 || (outer_code == AND
19716 && (satisfies_constraint_K (x)
19717 || (mode == SImode
19718 ? satisfies_constraint_L (x)
19719 : satisfies_constraint_J (x))
19720 || mask_operand (x, mode)
19721 || (mode == DImode
19722 && mask64_operand (x, DImode))))
19723 || ((outer_code == IOR || outer_code == XOR)
19724 && (satisfies_constraint_K (x)
19725 || (mode == SImode
19726 ? satisfies_constraint_L (x)
19727 : satisfies_constraint_J (x))))
19728 || outer_code == ASHIFT
19729 || outer_code == ASHIFTRT
19730 || outer_code == LSHIFTRT
19731 || outer_code == ROTATE
19732 || outer_code == ROTATERT
19733 || outer_code == ZERO_EXTRACT
19734 || (outer_code == MULT
19735 && satisfies_constraint_I (x))
19736 || ((outer_code == DIV || outer_code == UDIV
19737 || outer_code == MOD || outer_code == UMOD)
19738 && exact_log2 (INTVAL (x)) >= 0)
19739 || (outer_code == COMPARE
19740 && (satisfies_constraint_I (x)
19741 || satisfies_constraint_K (x)))
19742 || (outer_code == EQ
19743 && (satisfies_constraint_I (x)
19744 || satisfies_constraint_K (x)
19745 || (mode == SImode
19746 ? satisfies_constraint_L (x)
19747 : satisfies_constraint_J (x))))
19748 || (outer_code == GTU
19749 && satisfies_constraint_I (x))
19750 || (outer_code == LTU
19751 && satisfies_constraint_P (x)))
19753 *total = 0;
19754 return true;
19756 else if ((outer_code == PLUS
19757 && reg_or_add_cint_operand (x, VOIDmode))
19758 || (outer_code == MINUS
19759 && reg_or_sub_cint_operand (x, VOIDmode))
19760 || ((outer_code == SET
19761 || outer_code == IOR
19762 || outer_code == XOR)
19763 && (INTVAL (x)
19764 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
19766 *total = COSTS_N_INSNS (1);
19767 return true;
19769 /* FALLTHRU */
19771 case CONST_DOUBLE:
19772 if (mode == DImode && code == CONST_DOUBLE)
19774 if ((outer_code == IOR || outer_code == XOR)
19775 && CONST_DOUBLE_HIGH (x) == 0
19776 && (CONST_DOUBLE_LOW (x)
19777 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
19779 *total = 0;
19780 return true;
19782 else if ((outer_code == AND && and64_2_operand (x, DImode))
19783 || ((outer_code == SET
19784 || outer_code == IOR
19785 || outer_code == XOR)
19786 && CONST_DOUBLE_HIGH (x) == 0))
19788 *total = COSTS_N_INSNS (1);
19789 return true;
19792 /* FALLTHRU */
19794 case CONST:
19795 case HIGH:
19796 case SYMBOL_REF:
19797 case MEM:
19798 /* When optimizing for size, MEM should be slightly more expensive
19799 than generating address, e.g., (plus (reg) (const)).
19800 L1 cache latency is about two instructions. */
19801 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
19802 return true;
19804 case LABEL_REF:
19805 *total = 0;
19806 return true;
19808 case PLUS:
19809 if (mode == DFmode)
19811 if (GET_CODE (XEXP (x, 0)) == MULT)
19813 /* FNMA accounted in outer NEG. */
19814 if (outer_code == NEG)
19815 *total = rs6000_cost->dmul - rs6000_cost->fp;
19816 else
19817 *total = rs6000_cost->dmul;
19819 else
19820 *total = rs6000_cost->fp;
19822 else if (mode == SFmode)
19824 /* FNMA accounted in outer NEG. */
19825 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
19826 *total = 0;
19827 else
19828 *total = rs6000_cost->fp;
19830 else
19831 *total = COSTS_N_INSNS (1);
19832 return false;
19834 case MINUS:
19835 if (mode == DFmode)
19837 if (GET_CODE (XEXP (x, 0)) == MULT
19838 || GET_CODE (XEXP (x, 1)) == MULT)
19840 /* FNMA accounted in outer NEG. */
19841 if (outer_code == NEG)
19842 *total = rs6000_cost->dmul - rs6000_cost->fp;
19843 else
19844 *total = rs6000_cost->dmul;
19846 else
19847 *total = rs6000_cost->fp;
19849 else if (mode == SFmode)
19851 /* FNMA accounted in outer NEG. */
19852 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
19853 *total = 0;
19854 else
19855 *total = rs6000_cost->fp;
19857 else
19858 *total = COSTS_N_INSNS (1);
19859 return false;
19861 case MULT:
19862 if (GET_CODE (XEXP (x, 1)) == CONST_INT
19863 && satisfies_constraint_I (XEXP (x, 1)))
19865 if (INTVAL (XEXP (x, 1)) >= -256
19866 && INTVAL (XEXP (x, 1)) <= 255)
19867 *total = rs6000_cost->mulsi_const9;
19868 else
19869 *total = rs6000_cost->mulsi_const;
19871 /* FMA accounted in outer PLUS/MINUS. */
19872 else if ((mode == DFmode || mode == SFmode)
19873 && (outer_code == PLUS || outer_code == MINUS))
19874 *total = 0;
19875 else if (mode == DFmode)
19876 *total = rs6000_cost->dmul;
19877 else if (mode == SFmode)
19878 *total = rs6000_cost->fp;
19879 else if (mode == DImode)
19880 *total = rs6000_cost->muldi;
19881 else
19882 *total = rs6000_cost->mulsi;
19883 return false;
19885 case DIV:
19886 case MOD:
19887 if (FLOAT_MODE_P (mode))
19889 *total = mode == DFmode ? rs6000_cost->ddiv
19890 : rs6000_cost->sdiv;
19891 return false;
19893 /* FALLTHRU */
19895 case UDIV:
19896 case UMOD:
19897 if (GET_CODE (XEXP (x, 1)) == CONST_INT
19898 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
19900 if (code == DIV || code == MOD)
19901 /* Shift, addze */
19902 *total = COSTS_N_INSNS (2);
19903 else
19904 /* Shift */
19905 *total = COSTS_N_INSNS (1);
19907 else
19909 if (GET_MODE (XEXP (x, 1)) == DImode)
19910 *total = rs6000_cost->divdi;
19911 else
19912 *total = rs6000_cost->divsi;
19914 /* Add in shift and subtract for MOD. */
19915 if (code == MOD || code == UMOD)
19916 *total += COSTS_N_INSNS (2);
19917 return false;
19919 case FFS:
19920 *total = COSTS_N_INSNS (4);
19921 return false;
19923 case NOT:
19924 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
19926 *total = 0;
19927 return false;
19929 /* FALLTHRU */
19931 case AND:
19932 case IOR:
19933 case XOR:
19934 case ZERO_EXTRACT:
19935 *total = COSTS_N_INSNS (1);
19936 return false;
19938 case ASHIFT:
19939 case ASHIFTRT:
19940 case LSHIFTRT:
19941 case ROTATE:
19942 case ROTATERT:
19943 /* Handle mul_highpart. */
19944 if (outer_code == TRUNCATE
19945 && GET_CODE (XEXP (x, 0)) == MULT)
19947 if (mode == DImode)
19948 *total = rs6000_cost->muldi;
19949 else
19950 *total = rs6000_cost->mulsi;
19951 return true;
19953 else if (outer_code == AND)
19954 *total = 0;
19955 else
19956 *total = COSTS_N_INSNS (1);
19957 return false;
19959 case SIGN_EXTEND:
19960 case ZERO_EXTEND:
19961 if (GET_CODE (XEXP (x, 0)) == MEM)
19962 *total = 0;
19963 else
19964 *total = COSTS_N_INSNS (1);
19965 return false;
19967 case COMPARE:
19968 case NEG:
19969 case ABS:
19970 if (!FLOAT_MODE_P (mode))
19972 *total = COSTS_N_INSNS (1);
19973 return false;
19975 /* FALLTHRU */
19977 case FLOAT:
19978 case UNSIGNED_FLOAT:
19979 case FIX:
19980 case UNSIGNED_FIX:
19981 case FLOAT_TRUNCATE:
19982 *total = rs6000_cost->fp;
19983 return false;
19985 case FLOAT_EXTEND:
19986 if (mode == DFmode)
19987 *total = 0;
19988 else
19989 *total = rs6000_cost->fp;
19990 return false;
19992 case UNSPEC:
19993 switch (XINT (x, 1))
19995 case UNSPEC_FRSP:
19996 *total = rs6000_cost->fp;
19997 return true;
19999 default:
20000 break;
20002 break;
20004 case CALL:
20005 case IF_THEN_ELSE:
20006 if (optimize_size)
20008 *total = COSTS_N_INSNS (1);
20009 return true;
20011 else if (FLOAT_MODE_P (mode)
20012 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
20014 *total = rs6000_cost->fp;
20015 return false;
20017 break;
20019 case EQ:
20020 case GTU:
20021 case LTU:
20022 /* Carry bit requires mode == Pmode.
20023 NEG or PLUS already counted so only add one. */
20024 if (mode == Pmode
20025 && (outer_code == NEG || outer_code == PLUS))
20027 *total = COSTS_N_INSNS (1);
20028 return true;
20030 if (outer_code == SET)
20032 if (XEXP (x, 1) == const0_rtx)
20034 *total = COSTS_N_INSNS (2);
20035 return true;
20037 else if (mode == Pmode)
20039 *total = COSTS_N_INSNS (3);
20040 return false;
20043 /* FALLTHRU */
20045 case GT:
20046 case LT:
20047 case UNORDERED:
20048 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
20050 *total = COSTS_N_INSNS (2);
20051 return true;
20053 /* CC COMPARE. */
20054 if (outer_code == COMPARE)
20056 *total = 0;
20057 return true;
20059 break;
20061 default:
20062 break;
20065 return false;
20068 /* A C expression returning the cost of moving data from a register of class
20069 CLASS1 to one of CLASS2. */
20072 rs6000_register_move_cost (enum machine_mode mode,
20073 enum reg_class from, enum reg_class to)
20075 /* Moves from/to GENERAL_REGS. */
20076 if (reg_classes_intersect_p (to, GENERAL_REGS)
20077 || reg_classes_intersect_p (from, GENERAL_REGS))
20079 if (! reg_classes_intersect_p (to, GENERAL_REGS))
20080 from = to;
20082 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
20083 return (rs6000_memory_move_cost (mode, from, 0)
20084 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
20086 /* It's more expensive to move CR_REGS than CR0_REGS because of the
20087 shift. */
20088 else if (from == CR_REGS)
20089 return 4;
20091 else
20092 /* A move will cost one instruction per GPR moved. */
20093 return 2 * hard_regno_nregs[0][mode];
20096 /* Moving between two similar registers is just one instruction. */
20097 else if (reg_classes_intersect_p (to, from))
20098 return mode == TFmode ? 4 : 2;
20100 /* Everything else has to go through GENERAL_REGS. */
20101 else
20102 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
20103 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
20106 /* A C expressions returning the cost of moving data of MODE from a register to
20107 or from memory. */
20110 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
20111 int in ATTRIBUTE_UNUSED)
20113 if (reg_classes_intersect_p (class, GENERAL_REGS))
20114 return 4 * hard_regno_nregs[0][mode];
20115 else if (reg_classes_intersect_p (class, FLOAT_REGS))
20116 return 4 * hard_regno_nregs[32][mode];
20117 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
20118 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
20119 else
20120 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
20123 /* Newton-Raphson approximation of single-precision floating point divide n/d.
20124 Assumes no trapping math and finite arguments. */
20126 void
20127 rs6000_emit_swdivsf (rtx res, rtx n, rtx d)
20129 rtx x0, e0, e1, y1, u0, v0, one;
20131 x0 = gen_reg_rtx (SFmode);
20132 e0 = gen_reg_rtx (SFmode);
20133 e1 = gen_reg_rtx (SFmode);
20134 y1 = gen_reg_rtx (SFmode);
20135 u0 = gen_reg_rtx (SFmode);
20136 v0 = gen_reg_rtx (SFmode);
20137 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
20139 /* x0 = 1./d estimate */
20140 emit_insn (gen_rtx_SET (VOIDmode, x0,
20141 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
20142 UNSPEC_FRES)));
20143 /* e0 = 1. - d * x0 */
20144 emit_insn (gen_rtx_SET (VOIDmode, e0,
20145 gen_rtx_MINUS (SFmode, one,
20146 gen_rtx_MULT (SFmode, d, x0))));
20147 /* e1 = e0 + e0 * e0 */
20148 emit_insn (gen_rtx_SET (VOIDmode, e1,
20149 gen_rtx_PLUS (SFmode,
20150 gen_rtx_MULT (SFmode, e0, e0), e0)));
20151 /* y1 = x0 + e1 * x0 */
20152 emit_insn (gen_rtx_SET (VOIDmode, y1,
20153 gen_rtx_PLUS (SFmode,
20154 gen_rtx_MULT (SFmode, e1, x0), x0)));
20155 /* u0 = n * y1 */
20156 emit_insn (gen_rtx_SET (VOIDmode, u0,
20157 gen_rtx_MULT (SFmode, n, y1)));
20158 /* v0 = n - d * u0 */
20159 emit_insn (gen_rtx_SET (VOIDmode, v0,
20160 gen_rtx_MINUS (SFmode, n,
20161 gen_rtx_MULT (SFmode, d, u0))));
20162 /* res = u0 + v0 * y1 */
20163 emit_insn (gen_rtx_SET (VOIDmode, res,
20164 gen_rtx_PLUS (SFmode,
20165 gen_rtx_MULT (SFmode, v0, y1), u0)));
20168 /* Newton-Raphson approximation of double-precision floating point divide n/d.
20169 Assumes no trapping math and finite arguments. */
20171 void
20172 rs6000_emit_swdivdf (rtx res, rtx n, rtx d)
20174 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
20176 x0 = gen_reg_rtx (DFmode);
20177 e0 = gen_reg_rtx (DFmode);
20178 e1 = gen_reg_rtx (DFmode);
20179 e2 = gen_reg_rtx (DFmode);
20180 y1 = gen_reg_rtx (DFmode);
20181 y2 = gen_reg_rtx (DFmode);
20182 y3 = gen_reg_rtx (DFmode);
20183 u0 = gen_reg_rtx (DFmode);
20184 v0 = gen_reg_rtx (DFmode);
20185 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
20187 /* x0 = 1./d estimate */
20188 emit_insn (gen_rtx_SET (VOIDmode, x0,
20189 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
20190 UNSPEC_FRES)));
20191 /* e0 = 1. - d * x0 */
20192 emit_insn (gen_rtx_SET (VOIDmode, e0,
20193 gen_rtx_MINUS (DFmode, one,
20194 gen_rtx_MULT (SFmode, d, x0))));
20195 /* y1 = x0 + e0 * x0 */
20196 emit_insn (gen_rtx_SET (VOIDmode, y1,
20197 gen_rtx_PLUS (DFmode,
20198 gen_rtx_MULT (DFmode, e0, x0), x0)));
20199 /* e1 = e0 * e0 */
20200 emit_insn (gen_rtx_SET (VOIDmode, e1,
20201 gen_rtx_MULT (DFmode, e0, e0)));
20202 /* y2 = y1 + e1 * y1 */
20203 emit_insn (gen_rtx_SET (VOIDmode, y2,
20204 gen_rtx_PLUS (DFmode,
20205 gen_rtx_MULT (DFmode, e1, y1), y1)));
20206 /* e2 = e1 * e1 */
20207 emit_insn (gen_rtx_SET (VOIDmode, e2,
20208 gen_rtx_MULT (DFmode, e1, e1)));
20209 /* y3 = y2 + e2 * y2 */
20210 emit_insn (gen_rtx_SET (VOIDmode, y3,
20211 gen_rtx_PLUS (DFmode,
20212 gen_rtx_MULT (DFmode, e2, y2), y2)));
20213 /* u0 = n * y3 */
20214 emit_insn (gen_rtx_SET (VOIDmode, u0,
20215 gen_rtx_MULT (DFmode, n, y3)));
20216 /* v0 = n - d * u0 */
20217 emit_insn (gen_rtx_SET (VOIDmode, v0,
20218 gen_rtx_MINUS (DFmode, n,
20219 gen_rtx_MULT (DFmode, d, u0))));
20220 /* res = u0 + v0 * y3 */
20221 emit_insn (gen_rtx_SET (VOIDmode, res,
20222 gen_rtx_PLUS (DFmode,
20223 gen_rtx_MULT (DFmode, v0, y3), u0)));
20226 /* Return an RTX representing where to find the function value of a
20227 function returning MODE. */
20228 static rtx
20229 rs6000_complex_function_value (enum machine_mode mode)
20231 unsigned int regno;
20232 rtx r1, r2;
20233 enum machine_mode inner = GET_MODE_INNER (mode);
20234 unsigned int inner_bytes = GET_MODE_SIZE (inner);
20236 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
20237 regno = FP_ARG_RETURN;
20238 else
20240 regno = GP_ARG_RETURN;
20242 /* 32-bit is OK since it'll go in r3/r4. */
20243 if (TARGET_32BIT && inner_bytes >= 4)
20244 return gen_rtx_REG (mode, regno);
20247 if (inner_bytes >= 8)
20248 return gen_rtx_REG (mode, regno);
20250 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
20251 const0_rtx);
20252 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
20253 GEN_INT (inner_bytes));
20254 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
20257 /* Define how to find the value returned by a function.
20258 VALTYPE is the data type of the value (as a tree).
20259 If the precise function being called is known, FUNC is its FUNCTION_DECL;
20260 otherwise, FUNC is 0.
20262 On the SPE, both FPs and vectors are returned in r3.
20264 On RS/6000 an integer value is in r3 and a floating-point value is in
20265 fp1, unless -msoft-float. */
20268 rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
20270 enum machine_mode mode;
20271 unsigned int regno;
20273 /* Special handling for structs in darwin64. */
20274 if (rs6000_darwin64_abi
20275 && TYPE_MODE (valtype) == BLKmode
20276 && TREE_CODE (valtype) == RECORD_TYPE
20277 && int_size_in_bytes (valtype) > 0)
20279 CUMULATIVE_ARGS valcum;
20280 rtx valret;
20282 valcum.words = 0;
20283 valcum.fregno = FP_ARG_MIN_REG;
20284 valcum.vregno = ALTIVEC_ARG_MIN_REG;
20285 /* Do a trial code generation as if this were going to be passed as
20286 an argument; if any part goes in memory, we return NULL. */
20287 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
20288 if (valret)
20289 return valret;
20290 /* Otherwise fall through to standard ABI rules. */
20293 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
20295 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20296 return gen_rtx_PARALLEL (DImode,
20297 gen_rtvec (2,
20298 gen_rtx_EXPR_LIST (VOIDmode,
20299 gen_rtx_REG (SImode, GP_ARG_RETURN),
20300 const0_rtx),
20301 gen_rtx_EXPR_LIST (VOIDmode,
20302 gen_rtx_REG (SImode,
20303 GP_ARG_RETURN + 1),
20304 GEN_INT (4))));
20306 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
20308 return gen_rtx_PARALLEL (DCmode,
20309 gen_rtvec (4,
20310 gen_rtx_EXPR_LIST (VOIDmode,
20311 gen_rtx_REG (SImode, GP_ARG_RETURN),
20312 const0_rtx),
20313 gen_rtx_EXPR_LIST (VOIDmode,
20314 gen_rtx_REG (SImode,
20315 GP_ARG_RETURN + 1),
20316 GEN_INT (4)),
20317 gen_rtx_EXPR_LIST (VOIDmode,
20318 gen_rtx_REG (SImode,
20319 GP_ARG_RETURN + 2),
20320 GEN_INT (8)),
20321 gen_rtx_EXPR_LIST (VOIDmode,
20322 gen_rtx_REG (SImode,
20323 GP_ARG_RETURN + 3),
20324 GEN_INT (12))));
20327 if ((INTEGRAL_TYPE_P (valtype)
20328 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
20329 || POINTER_TYPE_P (valtype))
20330 mode = TARGET_32BIT ? SImode : DImode;
20331 else
20332 mode = TYPE_MODE (valtype);
20334 if (DECIMAL_FLOAT_MODE_P (mode))
20335 regno = GP_ARG_RETURN;
20336 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
20337 regno = FP_ARG_RETURN;
20338 else if (TREE_CODE (valtype) == COMPLEX_TYPE
20339 && targetm.calls.split_complex_arg)
20340 return rs6000_complex_function_value (mode);
20341 else if (TREE_CODE (valtype) == VECTOR_TYPE
20342 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
20343 && ALTIVEC_VECTOR_MODE (mode))
20344 regno = ALTIVEC_ARG_RETURN;
20345 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
20346 && (mode == DFmode || mode == DCmode
20347 || mode == TFmode || mode == TCmode))
20348 return spe_build_register_parallel (mode, GP_ARG_RETURN);
20349 else
20350 regno = GP_ARG_RETURN;
20352 return gen_rtx_REG (mode, regno);
20355 /* Define how to find the value returned by a library function
20356 assuming the value has mode MODE. */
20358 rs6000_libcall_value (enum machine_mode mode)
20360 unsigned int regno;
20362 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
20364 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20365 return gen_rtx_PARALLEL (DImode,
20366 gen_rtvec (2,
20367 gen_rtx_EXPR_LIST (VOIDmode,
20368 gen_rtx_REG (SImode, GP_ARG_RETURN),
20369 const0_rtx),
20370 gen_rtx_EXPR_LIST (VOIDmode,
20371 gen_rtx_REG (SImode,
20372 GP_ARG_RETURN + 1),
20373 GEN_INT (4))));
20376 if (DECIMAL_FLOAT_MODE_P (mode))
20377 regno = GP_ARG_RETURN;
20378 else if (SCALAR_FLOAT_MODE_P (mode)
20379 && TARGET_HARD_FLOAT && TARGET_FPRS)
20380 regno = FP_ARG_RETURN;
20381 else if (ALTIVEC_VECTOR_MODE (mode)
20382 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
20383 regno = ALTIVEC_ARG_RETURN;
20384 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
20385 return rs6000_complex_function_value (mode);
20386 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
20387 && (mode == DFmode || mode == DCmode
20388 || mode == TFmode || mode == TCmode))
20389 return spe_build_register_parallel (mode, GP_ARG_RETURN);
20390 else
20391 regno = GP_ARG_RETURN;
20393 return gen_rtx_REG (mode, regno);
20396 /* Define the offset between two registers, FROM to be eliminated and its
20397 replacement TO, at the start of a routine. */
20398 HOST_WIDE_INT
20399 rs6000_initial_elimination_offset (int from, int to)
20401 rs6000_stack_t *info = rs6000_stack_info ();
20402 HOST_WIDE_INT offset;
20404 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20405 offset = info->push_p ? 0 : -info->total_size;
20406 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20408 offset = info->push_p ? 0 : -info->total_size;
20409 if (FRAME_GROWS_DOWNWARD)
20410 offset += info->fixed_size + info->vars_size + info->parm_size;
20412 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
20413 offset = FRAME_GROWS_DOWNWARD
20414 ? info->fixed_size + info->vars_size + info->parm_size
20415 : 0;
20416 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
20417 offset = info->total_size;
20418 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20419 offset = info->push_p ? info->total_size : 0;
20420 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
20421 offset = 0;
20422 else
20423 gcc_unreachable ();
20425 return offset;
20428 /* Return true if TYPE is a SPE or AltiVec opaque type. */
20430 static bool
20431 rs6000_is_opaque_type (tree type)
20433 return (type == opaque_V2SI_type_node
20434 || type == opaque_V2SF_type_node
20435 || type == opaque_p_V2SI_type_node
20436 || type == opaque_V4SI_type_node);
20439 static rtx
20440 rs6000_dwarf_register_span (rtx reg)
20442 unsigned regno;
20444 if (TARGET_SPE
20445 && (SPE_VECTOR_MODE (GET_MODE (reg))
20446 || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
20448 else
20449 return NULL_RTX;
20451 regno = REGNO (reg);
20453 /* The duality of the SPE register size wreaks all kinds of havoc.
20454 This is a way of distinguishing r0 in 32-bits from r0 in
20455 64-bits. */
20456 return
20457 gen_rtx_PARALLEL (VOIDmode,
20458 BYTES_BIG_ENDIAN
20459 ? gen_rtvec (2,
20460 gen_rtx_REG (SImode, regno + 1200),
20461 gen_rtx_REG (SImode, regno))
20462 : gen_rtvec (2,
20463 gen_rtx_REG (SImode, regno),
20464 gen_rtx_REG (SImode, regno + 1200)));
20467 /* Map internal gcc register numbers to DWARF2 register numbers. */
20469 unsigned int
20470 rs6000_dbx_register_number (unsigned int regno)
20472 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
20473 return regno;
20474 if (regno == MQ_REGNO)
20475 return 100;
20476 if (regno == LINK_REGISTER_REGNUM)
20477 return 108;
20478 if (regno == COUNT_REGISTER_REGNUM)
20479 return 109;
20480 if (CR_REGNO_P (regno))
20481 return regno - CR0_REGNO + 86;
20482 if (regno == XER_REGNO)
20483 return 101;
20484 if (ALTIVEC_REGNO_P (regno))
20485 return regno - FIRST_ALTIVEC_REGNO + 1124;
20486 if (regno == VRSAVE_REGNO)
20487 return 356;
20488 if (regno == VSCR_REGNO)
20489 return 67;
20490 if (regno == SPE_ACC_REGNO)
20491 return 99;
20492 if (regno == SPEFSCR_REGNO)
20493 return 612;
20494 /* SPE high reg number. We get these values of regno from
20495 rs6000_dwarf_register_span. */
20496 gcc_assert (regno >= 1200 && regno < 1232);
20497 return regno;
20500 /* target hook eh_return_filter_mode */
20501 static enum machine_mode
20502 rs6000_eh_return_filter_mode (void)
20504 return TARGET_32BIT ? SImode : word_mode;
20507 /* Target hook for scalar_mode_supported_p. */
20508 static bool
20509 rs6000_scalar_mode_supported_p (enum machine_mode mode)
20511 if (DECIMAL_FLOAT_MODE_P (mode))
20512 return true;
20513 else
20514 return default_scalar_mode_supported_p (mode);
20517 /* Target hook for vector_mode_supported_p. */
20518 static bool
20519 rs6000_vector_mode_supported_p (enum machine_mode mode)
20522 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
20523 return true;
20525 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
20526 return true;
20528 else
20529 return false;
20532 /* Target hook for invalid_arg_for_unprototyped_fn. */
20533 static const char *
20534 invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
20536 return (!rs6000_darwin64_abi
20537 && typelist == 0
20538 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
20539 && (funcdecl == NULL_TREE
20540 || (TREE_CODE (funcdecl) == FUNCTION_DECL
20541 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
20542 ? N_("AltiVec argument passed to unprototyped function")
20543 : NULL;
20546 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
20547 setup by using __stack_chk_fail_local hidden function instead of
20548 calling __stack_chk_fail directly. Otherwise it is better to call
20549 __stack_chk_fail directly. */
20551 static tree
20552 rs6000_stack_protect_fail (void)
20554 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
20555 ? default_hidden_stack_protect_fail ()
20556 : default_external_stack_protect_fail ();
20559 #include "gt-rs6000.h"