tree.h (enum tree_code_class): Add tcc_vl_exp.
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blob5389c318cf4d8eba8bf85445f023607b81286a3e
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 (dep_t, 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);
719 static tree rs6000_builtin_conversion (enum tree_code, tree);
721 static void def_builtin (int, const char *, tree, int);
722 static void rs6000_init_builtins (void);
723 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
724 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
725 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
726 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
727 static void altivec_init_builtins (void);
728 static void rs6000_common_init_builtins (void);
729 static void rs6000_init_libfuncs (void);
731 static void enable_mask_for_builtins (struct builtin_description *, int,
732 enum rs6000_builtins,
733 enum rs6000_builtins);
734 static tree build_opaque_vector_type (tree, int);
735 static void spe_init_builtins (void);
736 static rtx spe_expand_builtin (tree, rtx, bool *);
737 static rtx spe_expand_stv_builtin (enum insn_code, tree);
738 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
739 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
740 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
741 static rs6000_stack_t *rs6000_stack_info (void);
742 static void debug_stack_info (rs6000_stack_t *);
744 static rtx altivec_expand_builtin (tree, rtx, bool *);
745 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
746 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
747 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
748 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
749 static rtx altivec_expand_predicate_builtin (enum insn_code,
750 const char *, tree, rtx);
751 static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
752 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
753 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
754 static rtx altivec_expand_vec_set_builtin (tree);
755 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
756 static int get_element_number (tree, tree);
757 static bool rs6000_handle_option (size_t, const char *, int);
758 static void rs6000_parse_tls_size_option (void);
759 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
760 static int first_altivec_reg_to_save (void);
761 static unsigned int compute_vrsave_mask (void);
762 static void compute_save_world_info (rs6000_stack_t *info_ptr);
763 static void is_altivec_return_reg (rtx, void *);
764 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
765 int easy_vector_constant (rtx, enum machine_mode);
766 static bool rs6000_is_opaque_type (tree);
767 static rtx rs6000_dwarf_register_span (rtx);
768 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
769 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
770 static rtx rs6000_tls_get_addr (void);
771 static rtx rs6000_got_sym (void);
772 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
773 static const char *rs6000_get_some_local_dynamic_name (void);
774 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
775 static rtx rs6000_complex_function_value (enum machine_mode);
776 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
777 enum machine_mode, tree);
778 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
779 HOST_WIDE_INT);
780 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
781 tree, HOST_WIDE_INT);
782 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
783 HOST_WIDE_INT,
784 rtx[], int *);
785 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
786 tree, HOST_WIDE_INT,
787 rtx[], int *);
788 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, tree, int, bool);
789 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
790 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
791 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
792 enum machine_mode, tree,
793 int *, int);
794 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
795 tree, bool);
796 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
797 tree, bool);
798 static const char *invalid_arg_for_unprototyped_fn (tree, tree, tree);
799 #if TARGET_MACHO
800 static void macho_branch_islands (void);
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
985 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
986 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
988 #undef TARGET_INIT_BUILTINS
989 #define TARGET_INIT_BUILTINS rs6000_init_builtins
991 #undef TARGET_EXPAND_BUILTIN
992 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
994 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
995 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
997 #undef TARGET_INIT_LIBFUNCS
998 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1000 #if TARGET_MACHO
1001 #undef TARGET_BINDS_LOCAL_P
1002 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1003 #endif
1005 #undef TARGET_MS_BITFIELD_LAYOUT_P
1006 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1008 #undef TARGET_ASM_OUTPUT_MI_THUNK
1009 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1011 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1012 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
1014 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1015 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1017 #undef TARGET_INVALID_WITHIN_DOLOOP
1018 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1020 #undef TARGET_RTX_COSTS
1021 #define TARGET_RTX_COSTS rs6000_rtx_costs
1022 #undef TARGET_ADDRESS_COST
1023 #define TARGET_ADDRESS_COST hook_int_rtx_0
1025 #undef TARGET_VECTOR_OPAQUE_P
1026 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
1028 #undef TARGET_DWARF_REGISTER_SPAN
1029 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1031 /* On rs6000, function arguments are promoted, as are function return
1032 values. */
1033 #undef TARGET_PROMOTE_FUNCTION_ARGS
1034 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
1035 #undef TARGET_PROMOTE_FUNCTION_RETURN
1036 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
1038 #undef TARGET_RETURN_IN_MEMORY
1039 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1041 #undef TARGET_SETUP_INCOMING_VARARGS
1042 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1044 /* Always strict argument naming on rs6000. */
1045 #undef TARGET_STRICT_ARGUMENT_NAMING
1046 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1047 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1048 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1049 #undef TARGET_SPLIT_COMPLEX_ARG
1050 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
1051 #undef TARGET_MUST_PASS_IN_STACK
1052 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1053 #undef TARGET_PASS_BY_REFERENCE
1054 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1055 #undef TARGET_ARG_PARTIAL_BYTES
1056 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1058 #undef TARGET_BUILD_BUILTIN_VA_LIST
1059 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1061 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1062 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1064 #undef TARGET_EH_RETURN_FILTER_MODE
1065 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1067 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1068 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1070 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1071 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1073 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1074 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1076 #undef TARGET_HANDLE_OPTION
1077 #define TARGET_HANDLE_OPTION rs6000_handle_option
1079 #undef TARGET_DEFAULT_TARGET_FLAGS
1080 #define TARGET_DEFAULT_TARGET_FLAGS \
1081 (TARGET_DEFAULT)
1083 #undef TARGET_STACK_PROTECT_FAIL
1084 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1086 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1087 The PowerPC architecture requires only weak consistency among
1088 processors--that is, memory accesses between processors need not be
1089 sequentially consistent and memory accesses among processors can occur
1090 in any order. The ability to order memory accesses weakly provides
1091 opportunities for more efficient use of the system bus. Unless a
1092 dependency exists, the 604e allows read operations to precede store
1093 operations. */
1094 #undef TARGET_RELAXED_ORDERING
1095 #define TARGET_RELAXED_ORDERING true
1097 #ifdef HAVE_AS_TLS
1098 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1099 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1100 #endif
1102 /* Use a 32-bit anchor range. This leads to sequences like:
1104 addis tmp,anchor,high
1105 add dest,tmp,low
1107 where tmp itself acts as an anchor, and can be shared between
1108 accesses to the same 64k page. */
1109 #undef TARGET_MIN_ANCHOR_OFFSET
1110 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1111 #undef TARGET_MAX_ANCHOR_OFFSET
1112 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1113 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1114 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1116 struct gcc_target targetm = TARGET_INITIALIZER;
1119 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1120 MODE. */
1121 static int
1122 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1124 /* The GPRs can hold any mode, but values bigger than one register
1125 cannot go past R31. */
1126 if (INT_REGNO_P (regno))
1127 return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
1129 /* The float registers can only hold floating modes and DImode.
1130 This also excludes decimal float modes. */
1131 if (FP_REGNO_P (regno))
1132 return
1133 (SCALAR_FLOAT_MODE_P (mode)
1134 && !DECIMAL_FLOAT_MODE_P (mode)
1135 && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
1136 || (GET_MODE_CLASS (mode) == MODE_INT
1137 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
1139 /* The CR register can only hold CC modes. */
1140 if (CR_REGNO_P (regno))
1141 return GET_MODE_CLASS (mode) == MODE_CC;
1143 if (XER_REGNO_P (regno))
1144 return mode == PSImode;
1146 /* AltiVec only in AldyVec registers. */
1147 if (ALTIVEC_REGNO_P (regno))
1148 return ALTIVEC_VECTOR_MODE (mode);
1150 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1151 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1152 return 1;
1154 /* We cannot put TImode anywhere except general register and it must be
1155 able to fit within the register set. */
1157 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1160 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1161 static void
1162 rs6000_init_hard_regno_mode_ok (void)
1164 int r, m;
1166 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1167 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1168 if (rs6000_hard_regno_mode_ok (r, m))
1169 rs6000_hard_regno_mode_ok_p[m][r] = true;
1172 /* If not otherwise specified by a target, make 'long double' equivalent to
1173 'double'. */
1175 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1176 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1177 #endif
1179 /* Override command line options. Mostly we process the processor
1180 type and sometimes adjust other TARGET_ options. */
1182 void
1183 rs6000_override_options (const char *default_cpu)
1185 size_t i, j;
1186 struct rs6000_cpu_select *ptr;
1187 int set_masks;
1189 /* Simplifications for entries below. */
1191 enum {
1192 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1193 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1196 /* This table occasionally claims that a processor does not support
1197 a particular feature even though it does, but the feature is slower
1198 than the alternative. Thus, it shouldn't be relied on as a
1199 complete description of the processor's support.
1201 Please keep this list in order, and don't forget to update the
1202 documentation in invoke.texi when adding a new processor or
1203 flag. */
1204 static struct ptt
1206 const char *const name; /* Canonical processor name. */
1207 const enum processor_type processor; /* Processor type enum value. */
1208 const int target_enable; /* Target flags to enable. */
1209 } const processor_target_table[]
1210 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1211 {"403", PROCESSOR_PPC403,
1212 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1213 {"405", PROCESSOR_PPC405,
1214 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1215 {"405fp", PROCESSOR_PPC405,
1216 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1217 {"440", PROCESSOR_PPC440,
1218 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1219 {"440fp", PROCESSOR_PPC440,
1220 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1221 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1222 {"601", PROCESSOR_PPC601,
1223 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1224 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1225 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1226 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1227 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1228 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1229 {"620", PROCESSOR_PPC620,
1230 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1231 {"630", PROCESSOR_PPC630,
1232 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1233 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1234 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1235 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1236 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1237 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1238 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1239 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1240 {"8540", PROCESSOR_PPC8540,
1241 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_STRICT_ALIGN},
1242 /* 8548 has a dummy entry for now. */
1243 {"8548", PROCESSOR_PPC8540,
1244 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_STRICT_ALIGN},
1245 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1246 {"970", PROCESSOR_POWER4,
1247 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1248 {"cell", PROCESSOR_CELL,
1249 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1250 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1251 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1252 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1253 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1254 {"G5", PROCESSOR_POWER4,
1255 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1256 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1257 {"power2", PROCESSOR_POWER,
1258 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1259 {"power3", PROCESSOR_PPC630,
1260 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1261 {"power4", PROCESSOR_POWER4,
1262 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
1263 {"power5", PROCESSOR_POWER5,
1264 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1265 | MASK_MFCRF | MASK_POPCNTB},
1266 {"power5+", PROCESSOR_POWER5,
1267 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1268 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1269 {"power6", PROCESSOR_POWER6,
1270 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
1271 | MASK_FPRND},
1272 {"power6x", PROCESSOR_POWER6,
1273 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
1274 | MASK_FPRND | MASK_MFPGPR},
1275 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1276 {"powerpc64", PROCESSOR_POWERPC64,
1277 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1278 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1279 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1280 {"rios2", PROCESSOR_RIOS2,
1281 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1282 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1283 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1284 {"rs64", PROCESSOR_RS64A,
1285 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1288 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
1290 /* Some OSs don't support saving the high part of 64-bit registers on
1291 context switch. Other OSs don't support saving Altivec registers.
1292 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1293 settings; if the user wants either, the user must explicitly specify
1294 them and we won't interfere with the user's specification. */
1296 enum {
1297 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1298 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1299 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1300 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1301 | MASK_DLMZB | MASK_MFPGPR)
1304 rs6000_init_hard_regno_mode_ok ();
1306 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
1307 #ifdef OS_MISSING_POWERPC64
1308 if (OS_MISSING_POWERPC64)
1309 set_masks &= ~MASK_POWERPC64;
1310 #endif
1311 #ifdef OS_MISSING_ALTIVEC
1312 if (OS_MISSING_ALTIVEC)
1313 set_masks &= ~MASK_ALTIVEC;
1314 #endif
1316 /* Don't override by the processor default if given explicitly. */
1317 set_masks &= ~target_flags_explicit;
1319 /* Identify the processor type. */
1320 rs6000_select[0].string = default_cpu;
1321 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
1323 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
1325 ptr = &rs6000_select[i];
1326 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
1328 for (j = 0; j < ptt_size; j++)
1329 if (! strcmp (ptr->string, processor_target_table[j].name))
1331 if (ptr->set_tune_p)
1332 rs6000_cpu = processor_target_table[j].processor;
1334 if (ptr->set_arch_p)
1336 target_flags &= ~set_masks;
1337 target_flags |= (processor_target_table[j].target_enable
1338 & set_masks);
1340 break;
1343 if (j == ptt_size)
1344 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
1348 if (TARGET_E500)
1349 rs6000_isel = 1;
1351 /* If we are optimizing big endian systems for space, use the load/store
1352 multiple and string instructions. */
1353 if (BYTES_BIG_ENDIAN && optimize_size)
1354 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
1356 /* Don't allow -mmultiple or -mstring on little endian systems
1357 unless the cpu is a 750, because the hardware doesn't support the
1358 instructions used in little endian mode, and causes an alignment
1359 trap. The 750 does not cause an alignment trap (except when the
1360 target is unaligned). */
1362 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
1364 if (TARGET_MULTIPLE)
1366 target_flags &= ~MASK_MULTIPLE;
1367 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
1368 warning (0, "-mmultiple is not supported on little endian systems");
1371 if (TARGET_STRING)
1373 target_flags &= ~MASK_STRING;
1374 if ((target_flags_explicit & MASK_STRING) != 0)
1375 warning (0, "-mstring is not supported on little endian systems");
1379 /* Set debug flags */
1380 if (rs6000_debug_name)
1382 if (! strcmp (rs6000_debug_name, "all"))
1383 rs6000_debug_stack = rs6000_debug_arg = 1;
1384 else if (! strcmp (rs6000_debug_name, "stack"))
1385 rs6000_debug_stack = 1;
1386 else if (! strcmp (rs6000_debug_name, "arg"))
1387 rs6000_debug_arg = 1;
1388 else
1389 error ("unknown -mdebug-%s switch", rs6000_debug_name);
1392 if (rs6000_traceback_name)
1394 if (! strncmp (rs6000_traceback_name, "full", 4))
1395 rs6000_traceback = traceback_full;
1396 else if (! strncmp (rs6000_traceback_name, "part", 4))
1397 rs6000_traceback = traceback_part;
1398 else if (! strncmp (rs6000_traceback_name, "no", 2))
1399 rs6000_traceback = traceback_none;
1400 else
1401 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1402 rs6000_traceback_name);
1405 if (!rs6000_explicit_options.long_double)
1406 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1408 #ifndef POWERPC_LINUX
1409 if (!rs6000_explicit_options.ieee)
1410 rs6000_ieeequad = 1;
1411 #endif
1413 /* Set Altivec ABI as default for powerpc64 linux. */
1414 if (TARGET_ELF && TARGET_64BIT)
1416 rs6000_altivec_abi = 1;
1417 TARGET_ALTIVEC_VRSAVE = 1;
1420 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1421 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1423 rs6000_darwin64_abi = 1;
1424 #if TARGET_MACHO
1425 darwin_one_byte_bool = 1;
1426 #endif
1427 /* Default to natural alignment, for better performance. */
1428 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
1431 /* Place FP constants in the constant pool instead of TOC
1432 if section anchors enabled. */
1433 if (flag_section_anchors)
1434 TARGET_NO_FP_IN_TOC = 1;
1436 /* Handle -mtls-size option. */
1437 rs6000_parse_tls_size_option ();
1439 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1440 SUBTARGET_OVERRIDE_OPTIONS;
1441 #endif
1442 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1443 SUBSUBTARGET_OVERRIDE_OPTIONS;
1444 #endif
1445 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1446 SUB3TARGET_OVERRIDE_OPTIONS;
1447 #endif
1449 if (TARGET_E500)
1451 /* The e500 does not have string instructions, and we set
1452 MASK_STRING above when optimizing for size. */
1453 if ((target_flags & MASK_STRING) != 0)
1454 target_flags = target_flags & ~MASK_STRING;
1456 else if (rs6000_select[1].string != NULL)
1458 /* For the powerpc-eabispe configuration, we set all these by
1459 default, so let's unset them if we manually set another
1460 CPU that is not the E500. */
1461 if (!rs6000_explicit_options.abi)
1462 rs6000_spe_abi = 0;
1463 if (!rs6000_explicit_options.spe)
1464 rs6000_spe = 0;
1465 if (!rs6000_explicit_options.float_gprs)
1466 rs6000_float_gprs = 0;
1467 if (!rs6000_explicit_options.isel)
1468 rs6000_isel = 0;
1471 /* Detect invalid option combinations with E500. */
1472 CHECK_E500_OPTIONS;
1474 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
1475 && rs6000_cpu != PROCESSOR_POWER5
1476 && rs6000_cpu != PROCESSOR_POWER6
1477 && rs6000_cpu != PROCESSOR_CELL);
1478 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
1479 || rs6000_cpu == PROCESSOR_POWER5);
1480 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
1481 || rs6000_cpu == PROCESSOR_POWER5
1482 || rs6000_cpu == PROCESSOR_POWER6);
1484 rs6000_sched_restricted_insns_priority
1485 = (rs6000_sched_groups ? 1 : 0);
1487 /* Handle -msched-costly-dep option. */
1488 rs6000_sched_costly_dep
1489 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
1491 if (rs6000_sched_costly_dep_str)
1493 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
1494 rs6000_sched_costly_dep = no_dep_costly;
1495 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
1496 rs6000_sched_costly_dep = all_deps_costly;
1497 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
1498 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
1499 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
1500 rs6000_sched_costly_dep = store_to_load_dep_costly;
1501 else
1502 rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
1505 /* Handle -minsert-sched-nops option. */
1506 rs6000_sched_insert_nops
1507 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
1509 if (rs6000_sched_insert_nops_str)
1511 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
1512 rs6000_sched_insert_nops = sched_finish_none;
1513 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
1514 rs6000_sched_insert_nops = sched_finish_pad_groups;
1515 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
1516 rs6000_sched_insert_nops = sched_finish_regroup_exact;
1517 else
1518 rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
1521 #ifdef TARGET_REGNAMES
1522 /* If the user desires alternate register names, copy in the
1523 alternate names now. */
1524 if (TARGET_REGNAMES)
1525 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
1526 #endif
1528 /* Set aix_struct_return last, after the ABI is determined.
1529 If -maix-struct-return or -msvr4-struct-return was explicitly
1530 used, don't override with the ABI default. */
1531 if (!rs6000_explicit_options.aix_struct_ret)
1532 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
1534 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
1535 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
1537 if (TARGET_TOC)
1538 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
1540 /* We can only guarantee the availability of DI pseudo-ops when
1541 assembling for 64-bit targets. */
1542 if (!TARGET_64BIT)
1544 targetm.asm_out.aligned_op.di = NULL;
1545 targetm.asm_out.unaligned_op.di = NULL;
1548 /* Set branch target alignment, if not optimizing for size. */
1549 if (!optimize_size)
1551 /* Cell wants to be aligned 8byte for dual issue. */
1552 if (rs6000_cpu == PROCESSOR_CELL)
1554 if (align_functions <= 0)
1555 align_functions = 8;
1556 if (align_jumps <= 0)
1557 align_jumps = 8;
1558 if (align_loops <= 0)
1559 align_loops = 8;
1561 if (rs6000_align_branch_targets)
1563 if (align_functions <= 0)
1564 align_functions = 16;
1565 if (align_jumps <= 0)
1566 align_jumps = 16;
1567 if (align_loops <= 0)
1568 align_loops = 16;
1570 if (align_jumps_max_skip <= 0)
1571 align_jumps_max_skip = 15;
1572 if (align_loops_max_skip <= 0)
1573 align_loops_max_skip = 15;
1576 /* Arrange to save and restore machine status around nested functions. */
1577 init_machine_status = rs6000_init_machine_status;
1579 /* We should always be splitting complex arguments, but we can't break
1580 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1581 if (DEFAULT_ABI != ABI_AIX)
1582 targetm.calls.split_complex_arg = NULL;
1584 /* Initialize rs6000_cost with the appropriate target costs. */
1585 if (optimize_size)
1586 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
1587 else
1588 switch (rs6000_cpu)
1590 case PROCESSOR_RIOS1:
1591 rs6000_cost = &rios1_cost;
1592 break;
1594 case PROCESSOR_RIOS2:
1595 rs6000_cost = &rios2_cost;
1596 break;
1598 case PROCESSOR_RS64A:
1599 rs6000_cost = &rs64a_cost;
1600 break;
1602 case PROCESSOR_MPCCORE:
1603 rs6000_cost = &mpccore_cost;
1604 break;
1606 case PROCESSOR_PPC403:
1607 rs6000_cost = &ppc403_cost;
1608 break;
1610 case PROCESSOR_PPC405:
1611 rs6000_cost = &ppc405_cost;
1612 break;
1614 case PROCESSOR_PPC440:
1615 rs6000_cost = &ppc440_cost;
1616 break;
1618 case PROCESSOR_PPC601:
1619 rs6000_cost = &ppc601_cost;
1620 break;
1622 case PROCESSOR_PPC603:
1623 rs6000_cost = &ppc603_cost;
1624 break;
1626 case PROCESSOR_PPC604:
1627 rs6000_cost = &ppc604_cost;
1628 break;
1630 case PROCESSOR_PPC604e:
1631 rs6000_cost = &ppc604e_cost;
1632 break;
1634 case PROCESSOR_PPC620:
1635 rs6000_cost = &ppc620_cost;
1636 break;
1638 case PROCESSOR_PPC630:
1639 rs6000_cost = &ppc630_cost;
1640 break;
1642 case PROCESSOR_CELL:
1643 rs6000_cost = &ppccell_cost;
1644 break;
1646 case PROCESSOR_PPC750:
1647 case PROCESSOR_PPC7400:
1648 rs6000_cost = &ppc750_cost;
1649 break;
1651 case PROCESSOR_PPC7450:
1652 rs6000_cost = &ppc7450_cost;
1653 break;
1655 case PROCESSOR_PPC8540:
1656 rs6000_cost = &ppc8540_cost;
1657 break;
1659 case PROCESSOR_POWER4:
1660 case PROCESSOR_POWER5:
1661 rs6000_cost = &power4_cost;
1662 break;
1664 case PROCESSOR_POWER6:
1665 rs6000_cost = &power6_cost;
1666 break;
1668 default:
1669 gcc_unreachable ();
1673 /* Implement targetm.vectorize.builtin_mask_for_load. */
1674 static tree
1675 rs6000_builtin_mask_for_load (void)
1677 if (TARGET_ALTIVEC)
1678 return altivec_builtin_mask_for_load;
1679 else
1680 return 0;
1683 /* Implement targetm.vectorize.builtin_conversion. */
1684 static tree
1685 rs6000_builtin_conversion (enum tree_code code, tree type)
1687 if (!TARGET_ALTIVEC)
1688 return NULL_TREE;
1690 switch (code)
1692 case FLOAT_EXPR:
1693 switch (TYPE_MODE (type))
1695 case V4SImode:
1696 return TYPE_UNSIGNED (type) ?
1697 rs6000_builtin_decls[ALTIVEC_BUILTIN_VCFUX] :
1698 rs6000_builtin_decls[ALTIVEC_BUILTIN_VCFSX];
1699 default:
1700 return NULL_TREE;
1702 default:
1703 return NULL_TREE;
1707 /* Implement targetm.vectorize.builtin_mul_widen_even. */
1708 static tree
1709 rs6000_builtin_mul_widen_even (tree type)
1711 if (!TARGET_ALTIVEC)
1712 return NULL_TREE;
1714 switch (TYPE_MODE (type))
1716 case V8HImode:
1717 return TYPE_UNSIGNED (type) ?
1718 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH] :
1719 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
1721 case V16QImode:
1722 return TYPE_UNSIGNED (type) ?
1723 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB] :
1724 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
1725 default:
1726 return NULL_TREE;
1730 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
1731 static tree
1732 rs6000_builtin_mul_widen_odd (tree type)
1734 if (!TARGET_ALTIVEC)
1735 return NULL_TREE;
1737 switch (TYPE_MODE (type))
1739 case V8HImode:
1740 return TYPE_UNSIGNED (type) ?
1741 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH] :
1742 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
1744 case V16QImode:
1745 return TYPE_UNSIGNED (type) ?
1746 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB] :
1747 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
1748 default:
1749 return NULL_TREE;
1753 /* Handle generic options of the form -mfoo=yes/no.
1754 NAME is the option name.
1755 VALUE is the option value.
1756 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1757 whether the option value is 'yes' or 'no' respectively. */
1758 static void
1759 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
1761 if (value == 0)
1762 return;
1763 else if (!strcmp (value, "yes"))
1764 *flag = 1;
1765 else if (!strcmp (value, "no"))
1766 *flag = 0;
1767 else
1768 error ("unknown -m%s= option specified: '%s'", name, value);
1771 /* Validate and record the size specified with the -mtls-size option. */
1773 static void
1774 rs6000_parse_tls_size_option (void)
1776 if (rs6000_tls_size_string == 0)
1777 return;
1778 else if (strcmp (rs6000_tls_size_string, "16") == 0)
1779 rs6000_tls_size = 16;
1780 else if (strcmp (rs6000_tls_size_string, "32") == 0)
1781 rs6000_tls_size = 32;
1782 else if (strcmp (rs6000_tls_size_string, "64") == 0)
1783 rs6000_tls_size = 64;
1784 else
1785 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
1788 void
1789 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1791 if (DEFAULT_ABI == ABI_DARWIN)
1792 /* The Darwin libraries never set errno, so we might as well
1793 avoid calling them when that's the only reason we would. */
1794 flag_errno_math = 0;
1796 /* Double growth factor to counter reduced min jump length. */
1797 set_param_value ("max-grow-copy-bb-insns", 16);
1799 /* Enable section anchors by default.
1800 Skip section anchors for Objective C and Objective C++
1801 until front-ends fixed. */
1802 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
1803 flag_section_anchors = 1;
1806 /* Implement TARGET_HANDLE_OPTION. */
1808 static bool
1809 rs6000_handle_option (size_t code, const char *arg, int value)
1811 switch (code)
1813 case OPT_mno_power:
1814 target_flags &= ~(MASK_POWER | MASK_POWER2
1815 | MASK_MULTIPLE | MASK_STRING);
1816 target_flags_explicit |= (MASK_POWER | MASK_POWER2
1817 | MASK_MULTIPLE | MASK_STRING);
1818 break;
1819 case OPT_mno_powerpc:
1820 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
1821 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1822 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
1823 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1824 break;
1825 case OPT_mfull_toc:
1826 target_flags &= ~MASK_MINIMAL_TOC;
1827 TARGET_NO_FP_IN_TOC = 0;
1828 TARGET_NO_SUM_IN_TOC = 0;
1829 target_flags_explicit |= MASK_MINIMAL_TOC;
1830 #ifdef TARGET_USES_SYSV4_OPT
1831 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1832 just the same as -mminimal-toc. */
1833 target_flags |= MASK_MINIMAL_TOC;
1834 target_flags_explicit |= MASK_MINIMAL_TOC;
1835 #endif
1836 break;
1838 #ifdef TARGET_USES_SYSV4_OPT
1839 case OPT_mtoc:
1840 /* Make -mtoc behave like -mminimal-toc. */
1841 target_flags |= MASK_MINIMAL_TOC;
1842 target_flags_explicit |= MASK_MINIMAL_TOC;
1843 break;
1844 #endif
1846 #ifdef TARGET_USES_AIX64_OPT
1847 case OPT_maix64:
1848 #else
1849 case OPT_m64:
1850 #endif
1851 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
1852 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
1853 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
1854 break;
1856 #ifdef TARGET_USES_AIX64_OPT
1857 case OPT_maix32:
1858 #else
1859 case OPT_m32:
1860 #endif
1861 target_flags &= ~MASK_POWERPC64;
1862 target_flags_explicit |= MASK_POWERPC64;
1863 break;
1865 case OPT_minsert_sched_nops_:
1866 rs6000_sched_insert_nops_str = arg;
1867 break;
1869 case OPT_mminimal_toc:
1870 if (value == 1)
1872 TARGET_NO_FP_IN_TOC = 0;
1873 TARGET_NO_SUM_IN_TOC = 0;
1875 break;
1877 case OPT_mpower:
1878 if (value == 1)
1880 target_flags |= (MASK_MULTIPLE | MASK_STRING);
1881 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
1883 break;
1885 case OPT_mpower2:
1886 if (value == 1)
1888 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1889 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1891 break;
1893 case OPT_mpowerpc_gpopt:
1894 case OPT_mpowerpc_gfxopt:
1895 if (value == 1)
1897 target_flags |= MASK_POWERPC;
1898 target_flags_explicit |= MASK_POWERPC;
1900 break;
1902 case OPT_maix_struct_return:
1903 case OPT_msvr4_struct_return:
1904 rs6000_explicit_options.aix_struct_ret = true;
1905 break;
1907 case OPT_mvrsave_:
1908 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
1909 break;
1911 case OPT_misel_:
1912 rs6000_explicit_options.isel = true;
1913 rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
1914 break;
1916 case OPT_mspe_:
1917 rs6000_explicit_options.spe = true;
1918 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
1919 break;
1921 case OPT_mdebug_:
1922 rs6000_debug_name = arg;
1923 break;
1925 #ifdef TARGET_USES_SYSV4_OPT
1926 case OPT_mcall_:
1927 rs6000_abi_name = arg;
1928 break;
1930 case OPT_msdata_:
1931 rs6000_sdata_name = arg;
1932 break;
1934 case OPT_mtls_size_:
1935 rs6000_tls_size_string = arg;
1936 break;
1938 case OPT_mrelocatable:
1939 if (value == 1)
1941 target_flags |= MASK_MINIMAL_TOC;
1942 target_flags_explicit |= MASK_MINIMAL_TOC;
1943 TARGET_NO_FP_IN_TOC = 1;
1945 break;
1947 case OPT_mrelocatable_lib:
1948 if (value == 1)
1950 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
1951 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
1952 TARGET_NO_FP_IN_TOC = 1;
1954 else
1956 target_flags &= ~MASK_RELOCATABLE;
1957 target_flags_explicit |= MASK_RELOCATABLE;
1959 break;
1960 #endif
1962 case OPT_mabi_:
1963 if (!strcmp (arg, "altivec"))
1965 rs6000_explicit_options.abi = true;
1966 rs6000_altivec_abi = 1;
1967 rs6000_spe_abi = 0;
1969 else if (! strcmp (arg, "no-altivec"))
1971 /* ??? Don't set rs6000_explicit_options.abi here, to allow
1972 the default for rs6000_spe_abi to be chosen later. */
1973 rs6000_altivec_abi = 0;
1975 else if (! strcmp (arg, "spe"))
1977 rs6000_explicit_options.abi = true;
1978 rs6000_spe_abi = 1;
1979 rs6000_altivec_abi = 0;
1980 if (!TARGET_SPE_ABI)
1981 error ("not configured for ABI: '%s'", arg);
1983 else if (! strcmp (arg, "no-spe"))
1985 rs6000_explicit_options.abi = true;
1986 rs6000_spe_abi = 0;
1989 /* These are here for testing during development only, do not
1990 document in the manual please. */
1991 else if (! strcmp (arg, "d64"))
1993 rs6000_darwin64_abi = 1;
1994 warning (0, "Using darwin64 ABI");
1996 else if (! strcmp (arg, "d32"))
1998 rs6000_darwin64_abi = 0;
1999 warning (0, "Using old darwin ABI");
2002 else if (! strcmp (arg, "ibmlongdouble"))
2004 rs6000_explicit_options.ieee = true;
2005 rs6000_ieeequad = 0;
2006 warning (0, "Using IBM extended precision long double");
2008 else if (! strcmp (arg, "ieeelongdouble"))
2010 rs6000_explicit_options.ieee = true;
2011 rs6000_ieeequad = 1;
2012 warning (0, "Using IEEE extended precision long double");
2015 else
2017 error ("unknown ABI specified: '%s'", arg);
2018 return false;
2020 break;
2022 case OPT_mcpu_:
2023 rs6000_select[1].string = arg;
2024 break;
2026 case OPT_mtune_:
2027 rs6000_select[2].string = arg;
2028 break;
2030 case OPT_mtraceback_:
2031 rs6000_traceback_name = arg;
2032 break;
2034 case OPT_mfloat_gprs_:
2035 rs6000_explicit_options.float_gprs = true;
2036 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
2037 rs6000_float_gprs = 1;
2038 else if (! strcmp (arg, "double"))
2039 rs6000_float_gprs = 2;
2040 else if (! strcmp (arg, "no"))
2041 rs6000_float_gprs = 0;
2042 else
2044 error ("invalid option for -mfloat-gprs: '%s'", arg);
2045 return false;
2047 break;
2049 case OPT_mlong_double_:
2050 rs6000_explicit_options.long_double = true;
2051 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2052 if (value != 64 && value != 128)
2054 error ("Unknown switch -mlong-double-%s", arg);
2055 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2056 return false;
2058 else
2059 rs6000_long_double_type_size = value;
2060 break;
2062 case OPT_msched_costly_dep_:
2063 rs6000_sched_costly_dep_str = arg;
2064 break;
2066 case OPT_malign_:
2067 rs6000_explicit_options.alignment = true;
2068 if (! strcmp (arg, "power"))
2070 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2071 some C library functions, so warn about it. The flag may be
2072 useful for performance studies from time to time though, so
2073 don't disable it entirely. */
2074 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2075 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2076 " it is incompatible with the installed C and C++ libraries");
2077 rs6000_alignment_flags = MASK_ALIGN_POWER;
2079 else if (! strcmp (arg, "natural"))
2080 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2081 else
2083 error ("unknown -malign-XXXXX option specified: '%s'", arg);
2084 return false;
2086 break;
2088 return true;
2091 /* Do anything needed at the start of the asm file. */
2093 static void
2094 rs6000_file_start (void)
2096 size_t i;
2097 char buffer[80];
2098 const char *start = buffer;
2099 struct rs6000_cpu_select *ptr;
2100 const char *default_cpu = TARGET_CPU_DEFAULT;
2101 FILE *file = asm_out_file;
2103 default_file_start ();
2105 #ifdef TARGET_BI_ARCH
2106 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
2107 default_cpu = 0;
2108 #endif
2110 if (flag_verbose_asm)
2112 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
2113 rs6000_select[0].string = default_cpu;
2115 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2117 ptr = &rs6000_select[i];
2118 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2120 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
2121 start = "";
2125 if (PPC405_ERRATUM77)
2127 fprintf (file, "%s PPC405CR_ERRATUM77", start);
2128 start = "";
2131 #ifdef USING_ELFOS_H
2132 switch (rs6000_sdata)
2134 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
2135 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
2136 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
2137 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
2140 if (rs6000_sdata && g_switch_value)
2142 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
2143 g_switch_value);
2144 start = "";
2146 #endif
2148 if (*start == '\0')
2149 putc ('\n', file);
2152 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
2154 switch_to_section (toc_section);
2155 switch_to_section (text_section);
2160 /* Return nonzero if this function is known to have a null epilogue. */
2163 direct_return (void)
2165 if (reload_completed)
2167 rs6000_stack_t *info = rs6000_stack_info ();
2169 if (info->first_gp_reg_save == 32
2170 && info->first_fp_reg_save == 64
2171 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
2172 && ! info->lr_save_p
2173 && ! info->cr_save_p
2174 && info->vrsave_mask == 0
2175 && ! info->push_p)
2176 return 1;
2179 return 0;
2182 /* Return the number of instructions it takes to form a constant in an
2183 integer register. */
2186 num_insns_constant_wide (HOST_WIDE_INT value)
2188 /* signed constant loadable with {cal|addi} */
2189 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
2190 return 1;
2192 /* constant loadable with {cau|addis} */
2193 else if ((value & 0xffff) == 0
2194 && (value >> 31 == -1 || value >> 31 == 0))
2195 return 1;
2197 #if HOST_BITS_PER_WIDE_INT == 64
2198 else if (TARGET_POWERPC64)
2200 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
2201 HOST_WIDE_INT high = value >> 31;
2203 if (high == 0 || high == -1)
2204 return 2;
2206 high >>= 1;
2208 if (low == 0)
2209 return num_insns_constant_wide (high) + 1;
2210 else
2211 return (num_insns_constant_wide (high)
2212 + num_insns_constant_wide (low) + 1);
2214 #endif
2216 else
2217 return 2;
2221 num_insns_constant (rtx op, enum machine_mode mode)
2223 HOST_WIDE_INT low, high;
2225 switch (GET_CODE (op))
2227 case CONST_INT:
2228 #if HOST_BITS_PER_WIDE_INT == 64
2229 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
2230 && mask64_operand (op, mode))
2231 return 2;
2232 else
2233 #endif
2234 return num_insns_constant_wide (INTVAL (op));
2236 case CONST_DOUBLE:
2237 if (mode == SFmode)
2239 long l;
2240 REAL_VALUE_TYPE rv;
2242 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2243 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
2244 return num_insns_constant_wide ((HOST_WIDE_INT) l);
2247 if (mode == VOIDmode || mode == DImode)
2249 high = CONST_DOUBLE_HIGH (op);
2250 low = CONST_DOUBLE_LOW (op);
2252 else
2254 long l[2];
2255 REAL_VALUE_TYPE rv;
2257 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2258 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
2259 high = l[WORDS_BIG_ENDIAN == 0];
2260 low = l[WORDS_BIG_ENDIAN != 0];
2263 if (TARGET_32BIT)
2264 return (num_insns_constant_wide (low)
2265 + num_insns_constant_wide (high));
2266 else
2268 if ((high == 0 && low >= 0)
2269 || (high == -1 && low < 0))
2270 return num_insns_constant_wide (low);
2272 else if (mask64_operand (op, mode))
2273 return 2;
2275 else if (low == 0)
2276 return num_insns_constant_wide (high) + 1;
2278 else
2279 return (num_insns_constant_wide (high)
2280 + num_insns_constant_wide (low) + 1);
2283 default:
2284 gcc_unreachable ();
2288 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2289 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2290 corresponding element of the vector, but for V4SFmode and V2SFmode,
2291 the corresponding "float" is interpreted as an SImode integer. */
2293 static HOST_WIDE_INT
2294 const_vector_elt_as_int (rtx op, unsigned int elt)
2296 rtx tmp = CONST_VECTOR_ELT (op, elt);
2297 if (GET_MODE (op) == V4SFmode
2298 || GET_MODE (op) == V2SFmode)
2299 tmp = gen_lowpart (SImode, tmp);
2300 return INTVAL (tmp);
2303 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2304 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2305 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2306 all items are set to the same value and contain COPIES replicas of the
2307 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2308 operand and the others are set to the value of the operand's msb. */
2310 static bool
2311 vspltis_constant (rtx op, unsigned step, unsigned copies)
2313 enum machine_mode mode = GET_MODE (op);
2314 enum machine_mode inner = GET_MODE_INNER (mode);
2316 unsigned i;
2317 unsigned nunits = GET_MODE_NUNITS (mode);
2318 unsigned bitsize = GET_MODE_BITSIZE (inner);
2319 unsigned mask = GET_MODE_MASK (inner);
2321 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
2322 HOST_WIDE_INT splat_val = val;
2323 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
2325 /* Construct the value to be splatted, if possible. If not, return 0. */
2326 for (i = 2; i <= copies; i *= 2)
2328 HOST_WIDE_INT small_val;
2329 bitsize /= 2;
2330 small_val = splat_val >> bitsize;
2331 mask >>= bitsize;
2332 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
2333 return false;
2334 splat_val = small_val;
2337 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2338 if (EASY_VECTOR_15 (splat_val))
2341 /* Also check if we can splat, and then add the result to itself. Do so if
2342 the value is positive, of if the splat instruction is using OP's mode;
2343 for splat_val < 0, the splat and the add should use the same mode. */
2344 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
2345 && (splat_val >= 0 || (step == 1 && copies == 1)))
2348 else
2349 return false;
2351 /* Check if VAL is present in every STEP-th element, and the
2352 other elements are filled with its most significant bit. */
2353 for (i = 0; i < nunits - 1; ++i)
2355 HOST_WIDE_INT desired_val;
2356 if (((i + 1) & (step - 1)) == 0)
2357 desired_val = val;
2358 else
2359 desired_val = msb_val;
2361 if (desired_val != const_vector_elt_as_int (op, i))
2362 return false;
2365 return true;
2369 /* Return true if OP is of the given MODE and can be synthesized
2370 with a vspltisb, vspltish or vspltisw. */
2372 bool
2373 easy_altivec_constant (rtx op, enum machine_mode mode)
2375 unsigned step, copies;
2377 if (mode == VOIDmode)
2378 mode = GET_MODE (op);
2379 else if (mode != GET_MODE (op))
2380 return false;
2382 /* Start with a vspltisw. */
2383 step = GET_MODE_NUNITS (mode) / 4;
2384 copies = 1;
2386 if (vspltis_constant (op, step, copies))
2387 return true;
2389 /* Then try with a vspltish. */
2390 if (step == 1)
2391 copies <<= 1;
2392 else
2393 step >>= 1;
2395 if (vspltis_constant (op, step, copies))
2396 return true;
2398 /* And finally a vspltisb. */
2399 if (step == 1)
2400 copies <<= 1;
2401 else
2402 step >>= 1;
2404 if (vspltis_constant (op, step, copies))
2405 return true;
2407 return false;
2410 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2411 result is OP. Abort if it is not possible. */
2414 gen_easy_altivec_constant (rtx op)
2416 enum machine_mode mode = GET_MODE (op);
2417 int nunits = GET_MODE_NUNITS (mode);
2418 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
2419 unsigned step = nunits / 4;
2420 unsigned copies = 1;
2422 /* Start with a vspltisw. */
2423 if (vspltis_constant (op, step, copies))
2424 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
2426 /* Then try with a vspltish. */
2427 if (step == 1)
2428 copies <<= 1;
2429 else
2430 step >>= 1;
2432 if (vspltis_constant (op, step, copies))
2433 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
2435 /* And finally a vspltisb. */
2436 if (step == 1)
2437 copies <<= 1;
2438 else
2439 step >>= 1;
2441 if (vspltis_constant (op, step, copies))
2442 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
2444 gcc_unreachable ();
2447 const char *
2448 output_vec_const_move (rtx *operands)
2450 int cst, cst2;
2451 enum machine_mode mode;
2452 rtx dest, vec;
2454 dest = operands[0];
2455 vec = operands[1];
2456 mode = GET_MODE (dest);
2458 if (TARGET_ALTIVEC)
2460 rtx splat_vec;
2461 if (zero_constant (vec, mode))
2462 return "vxor %0,%0,%0";
2464 splat_vec = gen_easy_altivec_constant (vec);
2465 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
2466 operands[1] = XEXP (splat_vec, 0);
2467 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
2468 return "#";
2470 switch (GET_MODE (splat_vec))
2472 case V4SImode:
2473 return "vspltisw %0,%1";
2475 case V8HImode:
2476 return "vspltish %0,%1";
2478 case V16QImode:
2479 return "vspltisb %0,%1";
2481 default:
2482 gcc_unreachable ();
2486 gcc_assert (TARGET_SPE);
2488 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2489 pattern of V1DI, V4HI, and V2SF.
2491 FIXME: We should probably return # and add post reload
2492 splitters for these, but this way is so easy ;-). */
2493 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
2494 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
2495 operands[1] = CONST_VECTOR_ELT (vec, 0);
2496 operands[2] = CONST_VECTOR_ELT (vec, 1);
2497 if (cst == cst2)
2498 return "li %0,%1\n\tevmergelo %0,%0,%0";
2499 else
2500 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2503 /* Initialize vector TARGET to VALS. */
2505 void
2506 rs6000_expand_vector_init (rtx target, rtx vals)
2508 enum machine_mode mode = GET_MODE (target);
2509 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2510 int n_elts = GET_MODE_NUNITS (mode);
2511 int n_var = 0, one_var = -1;
2512 bool all_same = true, all_const_zero = true;
2513 rtx x, mem;
2514 int i;
2516 for (i = 0; i < n_elts; ++i)
2518 x = XVECEXP (vals, 0, i);
2519 if (!CONSTANT_P (x))
2520 ++n_var, one_var = i;
2521 else if (x != CONST0_RTX (inner_mode))
2522 all_const_zero = false;
2524 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
2525 all_same = false;
2528 if (n_var == 0)
2530 if (mode != V4SFmode && all_const_zero)
2532 /* Zero register. */
2533 emit_insn (gen_rtx_SET (VOIDmode, target,
2534 gen_rtx_XOR (mode, target, target)));
2535 return;
2537 else if (mode != V4SFmode && easy_vector_constant (vals, mode))
2539 /* Splat immediate. */
2540 emit_insn (gen_rtx_SET (VOIDmode, target, vals));
2541 return;
2543 else if (all_same)
2544 ; /* Splat vector element. */
2545 else
2547 /* Load from constant pool. */
2548 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
2549 return;
2553 /* Store value to stack temp. Load vector element. Splat. */
2554 if (all_same)
2556 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2557 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
2558 XVECEXP (vals, 0, 0));
2559 x = gen_rtx_UNSPEC (VOIDmode,
2560 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2561 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2562 gen_rtvec (2,
2563 gen_rtx_SET (VOIDmode,
2564 target, mem),
2565 x)));
2566 x = gen_rtx_VEC_SELECT (inner_mode, target,
2567 gen_rtx_PARALLEL (VOIDmode,
2568 gen_rtvec (1, const0_rtx)));
2569 emit_insn (gen_rtx_SET (VOIDmode, target,
2570 gen_rtx_VEC_DUPLICATE (mode, x)));
2571 return;
2574 /* One field is non-constant. Load constant then overwrite
2575 varying field. */
2576 if (n_var == 1)
2578 rtx copy = copy_rtx (vals);
2580 /* Load constant part of vector, substitute neighboring value for
2581 varying element. */
2582 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
2583 rs6000_expand_vector_init (target, copy);
2585 /* Insert variable. */
2586 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
2587 return;
2590 /* Construct the vector in memory one field at a time
2591 and load the whole vector. */
2592 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2593 for (i = 0; i < n_elts; i++)
2594 emit_move_insn (adjust_address_nv (mem, inner_mode,
2595 i * GET_MODE_SIZE (inner_mode)),
2596 XVECEXP (vals, 0, i));
2597 emit_move_insn (target, mem);
2600 /* Set field ELT of TARGET to VAL. */
2602 void
2603 rs6000_expand_vector_set (rtx target, rtx val, int elt)
2605 enum machine_mode mode = GET_MODE (target);
2606 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2607 rtx reg = gen_reg_rtx (mode);
2608 rtx mask, mem, x;
2609 int width = GET_MODE_SIZE (inner_mode);
2610 int i;
2612 /* Load single variable value. */
2613 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2614 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
2615 x = gen_rtx_UNSPEC (VOIDmode,
2616 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2617 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2618 gen_rtvec (2,
2619 gen_rtx_SET (VOIDmode,
2620 reg, mem),
2621 x)));
2623 /* Linear sequence. */
2624 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
2625 for (i = 0; i < 16; ++i)
2626 XVECEXP (mask, 0, i) = GEN_INT (i);
2628 /* Set permute mask to insert element into target. */
2629 for (i = 0; i < width; ++i)
2630 XVECEXP (mask, 0, elt*width + i)
2631 = GEN_INT (i + 0x10);
2632 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
2633 x = gen_rtx_UNSPEC (mode,
2634 gen_rtvec (3, target, reg,
2635 force_reg (V16QImode, x)),
2636 UNSPEC_VPERM);
2637 emit_insn (gen_rtx_SET (VOIDmode, target, x));
2640 /* Extract field ELT from VEC into TARGET. */
2642 void
2643 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
2645 enum machine_mode mode = GET_MODE (vec);
2646 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2647 rtx mem, x;
2649 /* Allocate mode-sized buffer. */
2650 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2652 /* Add offset to field within buffer matching vector element. */
2653 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
2655 /* Store single field into mode-sized buffer. */
2656 x = gen_rtx_UNSPEC (VOIDmode,
2657 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
2658 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2659 gen_rtvec (2,
2660 gen_rtx_SET (VOIDmode,
2661 mem, vec),
2662 x)));
2663 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
2666 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2667 implement ANDing by the mask IN. */
2668 void
2669 build_mask64_2_operands (rtx in, rtx *out)
2671 #if HOST_BITS_PER_WIDE_INT >= 64
2672 unsigned HOST_WIDE_INT c, lsb, m1, m2;
2673 int shift;
2675 gcc_assert (GET_CODE (in) == CONST_INT);
2677 c = INTVAL (in);
2678 if (c & 1)
2680 /* Assume c initially something like 0x00fff000000fffff. The idea
2681 is to rotate the word so that the middle ^^^^^^ group of zeros
2682 is at the MS end and can be cleared with an rldicl mask. We then
2683 rotate back and clear off the MS ^^ group of zeros with a
2684 second rldicl. */
2685 c = ~c; /* c == 0xff000ffffff00000 */
2686 lsb = c & -c; /* lsb == 0x0000000000100000 */
2687 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
2688 c = ~c; /* c == 0x00fff000000fffff */
2689 c &= -lsb; /* c == 0x00fff00000000000 */
2690 lsb = c & -c; /* lsb == 0x0000100000000000 */
2691 c = ~c; /* c == 0xff000fffffffffff */
2692 c &= -lsb; /* c == 0xff00000000000000 */
2693 shift = 0;
2694 while ((lsb >>= 1) != 0)
2695 shift++; /* shift == 44 on exit from loop */
2696 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
2697 m1 = ~m1; /* m1 == 0x000000ffffffffff */
2698 m2 = ~c; /* m2 == 0x00ffffffffffffff */
2700 else
2702 /* Assume c initially something like 0xff000f0000000000. The idea
2703 is to rotate the word so that the ^^^ middle group of zeros
2704 is at the LS end and can be cleared with an rldicr mask. We then
2705 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2706 a second rldicr. */
2707 lsb = c & -c; /* lsb == 0x0000010000000000 */
2708 m2 = -lsb; /* m2 == 0xffffff0000000000 */
2709 c = ~c; /* c == 0x00fff0ffffffffff */
2710 c &= -lsb; /* c == 0x00fff00000000000 */
2711 lsb = c & -c; /* lsb == 0x0000100000000000 */
2712 c = ~c; /* c == 0xff000fffffffffff */
2713 c &= -lsb; /* c == 0xff00000000000000 */
2714 shift = 0;
2715 while ((lsb >>= 1) != 0)
2716 shift++; /* shift == 44 on exit from loop */
2717 m1 = ~c; /* m1 == 0x00ffffffffffffff */
2718 m1 >>= shift; /* m1 == 0x0000000000000fff */
2719 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
2722 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2723 masks will be all 1's. We are guaranteed more than one transition. */
2724 out[0] = GEN_INT (64 - shift);
2725 out[1] = GEN_INT (m1);
2726 out[2] = GEN_INT (shift);
2727 out[3] = GEN_INT (m2);
2728 #else
2729 (void)in;
2730 (void)out;
2731 gcc_unreachable ();
2732 #endif
2735 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2737 bool
2738 invalid_e500_subreg (rtx op, enum machine_mode mode)
2740 if (TARGET_E500_DOUBLE)
2742 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
2743 subreg:TI and reg:TF. */
2744 if (GET_CODE (op) == SUBREG
2745 && (mode == SImode || mode == DImode || mode == TImode)
2746 && REG_P (SUBREG_REG (op))
2747 && (GET_MODE (SUBREG_REG (op)) == DFmode
2748 || GET_MODE (SUBREG_REG (op)) == TFmode))
2749 return true;
2751 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
2752 reg:TI. */
2753 if (GET_CODE (op) == SUBREG
2754 && (mode == DFmode || mode == TFmode)
2755 && REG_P (SUBREG_REG (op))
2756 && (GET_MODE (SUBREG_REG (op)) == DImode
2757 || GET_MODE (SUBREG_REG (op)) == TImode))
2758 return true;
2761 if (TARGET_SPE
2762 && GET_CODE (op) == SUBREG
2763 && mode == SImode
2764 && REG_P (SUBREG_REG (op))
2765 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
2766 return true;
2768 return false;
2771 /* AIX increases natural record alignment to doubleword if the first
2772 field is an FP double while the FP fields remain word aligned. */
2774 unsigned int
2775 rs6000_special_round_type_align (tree type, unsigned int computed,
2776 unsigned int specified)
2778 unsigned int align = MAX (computed, specified);
2779 tree field = TYPE_FIELDS (type);
2781 /* Skip all non field decls */
2782 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
2783 field = TREE_CHAIN (field);
2785 if (field != NULL && field != type)
2787 type = TREE_TYPE (field);
2788 while (TREE_CODE (type) == ARRAY_TYPE)
2789 type = TREE_TYPE (type);
2791 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
2792 align = MAX (align, 64);
2795 return align;
2798 /* Darwin increases record alignment to the natural alignment of
2799 the first field. */
2801 unsigned int
2802 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
2803 unsigned int specified)
2805 unsigned int align = MAX (computed, specified);
2807 if (TYPE_PACKED (type))
2808 return align;
2810 /* Find the first field, looking down into aggregates. */
2811 do {
2812 tree field = TYPE_FIELDS (type);
2813 /* Skip all non field decls */
2814 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
2815 field = TREE_CHAIN (field);
2816 if (! field)
2817 break;
2818 type = TREE_TYPE (field);
2819 while (TREE_CODE (type) == ARRAY_TYPE)
2820 type = TREE_TYPE (type);
2821 } while (AGGREGATE_TYPE_P (type));
2823 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
2824 align = MAX (align, TYPE_ALIGN (type));
2826 return align;
2829 /* Return 1 for an operand in small memory on V.4/eabi. */
2832 small_data_operand (rtx op ATTRIBUTE_UNUSED,
2833 enum machine_mode mode ATTRIBUTE_UNUSED)
2835 #if TARGET_ELF
2836 rtx sym_ref;
2838 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
2839 return 0;
2841 if (DEFAULT_ABI != ABI_V4)
2842 return 0;
2844 if (GET_CODE (op) == SYMBOL_REF)
2845 sym_ref = op;
2847 else if (GET_CODE (op) != CONST
2848 || GET_CODE (XEXP (op, 0)) != PLUS
2849 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2850 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
2851 return 0;
2853 else
2855 rtx sum = XEXP (op, 0);
2856 HOST_WIDE_INT summand;
2858 /* We have to be careful here, because it is the referenced address
2859 that must be 32k from _SDA_BASE_, not just the symbol. */
2860 summand = INTVAL (XEXP (sum, 1));
2861 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
2862 return 0;
2864 sym_ref = XEXP (sum, 0);
2867 return SYMBOL_REF_SMALL_P (sym_ref);
2868 #else
2869 return 0;
2870 #endif
2873 /* Return true if either operand is a general purpose register. */
2875 bool
2876 gpr_or_gpr_p (rtx op0, rtx op1)
2878 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
2879 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
2883 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2885 static int
2886 constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
2888 switch (GET_CODE (op))
2890 case SYMBOL_REF:
2891 if (RS6000_SYMBOL_REF_TLS_P (op))
2892 return 0;
2893 else if (CONSTANT_POOL_ADDRESS_P (op))
2895 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2897 *have_sym = 1;
2898 return 1;
2900 else
2901 return 0;
2903 else if (! strcmp (XSTR (op, 0), toc_label_name))
2905 *have_toc = 1;
2906 return 1;
2908 else
2909 return 0;
2910 case PLUS:
2911 case MINUS:
2912 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2913 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
2914 case CONST:
2915 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
2916 case CONST_INT:
2917 return 1;
2918 default:
2919 return 0;
2923 static bool
2924 constant_pool_expr_p (rtx op)
2926 int have_sym = 0;
2927 int have_toc = 0;
2928 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2931 bool
2932 toc_relative_expr_p (rtx op)
2934 int have_sym = 0;
2935 int have_toc = 0;
2936 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2939 bool
2940 legitimate_constant_pool_address_p (rtx x)
2942 return (TARGET_TOC
2943 && GET_CODE (x) == PLUS
2944 && GET_CODE (XEXP (x, 0)) == REG
2945 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
2946 && constant_pool_expr_p (XEXP (x, 1)));
2949 static bool
2950 legitimate_small_data_p (enum machine_mode mode, rtx x)
2952 return (DEFAULT_ABI == ABI_V4
2953 && !flag_pic && !TARGET_TOC
2954 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
2955 && small_data_operand (x, mode));
2958 /* SPE offset addressing is limited to 5-bits worth of double words. */
2959 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2961 bool
2962 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
2964 unsigned HOST_WIDE_INT offset, extra;
2966 if (GET_CODE (x) != PLUS)
2967 return false;
2968 if (GET_CODE (XEXP (x, 0)) != REG)
2969 return false;
2970 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2971 return false;
2972 if (legitimate_constant_pool_address_p (x))
2973 return true;
2974 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2975 return false;
2977 offset = INTVAL (XEXP (x, 1));
2978 extra = 0;
2979 switch (mode)
2981 case V16QImode:
2982 case V8HImode:
2983 case V4SFmode:
2984 case V4SImode:
2985 /* AltiVec vector modes. Only reg+reg addressing is valid and
2986 constant offset zero should not occur due to canonicalization.
2987 Allow any offset when not strict before reload. */
2988 return !strict;
2990 case V4HImode:
2991 case V2SImode:
2992 case V1DImode:
2993 case V2SFmode:
2994 /* SPE vector modes. */
2995 return SPE_CONST_OFFSET_OK (offset);
2997 case DFmode:
2998 if (TARGET_E500_DOUBLE)
2999 return SPE_CONST_OFFSET_OK (offset);
3001 case DImode:
3002 /* On e500v2, we may have:
3004 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3006 Which gets addressed with evldd instructions. */
3007 if (TARGET_E500_DOUBLE)
3008 return SPE_CONST_OFFSET_OK (offset);
3010 if (mode == DFmode || !TARGET_POWERPC64)
3011 extra = 4;
3012 else if (offset & 3)
3013 return false;
3014 break;
3016 case TFmode:
3017 if (TARGET_E500_DOUBLE)
3018 return (SPE_CONST_OFFSET_OK (offset)
3019 && SPE_CONST_OFFSET_OK (offset + 8));
3021 case TImode:
3022 if (mode == TFmode || !TARGET_POWERPC64)
3023 extra = 12;
3024 else if (offset & 3)
3025 return false;
3026 else
3027 extra = 8;
3028 break;
3030 default:
3031 break;
3034 offset += 0x8000;
3035 return (offset < 0x10000) && (offset + extra < 0x10000);
3038 static bool
3039 legitimate_indexed_address_p (rtx x, int strict)
3041 rtx op0, op1;
3043 if (GET_CODE (x) != PLUS)
3044 return false;
3046 op0 = XEXP (x, 0);
3047 op1 = XEXP (x, 1);
3049 /* Recognize the rtl generated by reload which we know will later be
3050 replaced with proper base and index regs. */
3051 if (!strict
3052 && reload_in_progress
3053 && (REG_P (op0) || GET_CODE (op0) == PLUS)
3054 && REG_P (op1))
3055 return true;
3057 return (REG_P (op0) && REG_P (op1)
3058 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
3059 && INT_REG_OK_FOR_INDEX_P (op1, strict))
3060 || (INT_REG_OK_FOR_BASE_P (op1, strict)
3061 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
3064 inline bool
3065 legitimate_indirect_address_p (rtx x, int strict)
3067 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
3070 bool
3071 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
3073 if (!TARGET_MACHO || !flag_pic
3074 || mode != SImode || GET_CODE (x) != MEM)
3075 return false;
3076 x = XEXP (x, 0);
3078 if (GET_CODE (x) != LO_SUM)
3079 return false;
3080 if (GET_CODE (XEXP (x, 0)) != REG)
3081 return false;
3082 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
3083 return false;
3084 x = XEXP (x, 1);
3086 return CONSTANT_P (x);
3089 static bool
3090 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
3092 if (GET_CODE (x) != LO_SUM)
3093 return false;
3094 if (GET_CODE (XEXP (x, 0)) != REG)
3095 return false;
3096 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
3097 return false;
3098 /* Restrict addressing for DI because of our SUBREG hackery. */
3099 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3100 || mode == DImode))
3101 return false;
3102 x = XEXP (x, 1);
3104 if (TARGET_ELF || TARGET_MACHO)
3106 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
3107 return false;
3108 if (TARGET_TOC)
3109 return false;
3110 if (GET_MODE_NUNITS (mode) != 1)
3111 return false;
3112 if (GET_MODE_BITSIZE (mode) > 64
3113 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
3114 && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode)))
3115 return false;
3117 return CONSTANT_P (x);
3120 return false;
3124 /* Try machine-dependent ways of modifying an illegitimate address
3125 to be legitimate. If we find one, return the new, valid address.
3126 This is used from only one place: `memory_address' in explow.c.
3128 OLDX is the address as it was before break_out_memory_refs was
3129 called. In some cases it is useful to look at this to decide what
3130 needs to be done.
3132 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3134 It is always safe for this function to do nothing. It exists to
3135 recognize opportunities to optimize the output.
3137 On RS/6000, first check for the sum of a register with a constant
3138 integer that is out of range. If so, generate code to add the
3139 constant with the low-order 16 bits masked to the register and force
3140 this result into another register (this can be done with `cau').
3141 Then generate an address of REG+(CONST&0xffff), allowing for the
3142 possibility of bit 16 being a one.
3144 Then check for the sum of a register and something not constant, try to
3145 load the other things into a register and return the sum. */
3148 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3149 enum machine_mode mode)
3151 if (GET_CODE (x) == SYMBOL_REF)
3153 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
3154 if (model != 0)
3155 return rs6000_legitimize_tls_address (x, model);
3158 if (GET_CODE (x) == PLUS
3159 && GET_CODE (XEXP (x, 0)) == REG
3160 && GET_CODE (XEXP (x, 1)) == CONST_INT
3161 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
3163 HOST_WIDE_INT high_int, low_int;
3164 rtx sum;
3165 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3166 high_int = INTVAL (XEXP (x, 1)) - low_int;
3167 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
3168 GEN_INT (high_int)), 0);
3169 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
3171 else if (GET_CODE (x) == PLUS
3172 && GET_CODE (XEXP (x, 0)) == REG
3173 && GET_CODE (XEXP (x, 1)) != CONST_INT
3174 && GET_MODE_NUNITS (mode) == 1
3175 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3176 || TARGET_POWERPC64
3177 || (((mode != DImode && mode != DFmode) || TARGET_E500_DOUBLE)
3178 && mode != TFmode))
3179 && (TARGET_POWERPC64 || mode != DImode)
3180 && mode != TImode)
3182 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
3183 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
3185 else if (ALTIVEC_VECTOR_MODE (mode))
3187 rtx reg;
3189 /* Make sure both operands are registers. */
3190 if (GET_CODE (x) == PLUS)
3191 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
3192 force_reg (Pmode, XEXP (x, 1)));
3194 reg = force_reg (Pmode, x);
3195 return reg;
3197 else if (SPE_VECTOR_MODE (mode)
3198 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3199 || mode == DImode)))
3201 if (mode == DImode)
3202 return NULL_RTX;
3203 /* We accept [reg + reg] and [reg + OFFSET]. */
3205 if (GET_CODE (x) == PLUS)
3207 rtx op1 = XEXP (x, 0);
3208 rtx op2 = XEXP (x, 1);
3210 op1 = force_reg (Pmode, op1);
3212 if (GET_CODE (op2) != REG
3213 && (GET_CODE (op2) != CONST_INT
3214 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
3215 op2 = force_reg (Pmode, op2);
3217 return gen_rtx_PLUS (Pmode, op1, op2);
3220 return force_reg (Pmode, x);
3222 else if (TARGET_ELF
3223 && TARGET_32BIT
3224 && TARGET_NO_TOC
3225 && ! flag_pic
3226 && GET_CODE (x) != CONST_INT
3227 && GET_CODE (x) != CONST_DOUBLE
3228 && CONSTANT_P (x)
3229 && GET_MODE_NUNITS (mode) == 1
3230 && (GET_MODE_BITSIZE (mode) <= 32
3231 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
3233 rtx reg = gen_reg_rtx (Pmode);
3234 emit_insn (gen_elf_high (reg, x));
3235 return gen_rtx_LO_SUM (Pmode, reg, x);
3237 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
3238 && ! flag_pic
3239 #if TARGET_MACHO
3240 && ! MACHO_DYNAMIC_NO_PIC_P
3241 #endif
3242 && GET_CODE (x) != CONST_INT
3243 && GET_CODE (x) != CONST_DOUBLE
3244 && CONSTANT_P (x)
3245 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
3246 && mode != DImode
3247 && mode != TImode)
3249 rtx reg = gen_reg_rtx (Pmode);
3250 emit_insn (gen_macho_high (reg, x));
3251 return gen_rtx_LO_SUM (Pmode, reg, x);
3253 else if (TARGET_TOC
3254 && constant_pool_expr_p (x)
3255 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
3257 return create_TOC_reference (x);
3259 else
3260 return NULL_RTX;
3263 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3264 We need to emit DTP-relative relocations. */
3266 static void
3267 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
3269 switch (size)
3271 case 4:
3272 fputs ("\t.long\t", file);
3273 break;
3274 case 8:
3275 fputs (DOUBLE_INT_ASM_OP, file);
3276 break;
3277 default:
3278 gcc_unreachable ();
3280 output_addr_const (file, x);
3281 fputs ("@dtprel+0x8000", file);
3284 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3286 static GTY(()) rtx rs6000_tls_symbol;
3287 static rtx
3288 rs6000_tls_get_addr (void)
3290 if (!rs6000_tls_symbol)
3291 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
3293 return rs6000_tls_symbol;
3296 /* Construct the SYMBOL_REF for TLS GOT references. */
3298 static GTY(()) rtx rs6000_got_symbol;
3299 static rtx
3300 rs6000_got_sym (void)
3302 if (!rs6000_got_symbol)
3304 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
3305 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
3306 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
3309 return rs6000_got_symbol;
3312 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3313 this (thread-local) address. */
3315 static rtx
3316 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
3318 rtx dest, insn;
3320 dest = gen_reg_rtx (Pmode);
3321 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
3323 rtx tlsreg;
3325 if (TARGET_64BIT)
3327 tlsreg = gen_rtx_REG (Pmode, 13);
3328 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
3330 else
3332 tlsreg = gen_rtx_REG (Pmode, 2);
3333 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
3335 emit_insn (insn);
3337 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
3339 rtx tlsreg, tmp;
3341 tmp = gen_reg_rtx (Pmode);
3342 if (TARGET_64BIT)
3344 tlsreg = gen_rtx_REG (Pmode, 13);
3345 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
3347 else
3349 tlsreg = gen_rtx_REG (Pmode, 2);
3350 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
3352 emit_insn (insn);
3353 if (TARGET_64BIT)
3354 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
3355 else
3356 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
3357 emit_insn (insn);
3359 else
3361 rtx r3, got, tga, tmp1, tmp2, eqv;
3363 /* We currently use relocations like @got@tlsgd for tls, which
3364 means the linker will handle allocation of tls entries, placing
3365 them in the .got section. So use a pointer to the .got section,
3366 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3367 or to secondary GOT sections used by 32-bit -fPIC. */
3368 if (TARGET_64BIT)
3369 got = gen_rtx_REG (Pmode, 2);
3370 else
3372 if (flag_pic == 1)
3373 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
3374 else
3376 rtx gsym = rs6000_got_sym ();
3377 got = gen_reg_rtx (Pmode);
3378 if (flag_pic == 0)
3379 rs6000_emit_move (got, gsym, Pmode);
3380 else
3382 rtx tempLR, tmp3, mem;
3383 rtx first, last;
3385 tempLR = gen_reg_rtx (Pmode);
3386 tmp1 = gen_reg_rtx (Pmode);
3387 tmp2 = gen_reg_rtx (Pmode);
3388 tmp3 = gen_reg_rtx (Pmode);
3389 mem = gen_const_mem (Pmode, tmp1);
3391 first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, gsym));
3392 emit_move_insn (tmp1, tempLR);
3393 emit_move_insn (tmp2, mem);
3394 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
3395 last = emit_move_insn (got, tmp3);
3396 set_unique_reg_note (last, REG_EQUAL, gsym);
3397 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3398 REG_NOTES (first));
3399 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3400 REG_NOTES (last));
3405 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
3407 r3 = gen_rtx_REG (Pmode, 3);
3408 if (TARGET_64BIT)
3409 insn = gen_tls_gd_64 (r3, got, addr);
3410 else
3411 insn = gen_tls_gd_32 (r3, got, addr);
3412 start_sequence ();
3413 emit_insn (insn);
3414 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3415 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3416 insn = emit_call_insn (insn);
3417 CONST_OR_PURE_CALL_P (insn) = 1;
3418 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3419 insn = get_insns ();
3420 end_sequence ();
3421 emit_libcall_block (insn, dest, r3, addr);
3423 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3425 r3 = gen_rtx_REG (Pmode, 3);
3426 if (TARGET_64BIT)
3427 insn = gen_tls_ld_64 (r3, got);
3428 else
3429 insn = gen_tls_ld_32 (r3, got);
3430 start_sequence ();
3431 emit_insn (insn);
3432 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3433 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3434 insn = emit_call_insn (insn);
3435 CONST_OR_PURE_CALL_P (insn) = 1;
3436 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3437 insn = get_insns ();
3438 end_sequence ();
3439 tmp1 = gen_reg_rtx (Pmode);
3440 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3441 UNSPEC_TLSLD);
3442 emit_libcall_block (insn, tmp1, r3, eqv);
3443 if (rs6000_tls_size == 16)
3445 if (TARGET_64BIT)
3446 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3447 else
3448 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3450 else if (rs6000_tls_size == 32)
3452 tmp2 = gen_reg_rtx (Pmode);
3453 if (TARGET_64BIT)
3454 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3455 else
3456 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3457 emit_insn (insn);
3458 if (TARGET_64BIT)
3459 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3460 else
3461 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3463 else
3465 tmp2 = gen_reg_rtx (Pmode);
3466 if (TARGET_64BIT)
3467 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3468 else
3469 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3470 emit_insn (insn);
3471 insn = gen_rtx_SET (Pmode, dest,
3472 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3474 emit_insn (insn);
3476 else
3478 /* IE, or 64 bit offset LE. */
3479 tmp2 = gen_reg_rtx (Pmode);
3480 if (TARGET_64BIT)
3481 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3482 else
3483 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3484 emit_insn (insn);
3485 if (TARGET_64BIT)
3486 insn = gen_tls_tls_64 (dest, tmp2, addr);
3487 else
3488 insn = gen_tls_tls_32 (dest, tmp2, addr);
3489 emit_insn (insn);
3493 return dest;
3496 /* Return 1 if X contains a thread-local symbol. */
3498 bool
3499 rs6000_tls_referenced_p (rtx x)
3501 if (! TARGET_HAVE_TLS)
3502 return false;
3504 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
3507 /* Return 1 if *X is a thread-local symbol. This is the same as
3508 rs6000_tls_symbol_ref except for the type of the unused argument. */
3510 static int
3511 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
3513 return RS6000_SYMBOL_REF_TLS_P (*x);
3516 /* The convention appears to be to define this wherever it is used.
3517 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3518 is now used here. */
3519 #ifndef REG_MODE_OK_FOR_BASE_P
3520 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3521 #endif
3523 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3524 replace the input X, or the original X if no replacement is called for.
3525 The output parameter *WIN is 1 if the calling macro should goto WIN,
3526 0 if it should not.
3528 For RS/6000, we wish to handle large displacements off a base
3529 register by splitting the addend across an addiu/addis and the mem insn.
3530 This cuts number of extra insns needed from 3 to 1.
3532 On Darwin, we use this to generate code for floating point constants.
3533 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3534 The Darwin code is inside #if TARGET_MACHO because only then is
3535 machopic_function_base_name() defined. */
3537 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
3538 int opnum, int type,
3539 int ind_levels ATTRIBUTE_UNUSED, int *win)
3541 /* We must recognize output that we have already generated ourselves. */
3542 if (GET_CODE (x) == PLUS
3543 && GET_CODE (XEXP (x, 0)) == PLUS
3544 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3545 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3546 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3548 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3549 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3550 opnum, (enum reload_type)type);
3551 *win = 1;
3552 return x;
3555 #if TARGET_MACHO
3556 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
3557 && GET_CODE (x) == LO_SUM
3558 && GET_CODE (XEXP (x, 0)) == PLUS
3559 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
3560 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
3561 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
3562 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
3563 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
3564 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
3565 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
3567 /* Result of previous invocation of this function on Darwin
3568 floating point constant. */
3569 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3570 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3571 opnum, (enum reload_type)type);
3572 *win = 1;
3573 return x;
3575 #endif
3577 /* Force ld/std non-word aligned offset into base register by wrapping
3578 in offset 0. */
3579 if (GET_CODE (x) == PLUS
3580 && GET_CODE (XEXP (x, 0)) == REG
3581 && REGNO (XEXP (x, 0)) < 32
3582 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3583 && GET_CODE (XEXP (x, 1)) == CONST_INT
3584 && (INTVAL (XEXP (x, 1)) & 3) != 0
3585 && !ALTIVEC_VECTOR_MODE (mode)
3586 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
3587 && TARGET_POWERPC64)
3589 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
3590 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3591 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3592 opnum, (enum reload_type) type);
3593 *win = 1;
3594 return x;
3597 if (GET_CODE (x) == PLUS
3598 && GET_CODE (XEXP (x, 0)) == REG
3599 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
3600 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3601 && GET_CODE (XEXP (x, 1)) == CONST_INT
3602 && !SPE_VECTOR_MODE (mode)
3603 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3604 || mode == DImode))
3605 && !ALTIVEC_VECTOR_MODE (mode))
3607 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3608 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
3609 HOST_WIDE_INT high
3610 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3612 /* Check for 32-bit overflow. */
3613 if (high + low != val)
3615 *win = 0;
3616 return x;
3619 /* Reload the high part into a base reg; leave the low part
3620 in the mem directly. */
3622 x = gen_rtx_PLUS (GET_MODE (x),
3623 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
3624 GEN_INT (high)),
3625 GEN_INT (low));
3627 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3628 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3629 opnum, (enum reload_type)type);
3630 *win = 1;
3631 return x;
3634 if (GET_CODE (x) == SYMBOL_REF
3635 && !ALTIVEC_VECTOR_MODE (mode)
3636 && !SPE_VECTOR_MODE (mode)
3637 #if TARGET_MACHO
3638 && DEFAULT_ABI == ABI_DARWIN
3639 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
3640 #else
3641 && DEFAULT_ABI == ABI_V4
3642 && !flag_pic
3643 #endif
3644 /* Don't do this for TFmode, since the result isn't offsettable.
3645 The same goes for DImode without 64-bit gprs and DFmode
3646 without fprs. */
3647 && mode != TFmode
3648 && (mode != DImode || TARGET_POWERPC64)
3649 && (mode != DFmode || TARGET_POWERPC64
3650 || (TARGET_FPRS && TARGET_HARD_FLOAT)))
3652 #if TARGET_MACHO
3653 if (flag_pic)
3655 rtx offset = gen_rtx_CONST (Pmode,
3656 gen_rtx_MINUS (Pmode, x,
3657 machopic_function_base_sym ()));
3658 x = gen_rtx_LO_SUM (GET_MODE (x),
3659 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
3660 gen_rtx_HIGH (Pmode, offset)), offset);
3662 else
3663 #endif
3664 x = gen_rtx_LO_SUM (GET_MODE (x),
3665 gen_rtx_HIGH (Pmode, x), x);
3667 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3668 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3669 opnum, (enum reload_type)type);
3670 *win = 1;
3671 return x;
3674 /* Reload an offset address wrapped by an AND that represents the
3675 masking of the lower bits. Strip the outer AND and let reload
3676 convert the offset address into an indirect address. */
3677 if (TARGET_ALTIVEC
3678 && ALTIVEC_VECTOR_MODE (mode)
3679 && GET_CODE (x) == AND
3680 && GET_CODE (XEXP (x, 0)) == PLUS
3681 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3682 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3683 && GET_CODE (XEXP (x, 1)) == CONST_INT
3684 && INTVAL (XEXP (x, 1)) == -16)
3686 x = XEXP (x, 0);
3687 *win = 1;
3688 return x;
3691 if (TARGET_TOC
3692 && constant_pool_expr_p (x)
3693 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
3695 x = create_TOC_reference (x);
3696 *win = 1;
3697 return x;
3699 *win = 0;
3700 return x;
3703 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3704 that is a valid memory address for an instruction.
3705 The MODE argument is the machine mode for the MEM expression
3706 that wants to use this address.
3708 On the RS/6000, there are four valid address: a SYMBOL_REF that
3709 refers to a constant pool entry of an address (or the sum of it
3710 plus a constant), a short (16-bit signed) constant plus a register,
3711 the sum of two registers, or a register indirect, possibly with an
3712 auto-increment. For DFmode and DImode with a constant plus register,
3713 we must ensure that both words are addressable or PowerPC64 with offset
3714 word aligned.
3716 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3717 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3718 adjacent memory cells are accessed by adding word-sized offsets
3719 during assembly output. */
3721 rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
3723 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3724 if (TARGET_ALTIVEC
3725 && ALTIVEC_VECTOR_MODE (mode)
3726 && GET_CODE (x) == AND
3727 && GET_CODE (XEXP (x, 1)) == CONST_INT
3728 && INTVAL (XEXP (x, 1)) == -16)
3729 x = XEXP (x, 0);
3731 if (RS6000_SYMBOL_REF_TLS_P (x))
3732 return 0;
3733 if (legitimate_indirect_address_p (x, reg_ok_strict))
3734 return 1;
3735 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
3736 && !ALTIVEC_VECTOR_MODE (mode)
3737 && !SPE_VECTOR_MODE (mode)
3738 && mode != TFmode
3739 /* Restrict addressing for DI because of our SUBREG hackery. */
3740 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3741 || mode == DImode))
3742 && TARGET_UPDATE
3743 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
3744 return 1;
3745 if (legitimate_small_data_p (mode, x))
3746 return 1;
3747 if (legitimate_constant_pool_address_p (x))
3748 return 1;
3749 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3750 if (! reg_ok_strict
3751 && GET_CODE (x) == PLUS
3752 && GET_CODE (XEXP (x, 0)) == REG
3753 && (XEXP (x, 0) == virtual_stack_vars_rtx
3754 || XEXP (x, 0) == arg_pointer_rtx)
3755 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3756 return 1;
3757 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
3758 return 1;
3759 if (mode != TImode
3760 && mode != TFmode
3761 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3762 || TARGET_POWERPC64
3763 || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
3764 && (TARGET_POWERPC64 || mode != DImode)
3765 && legitimate_indexed_address_p (x, reg_ok_strict))
3766 return 1;
3767 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
3768 return 1;
3769 return 0;
3772 /* Go to LABEL if ADDR (a legitimate address expression)
3773 has an effect that depends on the machine mode it is used for.
3775 On the RS/6000 this is true of all integral offsets (since AltiVec
3776 modes don't allow them) or is a pre-increment or decrement.
3778 ??? Except that due to conceptual problems in offsettable_address_p
3779 we can't really report the problems of integral offsets. So leave
3780 this assuming that the adjustable offset must be valid for the
3781 sub-words of a TFmode operand, which is what we had before. */
3783 bool
3784 rs6000_mode_dependent_address (rtx addr)
3786 switch (GET_CODE (addr))
3788 case PLUS:
3789 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
3791 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
3792 return val + 12 + 0x8000 >= 0x10000;
3794 break;
3796 case LO_SUM:
3797 return true;
3799 /* Auto-increment cases are now treated generically in recog.c. */
3801 default:
3802 break;
3805 return false;
3808 /* More elaborate version of recog's offsettable_memref_p predicate
3809 that works around the ??? note of rs6000_mode_dependent_address.
3810 In particular it accepts
3812 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
3814 in 32-bit mode, that the recog predicate rejects. */
3816 bool
3817 rs6000_offsettable_memref_p (rtx op)
3819 if (!MEM_P (op))
3820 return false;
3822 /* First mimic offsettable_memref_p. */
3823 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
3824 return true;
3826 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
3827 the latter predicate knows nothing about the mode of the memory
3828 reference and, therefore, assumes that it is the largest supported
3829 mode (TFmode). As a consequence, legitimate offsettable memory
3830 references are rejected. rs6000_legitimate_offset_address_p contains
3831 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
3832 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
3835 /* Return number of consecutive hard regs needed starting at reg REGNO
3836 to hold something of mode MODE.
3837 This is ordinarily the length in words of a value of mode MODE
3838 but can be less for certain modes in special long registers.
3840 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3841 scalar instructions. The upper 32 bits are only available to the
3842 SIMD instructions.
3844 POWER and PowerPC GPRs hold 32 bits worth;
3845 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3848 rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
3850 if (FP_REGNO_P (regno))
3851 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3853 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
3854 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
3856 if (ALTIVEC_REGNO_P (regno))
3857 return
3858 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
3860 /* The value returned for SCmode in the E500 double case is 2 for
3861 ABI compatibility; storing an SCmode value in a single register
3862 would require function_arg and rs6000_spe_function_arg to handle
3863 SCmode so as to pass the value correctly in a pair of
3864 registers. */
3865 if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode)
3866 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3868 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3871 /* Change register usage conditional on target flags. */
3872 void
3873 rs6000_conditional_register_usage (void)
3875 int i;
3877 /* Set MQ register fixed (already call_used) if not POWER
3878 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3879 be allocated. */
3880 if (! TARGET_POWER)
3881 fixed_regs[64] = 1;
3883 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3884 if (TARGET_64BIT)
3885 fixed_regs[13] = call_used_regs[13]
3886 = call_really_used_regs[13] = 1;
3888 /* Conditionally disable FPRs. */
3889 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
3890 for (i = 32; i < 64; i++)
3891 fixed_regs[i] = call_used_regs[i]
3892 = call_really_used_regs[i] = 1;
3894 /* The TOC register is not killed across calls in a way that is
3895 visible to the compiler. */
3896 if (DEFAULT_ABI == ABI_AIX)
3897 call_really_used_regs[2] = 0;
3899 if (DEFAULT_ABI == ABI_V4
3900 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3901 && flag_pic == 2)
3902 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3904 if (DEFAULT_ABI == ABI_V4
3905 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3906 && flag_pic == 1)
3907 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3908 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3909 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3911 if (DEFAULT_ABI == ABI_DARWIN
3912 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
3913 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3914 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3915 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3917 if (TARGET_TOC && TARGET_MINIMAL_TOC)
3918 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3919 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3921 if (TARGET_ALTIVEC)
3922 global_regs[VSCR_REGNO] = 1;
3924 if (TARGET_SPE)
3926 global_regs[SPEFSCR_REGNO] = 1;
3927 fixed_regs[FIXED_SCRATCH]
3928 = call_used_regs[FIXED_SCRATCH]
3929 = call_really_used_regs[FIXED_SCRATCH] = 1;
3932 if (! TARGET_ALTIVEC)
3934 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
3935 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
3936 call_really_used_regs[VRSAVE_REGNO] = 1;
3939 if (TARGET_ALTIVEC_ABI)
3940 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
3941 call_used_regs[i] = call_really_used_regs[i] = 1;
3944 /* Try to output insns to set TARGET equal to the constant C if it can
3945 be done in less than N insns. Do all computations in MODE.
3946 Returns the place where the output has been placed if it can be
3947 done and the insns have been emitted. If it would take more than N
3948 insns, zero is returned and no insns and emitted. */
3951 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
3952 rtx source, int n ATTRIBUTE_UNUSED)
3954 rtx result, insn, set;
3955 HOST_WIDE_INT c0, c1;
3957 switch (mode)
3959 case QImode:
3960 case HImode:
3961 if (dest == NULL)
3962 dest = gen_reg_rtx (mode);
3963 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
3964 return dest;
3966 case SImode:
3967 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
3969 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
3970 GEN_INT (INTVAL (source)
3971 & (~ (HOST_WIDE_INT) 0xffff))));
3972 emit_insn (gen_rtx_SET (VOIDmode, dest,
3973 gen_rtx_IOR (SImode, copy_rtx (result),
3974 GEN_INT (INTVAL (source) & 0xffff))));
3975 result = dest;
3976 break;
3978 case DImode:
3979 switch (GET_CODE (source))
3981 case CONST_INT:
3982 c0 = INTVAL (source);
3983 c1 = -(c0 < 0);
3984 break;
3986 case CONST_DOUBLE:
3987 #if HOST_BITS_PER_WIDE_INT >= 64
3988 c0 = CONST_DOUBLE_LOW (source);
3989 c1 = -(c0 < 0);
3990 #else
3991 c0 = CONST_DOUBLE_LOW (source);
3992 c1 = CONST_DOUBLE_HIGH (source);
3993 #endif
3994 break;
3996 default:
3997 gcc_unreachable ();
4000 result = rs6000_emit_set_long_const (dest, c0, c1);
4001 break;
4003 default:
4004 gcc_unreachable ();
4007 insn = get_last_insn ();
4008 set = single_set (insn);
4009 if (! CONSTANT_P (SET_SRC (set)))
4010 set_unique_reg_note (insn, REG_EQUAL, source);
4012 return result;
4015 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4016 fall back to a straight forward decomposition. We do this to avoid
4017 exponential run times encountered when looking for longer sequences
4018 with rs6000_emit_set_const. */
4019 static rtx
4020 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
4022 if (!TARGET_POWERPC64)
4024 rtx operand1, operand2;
4026 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
4027 DImode);
4028 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
4029 DImode);
4030 emit_move_insn (operand1, GEN_INT (c1));
4031 emit_move_insn (operand2, GEN_INT (c2));
4033 else
4035 HOST_WIDE_INT ud1, ud2, ud3, ud4;
4037 ud1 = c1 & 0xffff;
4038 ud2 = (c1 & 0xffff0000) >> 16;
4039 #if HOST_BITS_PER_WIDE_INT >= 64
4040 c2 = c1 >> 32;
4041 #endif
4042 ud3 = c2 & 0xffff;
4043 ud4 = (c2 & 0xffff0000) >> 16;
4045 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
4046 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
4048 if (ud1 & 0x8000)
4049 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
4050 else
4051 emit_move_insn (dest, GEN_INT (ud1));
4054 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
4055 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
4057 if (ud2 & 0x8000)
4058 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
4059 - 0x80000000));
4060 else
4061 emit_move_insn (dest, GEN_INT (ud2 << 16));
4062 if (ud1 != 0)
4063 emit_move_insn (copy_rtx (dest),
4064 gen_rtx_IOR (DImode, copy_rtx (dest),
4065 GEN_INT (ud1)));
4067 else if ((ud4 == 0xffff && (ud3 & 0x8000))
4068 || (ud4 == 0 && ! (ud3 & 0x8000)))
4070 if (ud3 & 0x8000)
4071 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
4072 - 0x80000000));
4073 else
4074 emit_move_insn (dest, GEN_INT (ud3 << 16));
4076 if (ud2 != 0)
4077 emit_move_insn (copy_rtx (dest),
4078 gen_rtx_IOR (DImode, copy_rtx (dest),
4079 GEN_INT (ud2)));
4080 emit_move_insn (copy_rtx (dest),
4081 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4082 GEN_INT (16)));
4083 if (ud1 != 0)
4084 emit_move_insn (copy_rtx (dest),
4085 gen_rtx_IOR (DImode, copy_rtx (dest),
4086 GEN_INT (ud1)));
4088 else
4090 if (ud4 & 0x8000)
4091 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
4092 - 0x80000000));
4093 else
4094 emit_move_insn (dest, GEN_INT (ud4 << 16));
4096 if (ud3 != 0)
4097 emit_move_insn (copy_rtx (dest),
4098 gen_rtx_IOR (DImode, copy_rtx (dest),
4099 GEN_INT (ud3)));
4101 emit_move_insn (copy_rtx (dest),
4102 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4103 GEN_INT (32)));
4104 if (ud2 != 0)
4105 emit_move_insn (copy_rtx (dest),
4106 gen_rtx_IOR (DImode, copy_rtx (dest),
4107 GEN_INT (ud2 << 16)));
4108 if (ud1 != 0)
4109 emit_move_insn (copy_rtx (dest),
4110 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
4113 return dest;
4116 /* Helper for the following. Get rid of [r+r] memory refs
4117 in cases where it won't work (TImode, TFmode). */
4119 static void
4120 rs6000_eliminate_indexed_memrefs (rtx operands[2])
4122 if (GET_CODE (operands[0]) == MEM
4123 && GET_CODE (XEXP (operands[0], 0)) != REG
4124 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
4125 && ! reload_in_progress)
4126 operands[0]
4127 = replace_equiv_address (operands[0],
4128 copy_addr_to_reg (XEXP (operands[0], 0)));
4130 if (GET_CODE (operands[1]) == MEM
4131 && GET_CODE (XEXP (operands[1], 0)) != REG
4132 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
4133 && ! reload_in_progress)
4134 operands[1]
4135 = replace_equiv_address (operands[1],
4136 copy_addr_to_reg (XEXP (operands[1], 0)));
4139 /* Emit a move from SOURCE to DEST in mode MODE. */
4140 void
4141 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
4143 rtx operands[2];
4144 operands[0] = dest;
4145 operands[1] = source;
4147 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4148 if (GET_CODE (operands[1]) == CONST_DOUBLE
4149 && ! FLOAT_MODE_P (mode)
4150 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
4152 /* FIXME. This should never happen. */
4153 /* Since it seems that it does, do the safe thing and convert
4154 to a CONST_INT. */
4155 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
4157 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
4158 || FLOAT_MODE_P (mode)
4159 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
4160 || CONST_DOUBLE_LOW (operands[1]) < 0)
4161 && (CONST_DOUBLE_HIGH (operands[1]) != -1
4162 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
4164 /* Check if GCC is setting up a block move that will end up using FP
4165 registers as temporaries. We must make sure this is acceptable. */
4166 if (GET_CODE (operands[0]) == MEM
4167 && GET_CODE (operands[1]) == MEM
4168 && mode == DImode
4169 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
4170 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
4171 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
4172 ? 32 : MEM_ALIGN (operands[0])))
4173 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
4174 ? 32
4175 : MEM_ALIGN (operands[1]))))
4176 && ! MEM_VOLATILE_P (operands [0])
4177 && ! MEM_VOLATILE_P (operands [1]))
4179 emit_move_insn (adjust_address (operands[0], SImode, 0),
4180 adjust_address (operands[1], SImode, 0));
4181 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
4182 adjust_address (copy_rtx (operands[1]), SImode, 4));
4183 return;
4186 if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
4187 && !gpc_reg_operand (operands[1], mode))
4188 operands[1] = force_reg (mode, operands[1]);
4190 if (mode == SFmode && ! TARGET_POWERPC
4191 && TARGET_HARD_FLOAT && TARGET_FPRS
4192 && GET_CODE (operands[0]) == MEM)
4194 int regnum;
4196 if (reload_in_progress || reload_completed)
4197 regnum = true_regnum (operands[1]);
4198 else if (GET_CODE (operands[1]) == REG)
4199 regnum = REGNO (operands[1]);
4200 else
4201 regnum = -1;
4203 /* If operands[1] is a register, on POWER it may have
4204 double-precision data in it, so truncate it to single
4205 precision. */
4206 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
4208 rtx newreg;
4209 newreg = (no_new_pseudos ? copy_rtx (operands[1])
4210 : gen_reg_rtx (mode));
4211 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
4212 operands[1] = newreg;
4216 /* Recognize the case where operand[1] is a reference to thread-local
4217 data and load its address to a register. */
4218 if (rs6000_tls_referenced_p (operands[1]))
4220 enum tls_model model;
4221 rtx tmp = operands[1];
4222 rtx addend = NULL;
4224 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
4226 addend = XEXP (XEXP (tmp, 0), 1);
4227 tmp = XEXP (XEXP (tmp, 0), 0);
4230 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
4231 model = SYMBOL_REF_TLS_MODEL (tmp);
4232 gcc_assert (model != 0);
4234 tmp = rs6000_legitimize_tls_address (tmp, model);
4235 if (addend)
4237 tmp = gen_rtx_PLUS (mode, tmp, addend);
4238 tmp = force_operand (tmp, operands[0]);
4240 operands[1] = tmp;
4243 /* Handle the case where reload calls us with an invalid address. */
4244 if (reload_in_progress && mode == Pmode
4245 && (! general_operand (operands[1], mode)
4246 || ! nonimmediate_operand (operands[0], mode)))
4247 goto emit_set;
4249 /* 128-bit constant floating-point values on Darwin should really be
4250 loaded as two parts. */
4251 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
4252 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
4254 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4255 know how to get a DFmode SUBREG of a TFmode. */
4256 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
4257 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
4258 simplify_gen_subreg (imode, operands[1], mode, 0),
4259 imode);
4260 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
4261 GET_MODE_SIZE (imode)),
4262 simplify_gen_subreg (imode, operands[1], mode,
4263 GET_MODE_SIZE (imode)),
4264 imode);
4265 return;
4268 /* FIXME: In the long term, this switch statement should go away
4269 and be replaced by a sequence of tests based on things like
4270 mode == Pmode. */
4271 switch (mode)
4273 case HImode:
4274 case QImode:
4275 if (CONSTANT_P (operands[1])
4276 && GET_CODE (operands[1]) != CONST_INT)
4277 operands[1] = force_const_mem (mode, operands[1]);
4278 break;
4280 case TFmode:
4281 rs6000_eliminate_indexed_memrefs (operands);
4282 /* fall through */
4284 case DFmode:
4285 case SFmode:
4286 if (CONSTANT_P (operands[1])
4287 && ! easy_fp_constant (operands[1], mode))
4288 operands[1] = force_const_mem (mode, operands[1]);
4289 break;
4291 case V16QImode:
4292 case V8HImode:
4293 case V4SFmode:
4294 case V4SImode:
4295 case V4HImode:
4296 case V2SFmode:
4297 case V2SImode:
4298 case V1DImode:
4299 if (CONSTANT_P (operands[1])
4300 && !easy_vector_constant (operands[1], mode))
4301 operands[1] = force_const_mem (mode, operands[1]);
4302 break;
4304 case SImode:
4305 case DImode:
4306 /* Use default pattern for address of ELF small data */
4307 if (TARGET_ELF
4308 && mode == Pmode
4309 && DEFAULT_ABI == ABI_V4
4310 && (GET_CODE (operands[1]) == SYMBOL_REF
4311 || GET_CODE (operands[1]) == CONST)
4312 && small_data_operand (operands[1], mode))
4314 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4315 return;
4318 if (DEFAULT_ABI == ABI_V4
4319 && mode == Pmode && mode == SImode
4320 && flag_pic == 1 && got_operand (operands[1], mode))
4322 emit_insn (gen_movsi_got (operands[0], operands[1]));
4323 return;
4326 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
4327 && TARGET_NO_TOC
4328 && ! flag_pic
4329 && mode == Pmode
4330 && CONSTANT_P (operands[1])
4331 && GET_CODE (operands[1]) != HIGH
4332 && GET_CODE (operands[1]) != CONST_INT)
4334 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
4336 /* If this is a function address on -mcall-aixdesc,
4337 convert it to the address of the descriptor. */
4338 if (DEFAULT_ABI == ABI_AIX
4339 && GET_CODE (operands[1]) == SYMBOL_REF
4340 && XSTR (operands[1], 0)[0] == '.')
4342 const char *name = XSTR (operands[1], 0);
4343 rtx new_ref;
4344 while (*name == '.')
4345 name++;
4346 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
4347 CONSTANT_POOL_ADDRESS_P (new_ref)
4348 = CONSTANT_POOL_ADDRESS_P (operands[1]);
4349 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
4350 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
4351 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
4352 operands[1] = new_ref;
4355 if (DEFAULT_ABI == ABI_DARWIN)
4357 #if TARGET_MACHO
4358 if (MACHO_DYNAMIC_NO_PIC_P)
4360 /* Take care of any required data indirection. */
4361 operands[1] = rs6000_machopic_legitimize_pic_address (
4362 operands[1], mode, operands[0]);
4363 if (operands[0] != operands[1])
4364 emit_insn (gen_rtx_SET (VOIDmode,
4365 operands[0], operands[1]));
4366 return;
4368 #endif
4369 emit_insn (gen_macho_high (target, operands[1]));
4370 emit_insn (gen_macho_low (operands[0], target, operands[1]));
4371 return;
4374 emit_insn (gen_elf_high (target, operands[1]));
4375 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4376 return;
4379 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4380 and we have put it in the TOC, we just need to make a TOC-relative
4381 reference to it. */
4382 if (TARGET_TOC
4383 && GET_CODE (operands[1]) == SYMBOL_REF
4384 && constant_pool_expr_p (operands[1])
4385 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
4386 get_pool_mode (operands[1])))
4388 operands[1] = create_TOC_reference (operands[1]);
4390 else if (mode == Pmode
4391 && CONSTANT_P (operands[1])
4392 && ((GET_CODE (operands[1]) != CONST_INT
4393 && ! easy_fp_constant (operands[1], mode))
4394 || (GET_CODE (operands[1]) == CONST_INT
4395 && num_insns_constant (operands[1], mode) > 2)
4396 || (GET_CODE (operands[0]) == REG
4397 && FP_REGNO_P (REGNO (operands[0]))))
4398 && GET_CODE (operands[1]) != HIGH
4399 && ! legitimate_constant_pool_address_p (operands[1])
4400 && ! toc_relative_expr_p (operands[1]))
4402 /* Emit a USE operation so that the constant isn't deleted if
4403 expensive optimizations are turned on because nobody
4404 references it. This should only be done for operands that
4405 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4406 This should not be done for operands that contain LABEL_REFs.
4407 For now, we just handle the obvious case. */
4408 if (GET_CODE (operands[1]) != LABEL_REF)
4409 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
4411 #if TARGET_MACHO
4412 /* Darwin uses a special PIC legitimizer. */
4413 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
4415 operands[1] =
4416 rs6000_machopic_legitimize_pic_address (operands[1], mode,
4417 operands[0]);
4418 if (operands[0] != operands[1])
4419 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4420 return;
4422 #endif
4424 /* If we are to limit the number of things we put in the TOC and
4425 this is a symbol plus a constant we can add in one insn,
4426 just put the symbol in the TOC and add the constant. Don't do
4427 this if reload is in progress. */
4428 if (GET_CODE (operands[1]) == CONST
4429 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4430 && GET_CODE (XEXP (operands[1], 0)) == PLUS
4431 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
4432 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4433 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4434 && ! side_effects_p (operands[0]))
4436 rtx sym =
4437 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
4438 rtx other = XEXP (XEXP (operands[1], 0), 1);
4440 sym = force_reg (mode, sym);
4441 if (mode == SImode)
4442 emit_insn (gen_addsi3 (operands[0], sym, other));
4443 else
4444 emit_insn (gen_adddi3 (operands[0], sym, other));
4445 return;
4448 operands[1] = force_const_mem (mode, operands[1]);
4450 if (TARGET_TOC
4451 && constant_pool_expr_p (XEXP (operands[1], 0))
4452 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4453 get_pool_constant (XEXP (operands[1], 0)),
4454 get_pool_mode (XEXP (operands[1], 0))))
4456 operands[1]
4457 = gen_const_mem (mode,
4458 create_TOC_reference (XEXP (operands[1], 0)));
4459 set_mem_alias_set (operands[1], get_TOC_alias_set ());
4462 break;
4464 case TImode:
4465 rs6000_eliminate_indexed_memrefs (operands);
4467 if (TARGET_POWER)
4469 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4470 gen_rtvec (2,
4471 gen_rtx_SET (VOIDmode,
4472 operands[0], operands[1]),
4473 gen_rtx_CLOBBER (VOIDmode,
4474 gen_rtx_SCRATCH (SImode)))));
4475 return;
4477 break;
4479 default:
4480 gcc_unreachable ();
4483 /* Above, we may have called force_const_mem which may have returned
4484 an invalid address. If we can, fix this up; otherwise, reload will
4485 have to deal with it. */
4486 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
4487 operands[1] = validize_mem (operands[1]);
4489 emit_set:
4490 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4493 /* Nonzero if we can use a floating-point register to pass this arg. */
4494 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4495 (SCALAR_FLOAT_MODE_P (MODE) \
4496 && !DECIMAL_FLOAT_MODE_P (MODE) \
4497 && (CUM)->fregno <= FP_ARG_MAX_REG \
4498 && TARGET_HARD_FLOAT && TARGET_FPRS)
4500 /* Nonzero if we can use an AltiVec register to pass this arg. */
4501 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4502 (ALTIVEC_VECTOR_MODE (MODE) \
4503 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4504 && TARGET_ALTIVEC_ABI \
4505 && (NAMED))
4507 /* Return a nonzero value to say to return the function value in
4508 memory, just as large structures are always returned. TYPE will be
4509 the data type of the value, and FNTYPE will be the type of the
4510 function doing the returning, or @code{NULL} for libcalls.
4512 The AIX ABI for the RS/6000 specifies that all structures are
4513 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4514 specifies that structures <= 8 bytes are returned in r3/r4, but a
4515 draft put them in memory, and GCC used to implement the draft
4516 instead of the final standard. Therefore, aix_struct_return
4517 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4518 compatibility can change DRAFT_V4_STRUCT_RET to override the
4519 default, and -m switches get the final word. See
4520 rs6000_override_options for more details.
4522 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4523 long double support is enabled. These values are returned in memory.
4525 int_size_in_bytes returns -1 for variable size objects, which go in
4526 memory always. The cast to unsigned makes -1 > 8. */
4528 static bool
4529 rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
4531 /* In the darwin64 abi, try to use registers for larger structs
4532 if possible. */
4533 if (rs6000_darwin64_abi
4534 && TREE_CODE (type) == RECORD_TYPE
4535 && int_size_in_bytes (type) > 0)
4537 CUMULATIVE_ARGS valcum;
4538 rtx valret;
4540 valcum.words = 0;
4541 valcum.fregno = FP_ARG_MIN_REG;
4542 valcum.vregno = ALTIVEC_ARG_MIN_REG;
4543 /* Do a trial code generation as if this were going to be passed
4544 as an argument; if any part goes in memory, we return NULL. */
4545 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
4546 if (valret)
4547 return false;
4548 /* Otherwise fall through to more conventional ABI rules. */
4551 if (AGGREGATE_TYPE_P (type)
4552 && (aix_struct_return
4553 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
4554 return true;
4556 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4557 modes only exist for GCC vector types if -maltivec. */
4558 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
4559 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
4560 return false;
4562 /* Return synthetic vectors in memory. */
4563 if (TREE_CODE (type) == VECTOR_TYPE
4564 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
4566 static bool warned_for_return_big_vectors = false;
4567 if (!warned_for_return_big_vectors)
4569 warning (0, "GCC vector returned by reference: "
4570 "non-standard ABI extension with no compatibility guarantee");
4571 warned_for_return_big_vectors = true;
4573 return true;
4576 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
4577 return true;
4579 return false;
4582 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4583 for a call to a function whose data type is FNTYPE.
4584 For a library call, FNTYPE is 0.
4586 For incoming args we set the number of arguments in the prototype large
4587 so we never return a PARALLEL. */
4589 void
4590 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
4591 rtx libname ATTRIBUTE_UNUSED, int incoming,
4592 int libcall, int n_named_args)
4594 static CUMULATIVE_ARGS zero_cumulative;
4596 *cum = zero_cumulative;
4597 cum->words = 0;
4598 cum->fregno = FP_ARG_MIN_REG;
4599 cum->vregno = ALTIVEC_ARG_MIN_REG;
4600 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
4601 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
4602 ? CALL_LIBCALL : CALL_NORMAL);
4603 cum->sysv_gregno = GP_ARG_MIN_REG;
4604 cum->stdarg = fntype
4605 && (TYPE_ARG_TYPES (fntype) != 0
4606 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4607 != void_type_node));
4609 cum->nargs_prototype = 0;
4610 if (incoming || cum->prototype)
4611 cum->nargs_prototype = n_named_args;
4613 /* Check for a longcall attribute. */
4614 if ((!fntype && rs6000_default_long_calls)
4615 || (fntype
4616 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
4617 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
4618 cum->call_cookie |= CALL_LONG;
4620 if (TARGET_DEBUG_ARG)
4622 fprintf (stderr, "\ninit_cumulative_args:");
4623 if (fntype)
4625 tree ret_type = TREE_TYPE (fntype);
4626 fprintf (stderr, " ret code = %s,",
4627 tree_code_name[ (int)TREE_CODE (ret_type) ]);
4630 if (cum->call_cookie & CALL_LONG)
4631 fprintf (stderr, " longcall,");
4633 fprintf (stderr, " proto = %d, nargs = %d\n",
4634 cum->prototype, cum->nargs_prototype);
4637 if (fntype
4638 && !TARGET_ALTIVEC
4639 && TARGET_ALTIVEC_ABI
4640 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
4642 error ("cannot return value in vector register because"
4643 " altivec instructions are disabled, use -maltivec"
4644 " to enable them");
4648 /* Return true if TYPE must be passed on the stack and not in registers. */
4650 static bool
4651 rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
4653 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
4654 return must_pass_in_stack_var_size (mode, type);
4655 else
4656 return must_pass_in_stack_var_size_or_pad (mode, type);
4659 /* If defined, a C expression which determines whether, and in which
4660 direction, to pad out an argument with extra space. The value
4661 should be of type `enum direction': either `upward' to pad above
4662 the argument, `downward' to pad below, or `none' to inhibit
4663 padding.
4665 For the AIX ABI structs are always stored left shifted in their
4666 argument slot. */
4668 enum direction
4669 function_arg_padding (enum machine_mode mode, tree type)
4671 #ifndef AGGREGATE_PADDING_FIXED
4672 #define AGGREGATE_PADDING_FIXED 0
4673 #endif
4674 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4675 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4676 #endif
4678 if (!AGGREGATE_PADDING_FIXED)
4680 /* GCC used to pass structures of the same size as integer types as
4681 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4682 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4683 passed padded downward, except that -mstrict-align further
4684 muddied the water in that multi-component structures of 2 and 4
4685 bytes in size were passed padded upward.
4687 The following arranges for best compatibility with previous
4688 versions of gcc, but removes the -mstrict-align dependency. */
4689 if (BYTES_BIG_ENDIAN)
4691 HOST_WIDE_INT size = 0;
4693 if (mode == BLKmode)
4695 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
4696 size = int_size_in_bytes (type);
4698 else
4699 size = GET_MODE_SIZE (mode);
4701 if (size == 1 || size == 2 || size == 4)
4702 return downward;
4704 return upward;
4707 if (AGGREGATES_PAD_UPWARD_ALWAYS)
4709 if (type != 0 && AGGREGATE_TYPE_P (type))
4710 return upward;
4713 /* Fall back to the default. */
4714 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
4717 /* If defined, a C expression that gives the alignment boundary, in bits,
4718 of an argument with the specified mode and type. If it is not defined,
4719 PARM_BOUNDARY is used for all arguments.
4721 V.4 wants long longs and doubles to be double word aligned. Just
4722 testing the mode size is a boneheaded way to do this as it means
4723 that other types such as complex int are also double word aligned.
4724 However, we're stuck with this because changing the ABI might break
4725 existing library interfaces.
4727 Doubleword align SPE vectors.
4728 Quadword align Altivec vectors.
4729 Quadword align large synthetic vector types. */
4732 function_arg_boundary (enum machine_mode mode, tree type)
4734 if (DEFAULT_ABI == ABI_V4
4735 && (GET_MODE_SIZE (mode) == 8
4736 || (TARGET_HARD_FLOAT
4737 && TARGET_FPRS
4738 && mode == TFmode)))
4739 return 64;
4740 else if (SPE_VECTOR_MODE (mode)
4741 || (type && TREE_CODE (type) == VECTOR_TYPE
4742 && int_size_in_bytes (type) >= 8
4743 && int_size_in_bytes (type) < 16))
4744 return 64;
4745 else if (ALTIVEC_VECTOR_MODE (mode)
4746 || (type && TREE_CODE (type) == VECTOR_TYPE
4747 && int_size_in_bytes (type) >= 16))
4748 return 128;
4749 else if (rs6000_darwin64_abi && mode == BLKmode
4750 && type && TYPE_ALIGN (type) > 64)
4751 return 128;
4752 else
4753 return PARM_BOUNDARY;
4756 /* For a function parm of MODE and TYPE, return the starting word in
4757 the parameter area. NWORDS of the parameter area are already used. */
4759 static unsigned int
4760 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
4762 unsigned int align;
4763 unsigned int parm_offset;
4765 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
4766 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
4767 return nwords + (-(parm_offset + nwords) & align);
4770 /* Compute the size (in words) of a function argument. */
4772 static unsigned long
4773 rs6000_arg_size (enum machine_mode mode, tree type)
4775 unsigned long size;
4777 if (mode != BLKmode)
4778 size = GET_MODE_SIZE (mode);
4779 else
4780 size = int_size_in_bytes (type);
4782 if (TARGET_32BIT)
4783 return (size + 3) >> 2;
4784 else
4785 return (size + 7) >> 3;
4788 /* Use this to flush pending int fields. */
4790 static void
4791 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
4792 HOST_WIDE_INT bitpos)
4794 unsigned int startbit, endbit;
4795 int intregs, intoffset;
4796 enum machine_mode mode;
4798 if (cum->intoffset == -1)
4799 return;
4801 intoffset = cum->intoffset;
4802 cum->intoffset = -1;
4804 if (intoffset % BITS_PER_WORD != 0)
4806 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4807 MODE_INT, 0);
4808 if (mode == BLKmode)
4810 /* We couldn't find an appropriate mode, which happens,
4811 e.g., in packed structs when there are 3 bytes to load.
4812 Back intoffset back to the beginning of the word in this
4813 case. */
4814 intoffset = intoffset & -BITS_PER_WORD;
4818 startbit = intoffset & -BITS_PER_WORD;
4819 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4820 intregs = (endbit - startbit) / BITS_PER_WORD;
4821 cum->words += intregs;
4824 /* The darwin64 ABI calls for us to recurse down through structs,
4825 looking for elements passed in registers. Unfortunately, we have
4826 to track int register count here also because of misalignments
4827 in powerpc alignment mode. */
4829 static void
4830 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
4831 tree type,
4832 HOST_WIDE_INT startbitpos)
4834 tree f;
4836 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4837 if (TREE_CODE (f) == FIELD_DECL)
4839 HOST_WIDE_INT bitpos = startbitpos;
4840 tree ftype = TREE_TYPE (f);
4841 enum machine_mode mode;
4842 if (ftype == error_mark_node)
4843 continue;
4844 mode = TYPE_MODE (ftype);
4846 if (DECL_SIZE (f) != 0
4847 && host_integerp (bit_position (f), 1))
4848 bitpos += int_bit_position (f);
4850 /* ??? FIXME: else assume zero offset. */
4852 if (TREE_CODE (ftype) == RECORD_TYPE)
4853 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
4854 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
4856 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4857 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4858 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
4860 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
4862 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4863 cum->vregno++;
4864 cum->words += 2;
4866 else if (cum->intoffset == -1)
4867 cum->intoffset = bitpos;
4871 /* Update the data in CUM to advance over an argument
4872 of mode MODE and data type TYPE.
4873 (TYPE is null for libcalls where that information may not be available.)
4875 Note that for args passed by reference, function_arg will be called
4876 with MODE and TYPE set to that of the pointer to the arg, not the arg
4877 itself. */
4879 void
4880 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4881 tree type, int named, int depth)
4883 int size;
4885 /* Only tick off an argument if we're not recursing. */
4886 if (depth == 0)
4887 cum->nargs_prototype--;
4889 if (TARGET_ALTIVEC_ABI
4890 && (ALTIVEC_VECTOR_MODE (mode)
4891 || (type && TREE_CODE (type) == VECTOR_TYPE
4892 && int_size_in_bytes (type) == 16)))
4894 bool stack = false;
4896 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
4898 cum->vregno++;
4899 if (!TARGET_ALTIVEC)
4900 error ("cannot pass argument in vector register because"
4901 " altivec instructions are disabled, use -maltivec"
4902 " to enable them");
4904 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4905 even if it is going to be passed in a vector register.
4906 Darwin does the same for variable-argument functions. */
4907 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
4908 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
4909 stack = true;
4911 else
4912 stack = true;
4914 if (stack)
4916 int align;
4918 /* Vector parameters must be 16-byte aligned. This places
4919 them at 2 mod 4 in terms of words in 32-bit mode, since
4920 the parameter save area starts at offset 24 from the
4921 stack. In 64-bit mode, they just have to start on an
4922 even word, since the parameter save area is 16-byte
4923 aligned. Space for GPRs is reserved even if the argument
4924 will be passed in memory. */
4925 if (TARGET_32BIT)
4926 align = (2 - cum->words) & 3;
4927 else
4928 align = cum->words & 1;
4929 cum->words += align + rs6000_arg_size (mode, type);
4931 if (TARGET_DEBUG_ARG)
4933 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
4934 cum->words, align);
4935 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
4936 cum->nargs_prototype, cum->prototype,
4937 GET_MODE_NAME (mode));
4941 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
4942 && !cum->stdarg
4943 && cum->sysv_gregno <= GP_ARG_MAX_REG)
4944 cum->sysv_gregno++;
4946 else if (rs6000_darwin64_abi
4947 && mode == BLKmode
4948 && TREE_CODE (type) == RECORD_TYPE
4949 && (size = int_size_in_bytes (type)) > 0)
4951 /* Variable sized types have size == -1 and are
4952 treated as if consisting entirely of ints.
4953 Pad to 16 byte boundary if needed. */
4954 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4955 && (cum->words % 2) != 0)
4956 cum->words++;
4957 /* For varargs, we can just go up by the size of the struct. */
4958 if (!named)
4959 cum->words += (size + 7) / 8;
4960 else
4962 /* It is tempting to say int register count just goes up by
4963 sizeof(type)/8, but this is wrong in a case such as
4964 { int; double; int; } [powerpc alignment]. We have to
4965 grovel through the fields for these too. */
4966 cum->intoffset = 0;
4967 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
4968 rs6000_darwin64_record_arg_advance_flush (cum,
4969 size * BITS_PER_UNIT);
4972 else if (DEFAULT_ABI == ABI_V4)
4974 if (TARGET_HARD_FLOAT && TARGET_FPRS
4975 && (mode == SFmode || mode == DFmode
4976 || (mode == TFmode && !TARGET_IEEEQUAD)))
4978 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
4979 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4980 else
4982 cum->fregno = FP_ARG_V4_MAX_REG + 1;
4983 if (mode == DFmode || mode == TFmode)
4984 cum->words += cum->words & 1;
4985 cum->words += rs6000_arg_size (mode, type);
4988 else
4990 int n_words = rs6000_arg_size (mode, type);
4991 int gregno = cum->sysv_gregno;
4993 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4994 (r7,r8) or (r9,r10). As does any other 2 word item such
4995 as complex int due to a historical mistake. */
4996 if (n_words == 2)
4997 gregno += (1 - gregno) & 1;
4999 /* Multi-reg args are not split between registers and stack. */
5000 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5002 /* Long long and SPE vectors are aligned on the stack.
5003 So are other 2 word items such as complex int due to
5004 a historical mistake. */
5005 if (n_words == 2)
5006 cum->words += cum->words & 1;
5007 cum->words += n_words;
5010 /* Note: continuing to accumulate gregno past when we've started
5011 spilling to the stack indicates the fact that we've started
5012 spilling to the stack to expand_builtin_saveregs. */
5013 cum->sysv_gregno = gregno + n_words;
5016 if (TARGET_DEBUG_ARG)
5018 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5019 cum->words, cum->fregno);
5020 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
5021 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
5022 fprintf (stderr, "mode = %4s, named = %d\n",
5023 GET_MODE_NAME (mode), named);
5026 else
5028 int n_words = rs6000_arg_size (mode, type);
5029 int start_words = cum->words;
5030 int align_words = rs6000_parm_start (mode, type, start_words);
5032 cum->words = align_words + n_words;
5034 if (SCALAR_FLOAT_MODE_P (mode)
5035 && !DECIMAL_FLOAT_MODE_P (mode)
5036 && TARGET_HARD_FLOAT && TARGET_FPRS)
5037 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5039 if (TARGET_DEBUG_ARG)
5041 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5042 cum->words, cum->fregno);
5043 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
5044 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
5045 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
5046 named, align_words - start_words, depth);
5051 static rtx
5052 spe_build_register_parallel (enum machine_mode mode, int gregno)
5054 rtx r1, r3, r5, r7;
5056 switch (mode)
5058 case DFmode:
5059 r1 = gen_rtx_REG (DImode, gregno);
5060 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5061 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
5063 case DCmode:
5064 case TFmode:
5065 r1 = gen_rtx_REG (DImode, gregno);
5066 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5067 r3 = gen_rtx_REG (DImode, gregno + 2);
5068 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5069 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
5071 case TCmode:
5072 r1 = gen_rtx_REG (DImode, gregno);
5073 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5074 r3 = gen_rtx_REG (DImode, gregno + 2);
5075 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5076 r5 = gen_rtx_REG (DImode, gregno + 4);
5077 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
5078 r7 = gen_rtx_REG (DImode, gregno + 6);
5079 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
5080 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
5082 default:
5083 gcc_unreachable ();
5087 /* Determine where to put a SIMD argument on the SPE. */
5088 static rtx
5089 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5090 tree type)
5092 int gregno = cum->sysv_gregno;
5094 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5095 are passed and returned in a pair of GPRs for ABI compatibility. */
5096 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode
5097 || mode == TFmode || mode == TCmode))
5099 int n_words = rs6000_arg_size (mode, type);
5101 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5102 if (mode == DFmode)
5103 gregno += (1 - gregno) & 1;
5105 /* Multi-reg args are not split between registers and stack. */
5106 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5107 return NULL_RTX;
5109 return spe_build_register_parallel (mode, gregno);
5111 if (cum->stdarg)
5113 int n_words = rs6000_arg_size (mode, type);
5115 /* SPE vectors are put in odd registers. */
5116 if (n_words == 2 && (gregno & 1) == 0)
5117 gregno += 1;
5119 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
5121 rtx r1, r2;
5122 enum machine_mode m = SImode;
5124 r1 = gen_rtx_REG (m, gregno);
5125 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
5126 r2 = gen_rtx_REG (m, gregno + 1);
5127 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
5128 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
5130 else
5131 return NULL_RTX;
5133 else
5135 if (gregno <= GP_ARG_MAX_REG)
5136 return gen_rtx_REG (mode, gregno);
5137 else
5138 return NULL_RTX;
5142 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5143 structure between cum->intoffset and bitpos to integer registers. */
5145 static void
5146 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
5147 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
5149 enum machine_mode mode;
5150 unsigned int regno;
5151 unsigned int startbit, endbit;
5152 int this_regno, intregs, intoffset;
5153 rtx reg;
5155 if (cum->intoffset == -1)
5156 return;
5158 intoffset = cum->intoffset;
5159 cum->intoffset = -1;
5161 /* If this is the trailing part of a word, try to only load that
5162 much into the register. Otherwise load the whole register. Note
5163 that in the latter case we may pick up unwanted bits. It's not a
5164 problem at the moment but may wish to revisit. */
5166 if (intoffset % BITS_PER_WORD != 0)
5168 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5169 MODE_INT, 0);
5170 if (mode == BLKmode)
5172 /* We couldn't find an appropriate mode, which happens,
5173 e.g., in packed structs when there are 3 bytes to load.
5174 Back intoffset back to the beginning of the word in this
5175 case. */
5176 intoffset = intoffset & -BITS_PER_WORD;
5177 mode = word_mode;
5180 else
5181 mode = word_mode;
5183 startbit = intoffset & -BITS_PER_WORD;
5184 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5185 intregs = (endbit - startbit) / BITS_PER_WORD;
5186 this_regno = cum->words + intoffset / BITS_PER_WORD;
5188 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
5189 cum->use_stack = 1;
5191 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
5192 if (intregs <= 0)
5193 return;
5195 intoffset /= BITS_PER_UNIT;
5198 regno = GP_ARG_MIN_REG + this_regno;
5199 reg = gen_rtx_REG (mode, regno);
5200 rvec[(*k)++] =
5201 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
5203 this_regno += 1;
5204 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
5205 mode = word_mode;
5206 intregs -= 1;
5208 while (intregs > 0);
5211 /* Recursive workhorse for the following. */
5213 static void
5214 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
5215 HOST_WIDE_INT startbitpos, rtx rvec[],
5216 int *k)
5218 tree f;
5220 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5221 if (TREE_CODE (f) == FIELD_DECL)
5223 HOST_WIDE_INT bitpos = startbitpos;
5224 tree ftype = TREE_TYPE (f);
5225 enum machine_mode mode;
5226 if (ftype == error_mark_node)
5227 continue;
5228 mode = TYPE_MODE (ftype);
5230 if (DECL_SIZE (f) != 0
5231 && host_integerp (bit_position (f), 1))
5232 bitpos += int_bit_position (f);
5234 /* ??? FIXME: else assume zero offset. */
5236 if (TREE_CODE (ftype) == RECORD_TYPE)
5237 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
5238 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
5240 #if 0
5241 switch (mode)
5243 case SCmode: mode = SFmode; break;
5244 case DCmode: mode = DFmode; break;
5245 case TCmode: mode = TFmode; break;
5246 default: break;
5248 #endif
5249 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5250 rvec[(*k)++]
5251 = gen_rtx_EXPR_LIST (VOIDmode,
5252 gen_rtx_REG (mode, cum->fregno++),
5253 GEN_INT (bitpos / BITS_PER_UNIT));
5254 if (mode == TFmode)
5255 cum->fregno++;
5257 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
5259 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5260 rvec[(*k)++]
5261 = gen_rtx_EXPR_LIST (VOIDmode,
5262 gen_rtx_REG (mode, cum->vregno++),
5263 GEN_INT (bitpos / BITS_PER_UNIT));
5265 else if (cum->intoffset == -1)
5266 cum->intoffset = bitpos;
5270 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5271 the register(s) to be used for each field and subfield of a struct
5272 being passed by value, along with the offset of where the
5273 register's value may be found in the block. FP fields go in FP
5274 register, vector fields go in vector registers, and everything
5275 else goes in int registers, packed as in memory.
5277 This code is also used for function return values. RETVAL indicates
5278 whether this is the case.
5280 Much of this is taken from the SPARC V9 port, which has a similar
5281 calling convention. */
5283 static rtx
5284 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, tree type,
5285 int named, bool retval)
5287 rtx rvec[FIRST_PSEUDO_REGISTER];
5288 int k = 1, kbase = 1;
5289 HOST_WIDE_INT typesize = int_size_in_bytes (type);
5290 /* This is a copy; modifications are not visible to our caller. */
5291 CUMULATIVE_ARGS copy_cum = *orig_cum;
5292 CUMULATIVE_ARGS *cum = &copy_cum;
5294 /* Pad to 16 byte boundary if needed. */
5295 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5296 && (cum->words % 2) != 0)
5297 cum->words++;
5299 cum->intoffset = 0;
5300 cum->use_stack = 0;
5301 cum->named = named;
5303 /* Put entries into rvec[] for individual FP and vector fields, and
5304 for the chunks of memory that go in int regs. Note we start at
5305 element 1; 0 is reserved for an indication of using memory, and
5306 may or may not be filled in below. */
5307 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
5308 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
5310 /* If any part of the struct went on the stack put all of it there.
5311 This hack is because the generic code for
5312 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5313 parts of the struct are not at the beginning. */
5314 if (cum->use_stack)
5316 if (retval)
5317 return NULL_RTX; /* doesn't go in registers at all */
5318 kbase = 0;
5319 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5321 if (k > 1 || cum->use_stack)
5322 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
5323 else
5324 return NULL_RTX;
5327 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5329 static rtx
5330 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
5332 int n_units;
5333 int i, k;
5334 rtx rvec[GP_ARG_NUM_REG + 1];
5336 if (align_words >= GP_ARG_NUM_REG)
5337 return NULL_RTX;
5339 n_units = rs6000_arg_size (mode, type);
5341 /* Optimize the simple case where the arg fits in one gpr, except in
5342 the case of BLKmode due to assign_parms assuming that registers are
5343 BITS_PER_WORD wide. */
5344 if (n_units == 0
5345 || (n_units == 1 && mode != BLKmode))
5346 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5348 k = 0;
5349 if (align_words + n_units > GP_ARG_NUM_REG)
5350 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5351 using a magic NULL_RTX component.
5352 This is not strictly correct. Only some of the arg belongs in
5353 memory, not all of it. However, the normal scheme using
5354 function_arg_partial_nregs can result in unusual subregs, eg.
5355 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5356 store the whole arg to memory is often more efficient than code
5357 to store pieces, and we know that space is available in the right
5358 place for the whole arg. */
5359 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5361 i = 0;
5364 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
5365 rtx off = GEN_INT (i++ * 4);
5366 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5368 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
5370 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5373 /* Determine where to put an argument to a function.
5374 Value is zero to push the argument on the stack,
5375 or a hard register in which to store the argument.
5377 MODE is the argument's machine mode.
5378 TYPE is the data type of the argument (as a tree).
5379 This is null for libcalls where that information may
5380 not be available.
5381 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5382 the preceding args and about the function being called. It is
5383 not modified in this routine.
5384 NAMED is nonzero if this argument is a named parameter
5385 (otherwise it is an extra parameter matching an ellipsis).
5387 On RS/6000 the first eight words of non-FP are normally in registers
5388 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5389 Under V.4, the first 8 FP args are in registers.
5391 If this is floating-point and no prototype is specified, we use
5392 both an FP and integer register (or possibly FP reg and stack). Library
5393 functions (when CALL_LIBCALL is set) always have the proper types for args,
5394 so we can pass the FP value just in one register. emit_library_function
5395 doesn't support PARALLEL anyway.
5397 Note that for args passed by reference, function_arg will be called
5398 with MODE and TYPE set to that of the pointer to the arg, not the arg
5399 itself. */
5402 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5403 tree type, int named)
5405 enum rs6000_abi abi = DEFAULT_ABI;
5407 /* Return a marker to indicate whether CR1 needs to set or clear the
5408 bit that V.4 uses to say fp args were passed in registers.
5409 Assume that we don't need the marker for software floating point,
5410 or compiler generated library calls. */
5411 if (mode == VOIDmode)
5413 if (abi == ABI_V4
5414 && (cum->call_cookie & CALL_LIBCALL) == 0
5415 && (cum->stdarg
5416 || (cum->nargs_prototype < 0
5417 && (cum->prototype || TARGET_NO_PROTOTYPE))))
5419 /* For the SPE, we need to crxor CR6 always. */
5420 if (TARGET_SPE_ABI)
5421 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
5422 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
5423 return GEN_INT (cum->call_cookie
5424 | ((cum->fregno == FP_ARG_MIN_REG)
5425 ? CALL_V4_SET_FP_ARGS
5426 : CALL_V4_CLEAR_FP_ARGS));
5429 return GEN_INT (cum->call_cookie);
5432 if (rs6000_darwin64_abi && mode == BLKmode
5433 && TREE_CODE (type) == RECORD_TYPE)
5435 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
5436 if (rslt != NULL_RTX)
5437 return rslt;
5438 /* Else fall through to usual handling. */
5441 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
5442 if (TARGET_64BIT && ! cum->prototype)
5444 /* Vector parameters get passed in vector register
5445 and also in GPRs or memory, in absence of prototype. */
5446 int align_words;
5447 rtx slot;
5448 align_words = (cum->words + 1) & ~1;
5450 if (align_words >= GP_ARG_NUM_REG)
5452 slot = NULL_RTX;
5454 else
5456 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5458 return gen_rtx_PARALLEL (mode,
5459 gen_rtvec (2,
5460 gen_rtx_EXPR_LIST (VOIDmode,
5461 slot, const0_rtx),
5462 gen_rtx_EXPR_LIST (VOIDmode,
5463 gen_rtx_REG (mode, cum->vregno),
5464 const0_rtx)));
5466 else
5467 return gen_rtx_REG (mode, cum->vregno);
5468 else if (TARGET_ALTIVEC_ABI
5469 && (ALTIVEC_VECTOR_MODE (mode)
5470 || (type && TREE_CODE (type) == VECTOR_TYPE
5471 && int_size_in_bytes (type) == 16)))
5473 if (named || abi == ABI_V4)
5474 return NULL_RTX;
5475 else
5477 /* Vector parameters to varargs functions under AIX or Darwin
5478 get passed in memory and possibly also in GPRs. */
5479 int align, align_words, n_words;
5480 enum machine_mode part_mode;
5482 /* Vector parameters must be 16-byte aligned. This places them at
5483 2 mod 4 in terms of words in 32-bit mode, since the parameter
5484 save area starts at offset 24 from the stack. In 64-bit mode,
5485 they just have to start on an even word, since the parameter
5486 save area is 16-byte aligned. */
5487 if (TARGET_32BIT)
5488 align = (2 - cum->words) & 3;
5489 else
5490 align = cum->words & 1;
5491 align_words = cum->words + align;
5493 /* Out of registers? Memory, then. */
5494 if (align_words >= GP_ARG_NUM_REG)
5495 return NULL_RTX;
5497 if (TARGET_32BIT && TARGET_POWERPC64)
5498 return rs6000_mixed_function_arg (mode, type, align_words);
5500 /* The vector value goes in GPRs. Only the part of the
5501 value in GPRs is reported here. */
5502 part_mode = mode;
5503 n_words = rs6000_arg_size (mode, type);
5504 if (align_words + n_words > GP_ARG_NUM_REG)
5505 /* Fortunately, there are only two possibilities, the value
5506 is either wholly in GPRs or half in GPRs and half not. */
5507 part_mode = DImode;
5509 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
5512 else if (TARGET_SPE_ABI && TARGET_SPE
5513 && (SPE_VECTOR_MODE (mode)
5514 || (TARGET_E500_DOUBLE && (mode == DFmode
5515 || mode == DCmode
5516 || mode == TFmode
5517 || mode == TCmode))))
5518 return rs6000_spe_function_arg (cum, mode, type);
5520 else if (abi == ABI_V4)
5522 if (TARGET_HARD_FLOAT && TARGET_FPRS
5523 && (mode == SFmode || mode == DFmode
5524 || (mode == TFmode && !TARGET_IEEEQUAD)))
5526 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
5527 return gen_rtx_REG (mode, cum->fregno);
5528 else
5529 return NULL_RTX;
5531 else
5533 int n_words = rs6000_arg_size (mode, type);
5534 int gregno = cum->sysv_gregno;
5536 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5537 (r7,r8) or (r9,r10). As does any other 2 word item such
5538 as complex int due to a historical mistake. */
5539 if (n_words == 2)
5540 gregno += (1 - gregno) & 1;
5542 /* Multi-reg args are not split between registers and stack. */
5543 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5544 return NULL_RTX;
5546 if (TARGET_32BIT && TARGET_POWERPC64)
5547 return rs6000_mixed_function_arg (mode, type,
5548 gregno - GP_ARG_MIN_REG);
5549 return gen_rtx_REG (mode, gregno);
5552 else
5554 int align_words = rs6000_parm_start (mode, type, cum->words);
5556 if (USE_FP_FOR_ARG_P (cum, mode, type))
5558 rtx rvec[GP_ARG_NUM_REG + 1];
5559 rtx r;
5560 int k;
5561 bool needs_psave;
5562 enum machine_mode fmode = mode;
5563 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
5565 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
5567 /* Currently, we only ever need one reg here because complex
5568 doubles are split. */
5569 gcc_assert (cum->fregno == FP_ARG_MAX_REG && fmode == TFmode);
5571 /* Long double split over regs and memory. */
5572 fmode = DFmode;
5575 /* Do we also need to pass this arg in the parameter save
5576 area? */
5577 needs_psave = (type
5578 && (cum->nargs_prototype <= 0
5579 || (DEFAULT_ABI == ABI_AIX
5580 && TARGET_XL_COMPAT
5581 && align_words >= GP_ARG_NUM_REG)));
5583 if (!needs_psave && mode == fmode)
5584 return gen_rtx_REG (fmode, cum->fregno);
5586 k = 0;
5587 if (needs_psave)
5589 /* Describe the part that goes in gprs or the stack.
5590 This piece must come first, before the fprs. */
5591 if (align_words < GP_ARG_NUM_REG)
5593 unsigned long n_words = rs6000_arg_size (mode, type);
5595 if (align_words + n_words > GP_ARG_NUM_REG
5596 || (TARGET_32BIT && TARGET_POWERPC64))
5598 /* If this is partially on the stack, then we only
5599 include the portion actually in registers here. */
5600 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
5601 rtx off;
5602 int i = 0;
5603 if (align_words + n_words > GP_ARG_NUM_REG)
5604 /* Not all of the arg fits in gprs. Say that it
5605 goes in memory too, using a magic NULL_RTX
5606 component. Also see comment in
5607 rs6000_mixed_function_arg for why the normal
5608 function_arg_partial_nregs scheme doesn't work
5609 in this case. */
5610 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
5611 const0_rtx);
5614 r = gen_rtx_REG (rmode,
5615 GP_ARG_MIN_REG + align_words);
5616 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
5617 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5619 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
5621 else
5623 /* The whole arg fits in gprs. */
5624 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5625 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5628 else
5629 /* It's entirely in memory. */
5630 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5633 /* Describe where this piece goes in the fprs. */
5634 r = gen_rtx_REG (fmode, cum->fregno);
5635 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5637 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5639 else if (align_words < GP_ARG_NUM_REG)
5641 if (TARGET_32BIT && TARGET_POWERPC64)
5642 return rs6000_mixed_function_arg (mode, type, align_words);
5644 if (mode == BLKmode)
5645 mode = Pmode;
5647 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5649 else
5650 return NULL_RTX;
5654 /* For an arg passed partly in registers and partly in memory, this is
5655 the number of bytes passed in registers. For args passed entirely in
5656 registers or entirely in memory, zero. When an arg is described by a
5657 PARALLEL, perhaps using more than one register type, this function
5658 returns the number of bytes used by the first element of the PARALLEL. */
5660 static int
5661 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5662 tree type, bool named)
5664 int ret = 0;
5665 int align_words;
5667 if (DEFAULT_ABI == ABI_V4)
5668 return 0;
5670 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
5671 && cum->nargs_prototype >= 0)
5672 return 0;
5674 /* In this complicated case we just disable the partial_nregs code. */
5675 if (rs6000_darwin64_abi && mode == BLKmode
5676 && TREE_CODE (type) == RECORD_TYPE
5677 && int_size_in_bytes (type) > 0)
5678 return 0;
5680 align_words = rs6000_parm_start (mode, type, cum->words);
5682 if (USE_FP_FOR_ARG_P (cum, mode, type))
5684 /* If we are passing this arg in the fixed parameter save area
5685 (gprs or memory) as well as fprs, then this function should
5686 return the number of partial bytes passed in the parameter
5687 save area rather than partial bytes passed in fprs. */
5688 if (type
5689 && (cum->nargs_prototype <= 0
5690 || (DEFAULT_ABI == ABI_AIX
5691 && TARGET_XL_COMPAT
5692 && align_words >= GP_ARG_NUM_REG)))
5693 return 0;
5694 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
5695 > FP_ARG_MAX_REG + 1)
5696 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
5697 else if (cum->nargs_prototype >= 0)
5698 return 0;
5701 if (align_words < GP_ARG_NUM_REG
5702 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
5703 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
5705 if (ret != 0 && TARGET_DEBUG_ARG)
5706 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
5708 return ret;
5711 /* A C expression that indicates when an argument must be passed by
5712 reference. If nonzero for an argument, a copy of that argument is
5713 made in memory and a pointer to the argument is passed instead of
5714 the argument itself. The pointer is passed in whatever way is
5715 appropriate for passing a pointer to that type.
5717 Under V.4, aggregates and long double are passed by reference.
5719 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5720 reference unless the AltiVec vector extension ABI is in force.
5722 As an extension to all ABIs, variable sized types are passed by
5723 reference. */
5725 static bool
5726 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5727 enum machine_mode mode, tree type,
5728 bool named ATTRIBUTE_UNUSED)
5730 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
5732 if (TARGET_DEBUG_ARG)
5733 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
5734 return 1;
5737 if (!type)
5738 return 0;
5740 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
5742 if (TARGET_DEBUG_ARG)
5743 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
5744 return 1;
5747 if (int_size_in_bytes (type) < 0)
5749 if (TARGET_DEBUG_ARG)
5750 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
5751 return 1;
5754 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5755 modes only exist for GCC vector types if -maltivec. */
5756 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
5758 if (TARGET_DEBUG_ARG)
5759 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
5760 return 1;
5763 /* Pass synthetic vectors in memory. */
5764 if (TREE_CODE (type) == VECTOR_TYPE
5765 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
5767 static bool warned_for_pass_big_vectors = false;
5768 if (TARGET_DEBUG_ARG)
5769 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
5770 if (!warned_for_pass_big_vectors)
5772 warning (0, "GCC vector passed by reference: "
5773 "non-standard ABI extension with no compatibility guarantee");
5774 warned_for_pass_big_vectors = true;
5776 return 1;
5779 return 0;
5782 static void
5783 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
5785 int i;
5786 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
5788 if (nregs == 0)
5789 return;
5791 for (i = 0; i < nregs; i++)
5793 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
5794 if (reload_completed)
5796 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
5797 tem = NULL_RTX;
5798 else
5799 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
5800 i * GET_MODE_SIZE (reg_mode));
5802 else
5803 tem = replace_equiv_address (tem, XEXP (tem, 0));
5805 gcc_assert (tem);
5807 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
5811 /* Perform any needed actions needed for a function that is receiving a
5812 variable number of arguments.
5814 CUM is as above.
5816 MODE and TYPE are the mode and type of the current parameter.
5818 PRETEND_SIZE is a variable that should be set to the amount of stack
5819 that must be pushed by the prolog to pretend that our caller pushed
5822 Normally, this macro will push all remaining incoming registers on the
5823 stack and set PRETEND_SIZE to the length of the registers pushed. */
5825 static void
5826 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5827 tree type, int *pretend_size ATTRIBUTE_UNUSED,
5828 int no_rtl)
5830 CUMULATIVE_ARGS next_cum;
5831 int reg_size = TARGET_32BIT ? 4 : 8;
5832 rtx save_area = NULL_RTX, mem;
5833 int first_reg_offset, set;
5835 /* Skip the last named argument. */
5836 next_cum = *cum;
5837 function_arg_advance (&next_cum, mode, type, 1, 0);
5839 if (DEFAULT_ABI == ABI_V4)
5841 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
5843 if (! no_rtl)
5845 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
5846 HOST_WIDE_INT offset = 0;
5848 /* Try to optimize the size of the varargs save area.
5849 The ABI requires that ap.reg_save_area is doubleword
5850 aligned, but we don't need to allocate space for all
5851 the bytes, only those to which we actually will save
5852 anything. */
5853 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
5854 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
5855 if (TARGET_HARD_FLOAT && TARGET_FPRS
5856 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5857 && cfun->va_list_fpr_size)
5859 if (gpr_reg_num)
5860 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
5861 * UNITS_PER_FP_WORD;
5862 if (cfun->va_list_fpr_size
5863 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5864 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
5865 else
5866 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5867 * UNITS_PER_FP_WORD;
5869 if (gpr_reg_num)
5871 offset = -((first_reg_offset * reg_size) & ~7);
5872 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
5874 gpr_reg_num = cfun->va_list_gpr_size;
5875 if (reg_size == 4 && (first_reg_offset & 1))
5876 gpr_reg_num++;
5878 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
5880 else if (fpr_size)
5881 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
5882 * UNITS_PER_FP_WORD
5883 - (int) (GP_ARG_NUM_REG * reg_size);
5885 if (gpr_size + fpr_size)
5887 rtx reg_save_area
5888 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
5889 gcc_assert (GET_CODE (reg_save_area) == MEM);
5890 reg_save_area = XEXP (reg_save_area, 0);
5891 if (GET_CODE (reg_save_area) == PLUS)
5893 gcc_assert (XEXP (reg_save_area, 0)
5894 == virtual_stack_vars_rtx);
5895 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
5896 offset += INTVAL (XEXP (reg_save_area, 1));
5898 else
5899 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
5902 cfun->machine->varargs_save_offset = offset;
5903 save_area = plus_constant (virtual_stack_vars_rtx, offset);
5906 else
5908 first_reg_offset = next_cum.words;
5909 save_area = virtual_incoming_args_rtx;
5911 if (targetm.calls.must_pass_in_stack (mode, type))
5912 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
5915 set = get_varargs_alias_set ();
5916 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
5917 && cfun->va_list_gpr_size)
5919 int nregs = GP_ARG_NUM_REG - first_reg_offset;
5921 if (va_list_gpr_counter_field)
5923 /* V4 va_list_gpr_size counts number of registers needed. */
5924 if (nregs > cfun->va_list_gpr_size)
5925 nregs = cfun->va_list_gpr_size;
5927 else
5929 /* char * va_list instead counts number of bytes needed. */
5930 if (nregs > cfun->va_list_gpr_size / reg_size)
5931 nregs = cfun->va_list_gpr_size / reg_size;
5934 mem = gen_rtx_MEM (BLKmode,
5935 plus_constant (save_area,
5936 first_reg_offset * reg_size));
5937 MEM_NOTRAP_P (mem) = 1;
5938 set_mem_alias_set (mem, set);
5939 set_mem_align (mem, BITS_PER_WORD);
5941 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
5942 nregs);
5945 /* Save FP registers if needed. */
5946 if (DEFAULT_ABI == ABI_V4
5947 && TARGET_HARD_FLOAT && TARGET_FPRS
5948 && ! no_rtl
5949 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5950 && cfun->va_list_fpr_size)
5952 int fregno = next_cum.fregno, nregs;
5953 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
5954 rtx lab = gen_label_rtx ();
5955 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
5956 * UNITS_PER_FP_WORD);
5958 emit_jump_insn
5959 (gen_rtx_SET (VOIDmode,
5960 pc_rtx,
5961 gen_rtx_IF_THEN_ELSE (VOIDmode,
5962 gen_rtx_NE (VOIDmode, cr1,
5963 const0_rtx),
5964 gen_rtx_LABEL_REF (VOIDmode, lab),
5965 pc_rtx)));
5967 for (nregs = 0;
5968 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
5969 fregno++, off += UNITS_PER_FP_WORD, nregs++)
5971 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
5972 MEM_NOTRAP_P (mem) = 1;
5973 set_mem_alias_set (mem, set);
5974 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
5975 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
5978 emit_label (lab);
5982 /* Create the va_list data type. */
5984 static tree
5985 rs6000_build_builtin_va_list (void)
5987 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
5989 /* For AIX, prefer 'char *' because that's what the system
5990 header files like. */
5991 if (DEFAULT_ABI != ABI_V4)
5992 return build_pointer_type (char_type_node);
5994 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5995 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5997 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
5998 unsigned_char_type_node);
5999 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
6000 unsigned_char_type_node);
6001 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6002 every user file. */
6003 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
6004 short_unsigned_type_node);
6005 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
6006 ptr_type_node);
6007 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
6008 ptr_type_node);
6010 va_list_gpr_counter_field = f_gpr;
6011 va_list_fpr_counter_field = f_fpr;
6013 DECL_FIELD_CONTEXT (f_gpr) = record;
6014 DECL_FIELD_CONTEXT (f_fpr) = record;
6015 DECL_FIELD_CONTEXT (f_res) = record;
6016 DECL_FIELD_CONTEXT (f_ovf) = record;
6017 DECL_FIELD_CONTEXT (f_sav) = record;
6019 TREE_CHAIN (record) = type_decl;
6020 TYPE_NAME (record) = type_decl;
6021 TYPE_FIELDS (record) = f_gpr;
6022 TREE_CHAIN (f_gpr) = f_fpr;
6023 TREE_CHAIN (f_fpr) = f_res;
6024 TREE_CHAIN (f_res) = f_ovf;
6025 TREE_CHAIN (f_ovf) = f_sav;
6027 layout_type (record);
6029 /* The correct type is an array type of one element. */
6030 return build_array_type (record, build_index_type (size_zero_node));
6033 /* Implement va_start. */
6035 void
6036 rs6000_va_start (tree valist, rtx nextarg)
6038 HOST_WIDE_INT words, n_gpr, n_fpr;
6039 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6040 tree gpr, fpr, ovf, sav, t;
6042 /* Only SVR4 needs something special. */
6043 if (DEFAULT_ABI != ABI_V4)
6045 std_expand_builtin_va_start (valist, nextarg);
6046 return;
6049 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6050 f_fpr = TREE_CHAIN (f_gpr);
6051 f_res = TREE_CHAIN (f_fpr);
6052 f_ovf = TREE_CHAIN (f_res);
6053 f_sav = TREE_CHAIN (f_ovf);
6055 valist = build_va_arg_indirect_ref (valist);
6056 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6057 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6058 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6059 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6061 /* Count number of gp and fp argument registers used. */
6062 words = current_function_args_info.words;
6063 n_gpr = MIN (current_function_args_info.sysv_gregno - GP_ARG_MIN_REG,
6064 GP_ARG_NUM_REG);
6065 n_fpr = MIN (current_function_args_info.fregno - FP_ARG_MIN_REG,
6066 FP_ARG_NUM_REG);
6068 if (TARGET_DEBUG_ARG)
6069 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
6070 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
6071 words, n_gpr, n_fpr);
6073 if (cfun->va_list_gpr_size)
6075 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr,
6076 build_int_cst (NULL_TREE, n_gpr));
6077 TREE_SIDE_EFFECTS (t) = 1;
6078 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6081 if (cfun->va_list_fpr_size)
6083 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr,
6084 build_int_cst (NULL_TREE, n_fpr));
6085 TREE_SIDE_EFFECTS (t) = 1;
6086 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6089 /* Find the overflow area. */
6090 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6091 if (words != 0)
6092 t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t,
6093 build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
6094 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6095 TREE_SIDE_EFFECTS (t) = 1;
6096 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6098 /* If there were no va_arg invocations, don't set up the register
6099 save area. */
6100 if (!cfun->va_list_gpr_size
6101 && !cfun->va_list_fpr_size
6102 && n_gpr < GP_ARG_NUM_REG
6103 && n_fpr < FP_ARG_V4_MAX_REG)
6104 return;
6106 /* Find the register save area. */
6107 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
6108 if (cfun->machine->varargs_save_offset)
6109 t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
6110 build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
6111 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
6112 TREE_SIDE_EFFECTS (t) = 1;
6113 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6116 /* Implement va_arg. */
6118 tree
6119 rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
6121 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6122 tree gpr, fpr, ovf, sav, reg, t, u;
6123 int size, rsize, n_reg, sav_ofs, sav_scale;
6124 tree lab_false, lab_over, addr;
6125 int align;
6126 tree ptrtype = build_pointer_type (type);
6128 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
6130 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
6131 return build_va_arg_indirect_ref (t);
6134 if (DEFAULT_ABI != ABI_V4)
6136 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
6138 tree elem_type = TREE_TYPE (type);
6139 enum machine_mode elem_mode = TYPE_MODE (elem_type);
6140 int elem_size = GET_MODE_SIZE (elem_mode);
6142 if (elem_size < UNITS_PER_WORD)
6144 tree real_part, imag_part;
6145 tree post = NULL_TREE;
6147 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6148 &post);
6149 /* Copy the value into a temporary, lest the formal temporary
6150 be reused out from under us. */
6151 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
6152 append_to_statement_list (post, pre_p);
6154 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6155 post_p);
6157 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
6161 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6164 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6165 f_fpr = TREE_CHAIN (f_gpr);
6166 f_res = TREE_CHAIN (f_fpr);
6167 f_ovf = TREE_CHAIN (f_res);
6168 f_sav = TREE_CHAIN (f_ovf);
6170 valist = build_va_arg_indirect_ref (valist);
6171 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6172 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6173 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6174 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6176 size = int_size_in_bytes (type);
6177 rsize = (size + 3) / 4;
6178 align = 1;
6180 if (TARGET_HARD_FLOAT && TARGET_FPRS
6181 && (TYPE_MODE (type) == SFmode
6182 || TYPE_MODE (type) == DFmode
6183 || TYPE_MODE (type) == TFmode))
6185 /* FP args go in FP registers, if present. */
6186 reg = fpr;
6187 n_reg = (size + 7) / 8;
6188 sav_ofs = 8*4;
6189 sav_scale = 8;
6190 if (TYPE_MODE (type) != SFmode)
6191 align = 8;
6193 else
6195 /* Otherwise into GP registers. */
6196 reg = gpr;
6197 n_reg = rsize;
6198 sav_ofs = 0;
6199 sav_scale = 4;
6200 if (n_reg == 2)
6201 align = 8;
6204 /* Pull the value out of the saved registers.... */
6206 lab_over = NULL;
6207 addr = create_tmp_var (ptr_type_node, "addr");
6208 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
6210 /* AltiVec vectors never go in registers when -mabi=altivec. */
6211 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6212 align = 16;
6213 else
6215 lab_false = create_artificial_label ();
6216 lab_over = create_artificial_label ();
6218 /* Long long and SPE vectors are aligned in the registers.
6219 As are any other 2 gpr item such as complex int due to a
6220 historical mistake. */
6221 u = reg;
6222 if (n_reg == 2 && reg == gpr)
6224 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
6225 size_int (n_reg - 1));
6226 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
6229 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
6230 t = build2 (GE_EXPR, boolean_type_node, u, t);
6231 u = build1 (GOTO_EXPR, void_type_node, lab_false);
6232 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
6233 gimplify_and_add (t, pre_p);
6235 t = sav;
6236 if (sav_ofs)
6237 t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
6239 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
6240 u = build1 (CONVERT_EXPR, integer_type_node, u);
6241 u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
6242 t = build2 (PLUS_EXPR, ptr_type_node, t, u);
6244 t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6245 gimplify_and_add (t, pre_p);
6247 t = build1 (GOTO_EXPR, void_type_node, lab_over);
6248 gimplify_and_add (t, pre_p);
6250 t = build1 (LABEL_EXPR, void_type_node, lab_false);
6251 append_to_statement_list (t, pre_p);
6253 if ((n_reg == 2 && reg != gpr) || n_reg > 2)
6255 /* Ensure that we don't find any more args in regs.
6256 Alignment has taken care of the n_reg == 2 gpr case. */
6257 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (reg), reg, size_int (8));
6258 gimplify_and_add (t, pre_p);
6262 /* ... otherwise out of the overflow area. */
6264 /* Care for on-stack alignment if needed. */
6265 t = ovf;
6266 if (align != 1)
6268 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
6269 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
6270 build_int_cst (NULL_TREE, -align));
6272 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
6274 u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
6275 gimplify_and_add (u, pre_p);
6277 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
6278 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
6279 gimplify_and_add (t, pre_p);
6281 if (lab_over)
6283 t = build1 (LABEL_EXPR, void_type_node, lab_over);
6284 append_to_statement_list (t, pre_p);
6287 if (STRICT_ALIGNMENT
6288 && (TYPE_ALIGN (type)
6289 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
6291 /* The value (of type complex double, for example) may not be
6292 aligned in memory in the saved registers, so copy via a
6293 temporary. (This is the same code as used for SPARC.) */
6294 tree tmp = create_tmp_var (type, "va_arg_tmp");
6295 tree dest_addr = build_fold_addr_expr (tmp);
6297 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
6298 3, dest_addr, addr, size_int (rsize * 4));
6300 gimplify_and_add (copy, pre_p);
6301 addr = dest_addr;
6304 addr = fold_convert (ptrtype, addr);
6305 return build_va_arg_indirect_ref (addr);
6308 /* Builtins. */
6310 static void
6311 def_builtin (int mask, const char *name, tree type, int code)
6313 if (mask & target_flags)
6315 if (rs6000_builtin_decls[code])
6316 abort ();
6318 rs6000_builtin_decls[code] =
6319 add_builtin_function (name, type, code, BUILT_IN_MD,
6320 NULL, NULL_TREE);
6324 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6326 static const struct builtin_description bdesc_3arg[] =
6328 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
6329 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
6330 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
6331 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
6332 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
6333 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
6334 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
6335 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
6336 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
6337 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
6338 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
6339 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
6340 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
6341 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
6342 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
6343 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
6344 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
6345 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
6346 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
6347 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
6348 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
6349 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
6350 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
6352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
6353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
6354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
6355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
6356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
6357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
6358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
6359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
6360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
6361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
6362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
6363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
6364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
6365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
6366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
6369 /* DST operations: void foo (void *, const int, const char). */
6371 static const struct builtin_description bdesc_dst[] =
6373 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
6374 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
6375 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
6376 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
6378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
6379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
6380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
6381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
6384 /* Simple binary operations: VECc = foo (VECa, VECb). */
6386 static struct builtin_description bdesc_2arg[] =
6388 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
6389 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
6390 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
6391 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
6392 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
6393 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
6394 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
6395 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
6396 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
6397 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
6398 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
6399 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
6400 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
6401 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
6402 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
6403 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
6404 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
6405 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
6406 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
6407 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
6408 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
6409 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
6410 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
6411 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
6412 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
6413 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
6414 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
6415 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
6416 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
6417 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
6418 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
6419 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
6420 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
6421 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
6422 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
6423 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
6424 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
6425 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
6426 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
6427 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
6428 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
6429 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
6430 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
6431 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
6432 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
6433 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
6434 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
6435 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
6436 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
6437 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
6438 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
6439 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
6440 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
6441 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
6442 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
6443 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
6444 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
6445 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
6446 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
6447 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
6448 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
6449 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
6450 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
6451 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
6452 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
6453 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
6454 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
6455 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
6456 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
6457 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
6458 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
6459 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
6460 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
6461 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
6462 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
6463 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
6464 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
6465 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
6466 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
6467 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
6468 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
6469 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
6470 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
6471 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
6472 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
6473 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
6474 { MASK_ALTIVEC, CODE_FOR_lshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
6475 { MASK_ALTIVEC, CODE_FOR_lshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
6476 { MASK_ALTIVEC, CODE_FOR_lshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
6477 { MASK_ALTIVEC, CODE_FOR_ashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
6478 { MASK_ALTIVEC, CODE_FOR_ashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
6479 { MASK_ALTIVEC, CODE_FOR_ashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
6480 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
6481 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
6482 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
6483 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
6484 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
6485 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
6486 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
6487 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
6488 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
6489 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
6490 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
6491 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
6492 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
6493 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
6494 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
6495 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
6496 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
6497 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
6498 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
6500 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
6501 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
6502 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
6503 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
6504 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
6505 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
6506 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
6507 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
6508 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
6509 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
6510 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
6511 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
6512 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
6513 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
6514 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
6515 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
6516 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
6517 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
6518 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
6519 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
6520 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
6521 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
6522 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
6523 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
6524 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
6525 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
6526 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
6527 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
6528 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
6529 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
6530 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
6531 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
6532 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
6533 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
6534 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
6535 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
6536 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
6537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
6538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
6539 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
6540 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
6541 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
6542 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
6543 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
6544 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
6545 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
6546 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
6547 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
6548 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
6549 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
6550 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
6551 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
6552 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
6553 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
6554 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
6555 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
6556 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
6557 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
6558 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
6559 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
6560 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
6561 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
6562 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
6563 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
6564 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
6565 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
6566 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
6567 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
6568 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
6569 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
6570 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
6571 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
6572 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
6573 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
6574 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
6575 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
6576 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
6577 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
6578 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
6579 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
6580 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
6581 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
6582 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
6583 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
6584 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
6585 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
6586 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
6587 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
6588 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
6589 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
6590 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
6591 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
6592 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
6593 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
6594 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
6595 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
6596 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
6597 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
6598 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
6599 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
6600 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
6601 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
6602 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
6603 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
6604 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
6605 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
6606 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
6607 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
6608 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
6609 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
6610 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
6611 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
6612 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
6613 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
6614 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
6615 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
6616 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
6617 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
6618 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
6619 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
6620 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
6621 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
6622 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
6623 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
6624 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
6625 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
6626 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
6628 /* Place holder, leave as first spe builtin. */
6629 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
6630 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
6631 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
6632 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
6633 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
6634 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
6635 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
6636 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
6637 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
6638 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
6639 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
6640 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
6641 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
6642 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
6643 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
6644 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
6645 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
6646 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
6647 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
6648 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
6649 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
6650 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
6651 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
6652 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
6653 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
6654 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
6655 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
6656 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
6657 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
6658 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
6659 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
6660 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
6661 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
6662 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
6663 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
6664 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
6665 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
6666 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
6667 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
6668 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
6669 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
6670 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
6671 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
6672 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
6673 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
6674 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
6675 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
6676 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
6677 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
6678 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
6679 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
6680 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
6681 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
6682 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
6683 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
6684 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
6685 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
6686 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
6687 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
6688 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
6689 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
6690 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
6691 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
6692 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
6693 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
6694 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
6695 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
6696 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
6697 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
6698 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
6699 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
6700 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
6701 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
6702 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
6703 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
6704 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
6705 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
6706 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
6707 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
6708 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
6709 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
6710 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
6711 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
6712 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
6713 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
6714 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
6715 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
6716 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
6717 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
6718 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
6719 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
6720 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
6721 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
6722 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
6723 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
6724 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
6725 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
6726 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
6727 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
6728 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
6729 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
6730 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
6731 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
6732 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
6733 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
6734 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
6735 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
6736 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
6737 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
6739 /* SPE binary operations expecting a 5-bit unsigned literal. */
6740 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
6742 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
6743 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
6744 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
6745 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
6746 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
6747 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
6748 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
6749 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
6750 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
6751 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
6752 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
6753 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
6754 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
6755 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
6756 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
6757 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
6758 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
6759 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
6760 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
6761 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
6762 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
6763 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
6764 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
6765 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
6766 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
6767 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
6769 /* Place-holder. Leave as last binary SPE builtin. */
6770 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
6773 /* AltiVec predicates. */
6775 struct builtin_description_predicates
6777 const unsigned int mask;
6778 const enum insn_code icode;
6779 const char *opcode;
6780 const char *const name;
6781 const enum rs6000_builtins code;
6784 static const struct builtin_description_predicates bdesc_altivec_preds[] =
6786 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
6787 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
6788 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
6789 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
6790 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
6791 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
6792 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
6793 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
6794 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
6795 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
6796 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
6797 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
6798 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
6800 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
6801 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
6802 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
6805 /* SPE predicates. */
6806 static struct builtin_description bdesc_spe_predicates[] =
6808 /* Place-holder. Leave as first. */
6809 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
6810 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
6811 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
6812 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
6813 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
6814 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
6815 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
6816 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
6817 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
6818 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
6819 /* Place-holder. Leave as last. */
6820 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
6823 /* SPE evsel predicates. */
6824 static struct builtin_description bdesc_spe_evsel[] =
6826 /* Place-holder. Leave as first. */
6827 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
6828 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
6829 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
6830 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
6831 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
6832 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
6833 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
6834 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
6835 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
6836 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
6837 /* Place-holder. Leave as last. */
6838 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
6841 /* ABS* operations. */
6843 static const struct builtin_description bdesc_abs[] =
6845 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
6846 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
6847 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
6848 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
6849 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
6850 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
6851 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
6854 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6855 foo (VECa). */
6857 static struct builtin_description bdesc_1arg[] =
6859 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
6860 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
6861 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
6862 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
6863 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
6864 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
6865 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
6866 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
6867 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
6868 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
6869 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
6870 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
6871 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
6872 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
6873 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
6874 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
6875 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
6877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
6878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
6879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
6880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
6881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
6882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
6883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
6884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
6885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
6886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
6887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
6888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
6889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
6890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
6891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
6892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
6893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
6894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
6895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
6897 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6898 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6899 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
6900 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
6901 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
6902 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
6903 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
6904 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
6905 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
6906 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
6907 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
6908 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
6909 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
6910 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
6911 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
6912 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
6913 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
6914 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
6915 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
6916 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
6917 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
6918 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
6919 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
6920 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
6921 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
6922 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
6923 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
6924 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
6925 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
6926 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
6928 /* Place-holder. Leave as last unary SPE builtin. */
6929 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW }
6932 static rtx
6933 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
6935 rtx pat;
6936 tree arg0 = CALL_EXPR_ARG (exp, 0);
6937 rtx op0 = expand_normal (arg0);
6938 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6939 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6941 if (icode == CODE_FOR_nothing)
6942 /* Builtin not supported on this processor. */
6943 return 0;
6945 /* If we got invalid arguments bail out before generating bad rtl. */
6946 if (arg0 == error_mark_node)
6947 return const0_rtx;
6949 if (icode == CODE_FOR_altivec_vspltisb
6950 || icode == CODE_FOR_altivec_vspltish
6951 || icode == CODE_FOR_altivec_vspltisw
6952 || icode == CODE_FOR_spe_evsplatfi
6953 || icode == CODE_FOR_spe_evsplati)
6955 /* Only allow 5-bit *signed* literals. */
6956 if (GET_CODE (op0) != CONST_INT
6957 || INTVAL (op0) > 15
6958 || INTVAL (op0) < -16)
6960 error ("argument 1 must be a 5-bit signed literal");
6961 return const0_rtx;
6965 if (target == 0
6966 || GET_MODE (target) != tmode
6967 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6968 target = gen_reg_rtx (tmode);
6970 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6971 op0 = copy_to_mode_reg (mode0, op0);
6973 pat = GEN_FCN (icode) (target, op0);
6974 if (! pat)
6975 return 0;
6976 emit_insn (pat);
6978 return target;
6981 static rtx
6982 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
6984 rtx pat, scratch1, scratch2;
6985 tree arg0 = CALL_EXPR_ARG (exp, 0);
6986 rtx op0 = expand_normal (arg0);
6987 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6988 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6990 /* If we have invalid arguments, bail out before generating bad rtl. */
6991 if (arg0 == error_mark_node)
6992 return const0_rtx;
6994 if (target == 0
6995 || GET_MODE (target) != tmode
6996 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6997 target = gen_reg_rtx (tmode);
6999 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7000 op0 = copy_to_mode_reg (mode0, op0);
7002 scratch1 = gen_reg_rtx (mode0);
7003 scratch2 = gen_reg_rtx (mode0);
7005 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
7006 if (! pat)
7007 return 0;
7008 emit_insn (pat);
7010 return target;
7013 static rtx
7014 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
7016 rtx pat;
7017 tree arg0 = CALL_EXPR_ARG (exp, 0);
7018 tree arg1 = CALL_EXPR_ARG (exp, 1);
7019 rtx op0 = expand_normal (arg0);
7020 rtx op1 = expand_normal (arg1);
7021 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7022 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7023 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7025 if (icode == CODE_FOR_nothing)
7026 /* Builtin not supported on this processor. */
7027 return 0;
7029 /* If we got invalid arguments bail out before generating bad rtl. */
7030 if (arg0 == error_mark_node || arg1 == error_mark_node)
7031 return const0_rtx;
7033 if (icode == CODE_FOR_altivec_vcfux
7034 || icode == CODE_FOR_altivec_vcfsx
7035 || icode == CODE_FOR_altivec_vctsxs
7036 || icode == CODE_FOR_altivec_vctuxs
7037 || icode == CODE_FOR_altivec_vspltb
7038 || icode == CODE_FOR_altivec_vsplth
7039 || icode == CODE_FOR_altivec_vspltw
7040 || icode == CODE_FOR_spe_evaddiw
7041 || icode == CODE_FOR_spe_evldd
7042 || icode == CODE_FOR_spe_evldh
7043 || icode == CODE_FOR_spe_evldw
7044 || icode == CODE_FOR_spe_evlhhesplat
7045 || icode == CODE_FOR_spe_evlhhossplat
7046 || icode == CODE_FOR_spe_evlhhousplat
7047 || icode == CODE_FOR_spe_evlwhe
7048 || icode == CODE_FOR_spe_evlwhos
7049 || icode == CODE_FOR_spe_evlwhou
7050 || icode == CODE_FOR_spe_evlwhsplat
7051 || icode == CODE_FOR_spe_evlwwsplat
7052 || icode == CODE_FOR_spe_evrlwi
7053 || icode == CODE_FOR_spe_evslwi
7054 || icode == CODE_FOR_spe_evsrwis
7055 || icode == CODE_FOR_spe_evsubifw
7056 || icode == CODE_FOR_spe_evsrwiu)
7058 /* Only allow 5-bit unsigned literals. */
7059 STRIP_NOPS (arg1);
7060 if (TREE_CODE (arg1) != INTEGER_CST
7061 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7063 error ("argument 2 must be a 5-bit unsigned literal");
7064 return const0_rtx;
7068 if (target == 0
7069 || GET_MODE (target) != tmode
7070 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7071 target = gen_reg_rtx (tmode);
7073 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7074 op0 = copy_to_mode_reg (mode0, op0);
7075 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7076 op1 = copy_to_mode_reg (mode1, op1);
7078 pat = GEN_FCN (icode) (target, op0, op1);
7079 if (! pat)
7080 return 0;
7081 emit_insn (pat);
7083 return target;
7086 static rtx
7087 altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
7088 tree exp, rtx target)
7090 rtx pat, scratch;
7091 tree cr6_form = CALL_EXPR_ARG (exp, 0);
7092 tree arg0 = CALL_EXPR_ARG (exp, 1);
7093 tree arg1 = CALL_EXPR_ARG (exp, 2);
7094 rtx op0 = expand_normal (arg0);
7095 rtx op1 = expand_normal (arg1);
7096 enum machine_mode tmode = SImode;
7097 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7098 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7099 int cr6_form_int;
7101 if (TREE_CODE (cr6_form) != INTEGER_CST)
7103 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7104 return const0_rtx;
7106 else
7107 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
7109 gcc_assert (mode0 == mode1);
7111 /* If we have invalid arguments, bail out before generating bad rtl. */
7112 if (arg0 == error_mark_node || arg1 == error_mark_node)
7113 return const0_rtx;
7115 if (target == 0
7116 || GET_MODE (target) != tmode
7117 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7118 target = gen_reg_rtx (tmode);
7120 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7121 op0 = copy_to_mode_reg (mode0, op0);
7122 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7123 op1 = copy_to_mode_reg (mode1, op1);
7125 scratch = gen_reg_rtx (mode0);
7127 pat = GEN_FCN (icode) (scratch, op0, op1,
7128 gen_rtx_SYMBOL_REF (Pmode, opcode));
7129 if (! pat)
7130 return 0;
7131 emit_insn (pat);
7133 /* The vec_any* and vec_all* predicates use the same opcodes for two
7134 different operations, but the bits in CR6 will be different
7135 depending on what information we want. So we have to play tricks
7136 with CR6 to get the right bits out.
7138 If you think this is disgusting, look at the specs for the
7139 AltiVec predicates. */
7141 switch (cr6_form_int)
7143 case 0:
7144 emit_insn (gen_cr6_test_for_zero (target));
7145 break;
7146 case 1:
7147 emit_insn (gen_cr6_test_for_zero_reverse (target));
7148 break;
7149 case 2:
7150 emit_insn (gen_cr6_test_for_lt (target));
7151 break;
7152 case 3:
7153 emit_insn (gen_cr6_test_for_lt_reverse (target));
7154 break;
7155 default:
7156 error ("argument 1 of __builtin_altivec_predicate is out of range");
7157 break;
7160 return target;
7163 static rtx
7164 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
7166 rtx pat, addr;
7167 tree arg0 = CALL_EXPR_ARG (exp, 0);
7168 tree arg1 = CALL_EXPR_ARG (exp, 1);
7169 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7170 enum machine_mode mode0 = Pmode;
7171 enum machine_mode mode1 = Pmode;
7172 rtx op0 = expand_normal (arg0);
7173 rtx op1 = expand_normal (arg1);
7175 if (icode == CODE_FOR_nothing)
7176 /* Builtin not supported on this processor. */
7177 return 0;
7179 /* If we got invalid arguments bail out before generating bad rtl. */
7180 if (arg0 == error_mark_node || arg1 == error_mark_node)
7181 return const0_rtx;
7183 if (target == 0
7184 || GET_MODE (target) != tmode
7185 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7186 target = gen_reg_rtx (tmode);
7188 op1 = copy_to_mode_reg (mode1, op1);
7190 if (op0 == const0_rtx)
7192 addr = gen_rtx_MEM (tmode, op1);
7194 else
7196 op0 = copy_to_mode_reg (mode0, op0);
7197 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7200 pat = GEN_FCN (icode) (target, addr);
7202 if (! pat)
7203 return 0;
7204 emit_insn (pat);
7206 return target;
7209 static rtx
7210 spe_expand_stv_builtin (enum insn_code icode, tree exp)
7212 tree arg0 = CALL_EXPR_ARG (exp, 0);
7213 tree arg1 = CALL_EXPR_ARG (exp, 1);
7214 tree arg2 = CALL_EXPR_ARG (exp, 2);
7215 rtx op0 = expand_normal (arg0);
7216 rtx op1 = expand_normal (arg1);
7217 rtx op2 = expand_normal (arg2);
7218 rtx pat;
7219 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
7220 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
7221 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
7223 /* Invalid arguments. Bail before doing anything stoopid! */
7224 if (arg0 == error_mark_node
7225 || arg1 == error_mark_node
7226 || arg2 == error_mark_node)
7227 return const0_rtx;
7229 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
7230 op0 = copy_to_mode_reg (mode2, op0);
7231 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
7232 op1 = copy_to_mode_reg (mode0, op1);
7233 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7234 op2 = copy_to_mode_reg (mode1, op2);
7236 pat = GEN_FCN (icode) (op1, op2, op0);
7237 if (pat)
7238 emit_insn (pat);
7239 return NULL_RTX;
7242 static rtx
7243 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
7245 tree arg0 = CALL_EXPR_ARG (exp, 0);
7246 tree arg1 = CALL_EXPR_ARG (exp, 1);
7247 tree arg2 = CALL_EXPR_ARG (exp, 2);
7248 rtx op0 = expand_normal (arg0);
7249 rtx op1 = expand_normal (arg1);
7250 rtx op2 = expand_normal (arg2);
7251 rtx pat, addr;
7252 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7253 enum machine_mode mode1 = Pmode;
7254 enum machine_mode mode2 = Pmode;
7256 /* Invalid arguments. Bail before doing anything stoopid! */
7257 if (arg0 == error_mark_node
7258 || arg1 == error_mark_node
7259 || arg2 == error_mark_node)
7260 return const0_rtx;
7262 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
7263 op0 = copy_to_mode_reg (tmode, op0);
7265 op2 = copy_to_mode_reg (mode2, op2);
7267 if (op1 == const0_rtx)
7269 addr = gen_rtx_MEM (tmode, op2);
7271 else
7273 op1 = copy_to_mode_reg (mode1, op1);
7274 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
7277 pat = GEN_FCN (icode) (addr, op0);
7278 if (pat)
7279 emit_insn (pat);
7280 return NULL_RTX;
7283 static rtx
7284 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
7286 rtx pat;
7287 tree arg0 = CALL_EXPR_ARG (exp, 0);
7288 tree arg1 = CALL_EXPR_ARG (exp, 1);
7289 tree arg2 = CALL_EXPR_ARG (exp, 2);
7290 rtx op0 = expand_normal (arg0);
7291 rtx op1 = expand_normal (arg1);
7292 rtx op2 = expand_normal (arg2);
7293 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7294 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7295 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7296 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
7298 if (icode == CODE_FOR_nothing)
7299 /* Builtin not supported on this processor. */
7300 return 0;
7302 /* If we got invalid arguments bail out before generating bad rtl. */
7303 if (arg0 == error_mark_node
7304 || arg1 == error_mark_node
7305 || arg2 == error_mark_node)
7306 return const0_rtx;
7308 if (icode == CODE_FOR_altivec_vsldoi_v4sf
7309 || icode == CODE_FOR_altivec_vsldoi_v4si
7310 || icode == CODE_FOR_altivec_vsldoi_v8hi
7311 || icode == CODE_FOR_altivec_vsldoi_v16qi)
7313 /* Only allow 4-bit unsigned literals. */
7314 STRIP_NOPS (arg2);
7315 if (TREE_CODE (arg2) != INTEGER_CST
7316 || TREE_INT_CST_LOW (arg2) & ~0xf)
7318 error ("argument 3 must be a 4-bit unsigned literal");
7319 return const0_rtx;
7323 if (target == 0
7324 || GET_MODE (target) != tmode
7325 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7326 target = gen_reg_rtx (tmode);
7328 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7329 op0 = copy_to_mode_reg (mode0, op0);
7330 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7331 op1 = copy_to_mode_reg (mode1, op1);
7332 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
7333 op2 = copy_to_mode_reg (mode2, op2);
7335 pat = GEN_FCN (icode) (target, op0, op1, op2);
7336 if (! pat)
7337 return 0;
7338 emit_insn (pat);
7340 return target;
7343 /* Expand the lvx builtins. */
7344 static rtx
7345 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
7347 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
7348 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7349 tree arg0;
7350 enum machine_mode tmode, mode0;
7351 rtx pat, op0;
7352 enum insn_code icode;
7354 switch (fcode)
7356 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
7357 icode = CODE_FOR_altivec_lvx_v16qi;
7358 break;
7359 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
7360 icode = CODE_FOR_altivec_lvx_v8hi;
7361 break;
7362 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
7363 icode = CODE_FOR_altivec_lvx_v4si;
7364 break;
7365 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
7366 icode = CODE_FOR_altivec_lvx_v4sf;
7367 break;
7368 default:
7369 *expandedp = false;
7370 return NULL_RTX;
7373 *expandedp = true;
7375 arg0 = CALL_EXPR_ARG (exp, 0);
7376 op0 = expand_normal (arg0);
7377 tmode = insn_data[icode].operand[0].mode;
7378 mode0 = insn_data[icode].operand[1].mode;
7380 if (target == 0
7381 || GET_MODE (target) != tmode
7382 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7383 target = gen_reg_rtx (tmode);
7385 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7386 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7388 pat = GEN_FCN (icode) (target, op0);
7389 if (! pat)
7390 return 0;
7391 emit_insn (pat);
7392 return target;
7395 /* Expand the stvx builtins. */
7396 static rtx
7397 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
7398 bool *expandedp)
7400 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
7401 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7402 tree arg0, arg1;
7403 enum machine_mode mode0, mode1;
7404 rtx pat, op0, op1;
7405 enum insn_code icode;
7407 switch (fcode)
7409 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
7410 icode = CODE_FOR_altivec_stvx_v16qi;
7411 break;
7412 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
7413 icode = CODE_FOR_altivec_stvx_v8hi;
7414 break;
7415 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
7416 icode = CODE_FOR_altivec_stvx_v4si;
7417 break;
7418 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
7419 icode = CODE_FOR_altivec_stvx_v4sf;
7420 break;
7421 default:
7422 *expandedp = false;
7423 return NULL_RTX;
7426 arg0 = CALL_EXPR_ARG (exp, 0);
7427 arg1 = CALL_EXPR_ARG (exp, 1);
7428 op0 = expand_normal (arg0);
7429 op1 = expand_normal (arg1);
7430 mode0 = insn_data[icode].operand[0].mode;
7431 mode1 = insn_data[icode].operand[1].mode;
7433 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7434 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7435 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7436 op1 = copy_to_mode_reg (mode1, op1);
7438 pat = GEN_FCN (icode) (op0, op1);
7439 if (pat)
7440 emit_insn (pat);
7442 *expandedp = true;
7443 return NULL_RTX;
7446 /* Expand the dst builtins. */
7447 static rtx
7448 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
7449 bool *expandedp)
7451 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
7452 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7453 tree arg0, arg1, arg2;
7454 enum machine_mode mode0, mode1, mode2;
7455 rtx pat, op0, op1, op2;
7456 struct builtin_description *d;
7457 size_t i;
7459 *expandedp = false;
7461 /* Handle DST variants. */
7462 d = (struct builtin_description *) bdesc_dst;
7463 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
7464 if (d->code == fcode)
7466 arg0 = CALL_EXPR_ARG (exp, 0);
7467 arg1 = CALL_EXPR_ARG (exp, 1);
7468 arg2 = CALL_EXPR_ARG (exp, 2);
7469 op0 = expand_normal (arg0);
7470 op1 = expand_normal (arg1);
7471 op2 = expand_normal (arg2);
7472 mode0 = insn_data[d->icode].operand[0].mode;
7473 mode1 = insn_data[d->icode].operand[1].mode;
7474 mode2 = insn_data[d->icode].operand[2].mode;
7476 /* Invalid arguments, bail out before generating bad rtl. */
7477 if (arg0 == error_mark_node
7478 || arg1 == error_mark_node
7479 || arg2 == error_mark_node)
7480 return const0_rtx;
7482 *expandedp = true;
7483 STRIP_NOPS (arg2);
7484 if (TREE_CODE (arg2) != INTEGER_CST
7485 || TREE_INT_CST_LOW (arg2) & ~0x3)
7487 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
7488 return const0_rtx;
7491 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
7492 op0 = copy_to_mode_reg (Pmode, op0);
7493 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
7494 op1 = copy_to_mode_reg (mode1, op1);
7496 pat = GEN_FCN (d->icode) (op0, op1, op2);
7497 if (pat != 0)
7498 emit_insn (pat);
7500 return NULL_RTX;
7503 return NULL_RTX;
7506 /* Expand vec_init builtin. */
7507 static rtx
7508 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
7510 enum machine_mode tmode = TYPE_MODE (type);
7511 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
7512 int i, n_elt = GET_MODE_NUNITS (tmode);
7513 rtvec v = rtvec_alloc (n_elt);
7515 gcc_assert (VECTOR_MODE_P (tmode));
7516 gcc_assert (n_elt == call_expr_nargs (exp));
7518 for (i = 0; i < n_elt; ++i)
7520 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
7521 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
7524 if (!target || !register_operand (target, tmode))
7525 target = gen_reg_rtx (tmode);
7527 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
7528 return target;
7531 /* Return the integer constant in ARG. Constrain it to be in the range
7532 of the subparts of VEC_TYPE; issue an error if not. */
7534 static int
7535 get_element_number (tree vec_type, tree arg)
7537 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
7539 if (!host_integerp (arg, 1)
7540 || (elt = tree_low_cst (arg, 1), elt > max))
7542 error ("selector must be an integer constant in the range 0..%wi", max);
7543 return 0;
7546 return elt;
7549 /* Expand vec_set builtin. */
7550 static rtx
7551 altivec_expand_vec_set_builtin (tree exp)
7553 enum machine_mode tmode, mode1;
7554 tree arg0, arg1, arg2;
7555 int elt;
7556 rtx op0, op1;
7558 arg0 = CALL_EXPR_ARG (exp, 0);
7559 arg1 = CALL_EXPR_ARG (exp, 1);
7560 arg2 = CALL_EXPR_ARG (exp, 2);
7562 tmode = TYPE_MODE (TREE_TYPE (arg0));
7563 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7564 gcc_assert (VECTOR_MODE_P (tmode));
7566 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
7567 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
7568 elt = get_element_number (TREE_TYPE (arg0), arg2);
7570 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
7571 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
7573 op0 = force_reg (tmode, op0);
7574 op1 = force_reg (mode1, op1);
7576 rs6000_expand_vector_set (op0, op1, elt);
7578 return op0;
7581 /* Expand vec_ext builtin. */
7582 static rtx
7583 altivec_expand_vec_ext_builtin (tree exp, rtx target)
7585 enum machine_mode tmode, mode0;
7586 tree arg0, arg1;
7587 int elt;
7588 rtx op0;
7590 arg0 = CALL_EXPR_ARG (exp, 0);
7591 arg1 = CALL_EXPR_ARG (exp, 1);
7593 op0 = expand_normal (arg0);
7594 elt = get_element_number (TREE_TYPE (arg0), arg1);
7596 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7597 mode0 = TYPE_MODE (TREE_TYPE (arg0));
7598 gcc_assert (VECTOR_MODE_P (mode0));
7600 op0 = force_reg (mode0, op0);
7602 if (optimize || !target || !register_operand (target, tmode))
7603 target = gen_reg_rtx (tmode);
7605 rs6000_expand_vector_extract (target, op0, elt);
7607 return target;
7610 /* Expand the builtin in EXP and store the result in TARGET. Store
7611 true in *EXPANDEDP if we found a builtin to expand. */
7612 static rtx
7613 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
7615 struct builtin_description *d;
7616 struct builtin_description_predicates *dp;
7617 size_t i;
7618 enum insn_code icode;
7619 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
7620 tree arg0;
7621 rtx op0, pat;
7622 enum machine_mode tmode, mode0;
7623 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7625 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7626 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
7628 *expandedp = true;
7629 error ("unresolved overload for Altivec builtin %qF", fndecl);
7630 return const0_rtx;
7633 target = altivec_expand_ld_builtin (exp, target, expandedp);
7634 if (*expandedp)
7635 return target;
7637 target = altivec_expand_st_builtin (exp, target, expandedp);
7638 if (*expandedp)
7639 return target;
7641 target = altivec_expand_dst_builtin (exp, target, expandedp);
7642 if (*expandedp)
7643 return target;
7645 *expandedp = true;
7647 switch (fcode)
7649 case ALTIVEC_BUILTIN_STVX:
7650 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
7651 case ALTIVEC_BUILTIN_STVEBX:
7652 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
7653 case ALTIVEC_BUILTIN_STVEHX:
7654 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
7655 case ALTIVEC_BUILTIN_STVEWX:
7656 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
7657 case ALTIVEC_BUILTIN_STVXL:
7658 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
7660 case ALTIVEC_BUILTIN_MFVSCR:
7661 icode = CODE_FOR_altivec_mfvscr;
7662 tmode = insn_data[icode].operand[0].mode;
7664 if (target == 0
7665 || GET_MODE (target) != tmode
7666 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7667 target = gen_reg_rtx (tmode);
7669 pat = GEN_FCN (icode) (target);
7670 if (! pat)
7671 return 0;
7672 emit_insn (pat);
7673 return target;
7675 case ALTIVEC_BUILTIN_MTVSCR:
7676 icode = CODE_FOR_altivec_mtvscr;
7677 arg0 = CALL_EXPR_ARG (exp, 0);
7678 op0 = expand_normal (arg0);
7679 mode0 = insn_data[icode].operand[0].mode;
7681 /* If we got invalid arguments bail out before generating bad rtl. */
7682 if (arg0 == error_mark_node)
7683 return const0_rtx;
7685 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7686 op0 = copy_to_mode_reg (mode0, op0);
7688 pat = GEN_FCN (icode) (op0);
7689 if (pat)
7690 emit_insn (pat);
7691 return NULL_RTX;
7693 case ALTIVEC_BUILTIN_DSSALL:
7694 emit_insn (gen_altivec_dssall ());
7695 return NULL_RTX;
7697 case ALTIVEC_BUILTIN_DSS:
7698 icode = CODE_FOR_altivec_dss;
7699 arg0 = CALL_EXPR_ARG (exp, 0);
7700 STRIP_NOPS (arg0);
7701 op0 = expand_normal (arg0);
7702 mode0 = insn_data[icode].operand[0].mode;
7704 /* If we got invalid arguments bail out before generating bad rtl. */
7705 if (arg0 == error_mark_node)
7706 return const0_rtx;
7708 if (TREE_CODE (arg0) != INTEGER_CST
7709 || TREE_INT_CST_LOW (arg0) & ~0x3)
7711 error ("argument to dss must be a 2-bit unsigned literal");
7712 return const0_rtx;
7715 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7716 op0 = copy_to_mode_reg (mode0, op0);
7718 emit_insn (gen_altivec_dss (op0));
7719 return NULL_RTX;
7721 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
7722 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
7723 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
7724 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
7725 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
7727 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
7728 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
7729 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
7730 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
7731 return altivec_expand_vec_set_builtin (exp);
7733 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
7734 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
7735 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
7736 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
7737 return altivec_expand_vec_ext_builtin (exp, target);
7739 default:
7740 break;
7741 /* Fall through. */
7744 /* Expand abs* operations. */
7745 d = (struct builtin_description *) bdesc_abs;
7746 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
7747 if (d->code == fcode)
7748 return altivec_expand_abs_builtin (d->icode, exp, target);
7750 /* Expand the AltiVec predicates. */
7751 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
7752 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
7753 if (dp->code == fcode)
7754 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
7755 exp, target);
7757 /* LV* are funky. We initialized them differently. */
7758 switch (fcode)
7760 case ALTIVEC_BUILTIN_LVSL:
7761 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
7762 exp, target);
7763 case ALTIVEC_BUILTIN_LVSR:
7764 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
7765 exp, target);
7766 case ALTIVEC_BUILTIN_LVEBX:
7767 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
7768 exp, target);
7769 case ALTIVEC_BUILTIN_LVEHX:
7770 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
7771 exp, target);
7772 case ALTIVEC_BUILTIN_LVEWX:
7773 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
7774 exp, target);
7775 case ALTIVEC_BUILTIN_LVXL:
7776 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
7777 exp, target);
7778 case ALTIVEC_BUILTIN_LVX:
7779 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
7780 exp, target);
7781 default:
7782 break;
7783 /* Fall through. */
7786 *expandedp = false;
7787 return NULL_RTX;
7790 /* Binops that need to be initialized manually, but can be expanded
7791 automagically by rs6000_expand_binop_builtin. */
7792 static struct builtin_description bdesc_2arg_spe[] =
7794 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
7795 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
7796 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
7797 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
7798 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
7799 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
7800 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
7801 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
7802 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
7803 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
7804 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
7805 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
7806 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
7807 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
7808 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
7809 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
7810 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
7811 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
7812 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
7813 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
7814 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
7815 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
7818 /* Expand the builtin in EXP and store the result in TARGET. Store
7819 true in *EXPANDEDP if we found a builtin to expand.
7821 This expands the SPE builtins that are not simple unary and binary
7822 operations. */
7823 static rtx
7824 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
7826 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
7827 tree arg1, arg0;
7828 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7829 enum insn_code icode;
7830 enum machine_mode tmode, mode0;
7831 rtx pat, op0;
7832 struct builtin_description *d;
7833 size_t i;
7835 *expandedp = true;
7837 /* Syntax check for a 5-bit unsigned immediate. */
7838 switch (fcode)
7840 case SPE_BUILTIN_EVSTDD:
7841 case SPE_BUILTIN_EVSTDH:
7842 case SPE_BUILTIN_EVSTDW:
7843 case SPE_BUILTIN_EVSTWHE:
7844 case SPE_BUILTIN_EVSTWHO:
7845 case SPE_BUILTIN_EVSTWWE:
7846 case SPE_BUILTIN_EVSTWWO:
7847 arg1 = CALL_EXPR_ARG (exp, 2);
7848 if (TREE_CODE (arg1) != INTEGER_CST
7849 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7851 error ("argument 2 must be a 5-bit unsigned literal");
7852 return const0_rtx;
7854 break;
7855 default:
7856 break;
7859 /* The evsplat*i instructions are not quite generic. */
7860 switch (fcode)
7862 case SPE_BUILTIN_EVSPLATFI:
7863 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
7864 exp, target);
7865 case SPE_BUILTIN_EVSPLATI:
7866 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
7867 exp, target);
7868 default:
7869 break;
7872 d = (struct builtin_description *) bdesc_2arg_spe;
7873 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
7874 if (d->code == fcode)
7875 return rs6000_expand_binop_builtin (d->icode, exp, target);
7877 d = (struct builtin_description *) bdesc_spe_predicates;
7878 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
7879 if (d->code == fcode)
7880 return spe_expand_predicate_builtin (d->icode, exp, target);
7882 d = (struct builtin_description *) bdesc_spe_evsel;
7883 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
7884 if (d->code == fcode)
7885 return spe_expand_evsel_builtin (d->icode, exp, target);
7887 switch (fcode)
7889 case SPE_BUILTIN_EVSTDDX:
7890 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
7891 case SPE_BUILTIN_EVSTDHX:
7892 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
7893 case SPE_BUILTIN_EVSTDWX:
7894 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
7895 case SPE_BUILTIN_EVSTWHEX:
7896 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
7897 case SPE_BUILTIN_EVSTWHOX:
7898 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
7899 case SPE_BUILTIN_EVSTWWEX:
7900 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
7901 case SPE_BUILTIN_EVSTWWOX:
7902 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
7903 case SPE_BUILTIN_EVSTDD:
7904 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
7905 case SPE_BUILTIN_EVSTDH:
7906 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
7907 case SPE_BUILTIN_EVSTDW:
7908 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
7909 case SPE_BUILTIN_EVSTWHE:
7910 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
7911 case SPE_BUILTIN_EVSTWHO:
7912 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
7913 case SPE_BUILTIN_EVSTWWE:
7914 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
7915 case SPE_BUILTIN_EVSTWWO:
7916 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
7917 case SPE_BUILTIN_MFSPEFSCR:
7918 icode = CODE_FOR_spe_mfspefscr;
7919 tmode = insn_data[icode].operand[0].mode;
7921 if (target == 0
7922 || GET_MODE (target) != tmode
7923 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7924 target = gen_reg_rtx (tmode);
7926 pat = GEN_FCN (icode) (target);
7927 if (! pat)
7928 return 0;
7929 emit_insn (pat);
7930 return target;
7931 case SPE_BUILTIN_MTSPEFSCR:
7932 icode = CODE_FOR_spe_mtspefscr;
7933 arg0 = CALL_EXPR_ARG (exp, 0);
7934 op0 = expand_normal (arg0);
7935 mode0 = insn_data[icode].operand[0].mode;
7937 if (arg0 == error_mark_node)
7938 return const0_rtx;
7940 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7941 op0 = copy_to_mode_reg (mode0, op0);
7943 pat = GEN_FCN (icode) (op0);
7944 if (pat)
7945 emit_insn (pat);
7946 return NULL_RTX;
7947 default:
7948 break;
7951 *expandedp = false;
7952 return NULL_RTX;
7955 static rtx
7956 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
7958 rtx pat, scratch, tmp;
7959 tree form = CALL_EXPR_ARG (exp, 0);
7960 tree arg0 = CALL_EXPR_ARG (exp, 1);
7961 tree arg1 = CALL_EXPR_ARG (exp, 2);
7962 rtx op0 = expand_normal (arg0);
7963 rtx op1 = expand_normal (arg1);
7964 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7965 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7966 int form_int;
7967 enum rtx_code code;
7969 if (TREE_CODE (form) != INTEGER_CST)
7971 error ("argument 1 of __builtin_spe_predicate must be a constant");
7972 return const0_rtx;
7974 else
7975 form_int = TREE_INT_CST_LOW (form);
7977 gcc_assert (mode0 == mode1);
7979 if (arg0 == error_mark_node || arg1 == error_mark_node)
7980 return const0_rtx;
7982 if (target == 0
7983 || GET_MODE (target) != SImode
7984 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
7985 target = gen_reg_rtx (SImode);
7987 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7988 op0 = copy_to_mode_reg (mode0, op0);
7989 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7990 op1 = copy_to_mode_reg (mode1, op1);
7992 scratch = gen_reg_rtx (CCmode);
7994 pat = GEN_FCN (icode) (scratch, op0, op1);
7995 if (! pat)
7996 return const0_rtx;
7997 emit_insn (pat);
7999 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
8000 _lower_. We use one compare, but look in different bits of the
8001 CR for each variant.
8003 There are 2 elements in each SPE simd type (upper/lower). The CR
8004 bits are set as follows:
8006 BIT0 | BIT 1 | BIT 2 | BIT 3
8007 U | L | (U | L) | (U & L)
8009 So, for an "all" relationship, BIT 3 would be set.
8010 For an "any" relationship, BIT 2 would be set. Etc.
8012 Following traditional nomenclature, these bits map to:
8014 BIT0 | BIT 1 | BIT 2 | BIT 3
8015 LT | GT | EQ | OV
8017 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8020 switch (form_int)
8022 /* All variant. OV bit. */
8023 case 0:
8024 /* We need to get to the OV bit, which is the ORDERED bit. We
8025 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
8026 that's ugly and will make validate_condition_mode die.
8027 So let's just use another pattern. */
8028 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
8029 return target;
8030 /* Any variant. EQ bit. */
8031 case 1:
8032 code = EQ;
8033 break;
8034 /* Upper variant. LT bit. */
8035 case 2:
8036 code = LT;
8037 break;
8038 /* Lower variant. GT bit. */
8039 case 3:
8040 code = GT;
8041 break;
8042 default:
8043 error ("argument 1 of __builtin_spe_predicate is out of range");
8044 return const0_rtx;
8047 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8048 emit_move_insn (target, tmp);
8050 return target;
8053 /* The evsel builtins look like this:
8055 e = __builtin_spe_evsel_OP (a, b, c, d);
8057 and work like this:
8059 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8060 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8063 static rtx
8064 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
8066 rtx pat, scratch;
8067 tree arg0 = CALL_EXPR_ARG (exp, 0);
8068 tree arg1 = CALL_EXPR_ARG (exp, 1);
8069 tree arg2 = CALL_EXPR_ARG (exp, 2);
8070 tree arg3 = CALL_EXPR_ARG (exp, 3);
8071 rtx op0 = expand_normal (arg0);
8072 rtx op1 = expand_normal (arg1);
8073 rtx op2 = expand_normal (arg2);
8074 rtx op3 = expand_normal (arg3);
8075 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8076 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8078 gcc_assert (mode0 == mode1);
8080 if (arg0 == error_mark_node || arg1 == error_mark_node
8081 || arg2 == error_mark_node || arg3 == error_mark_node)
8082 return const0_rtx;
8084 if (target == 0
8085 || GET_MODE (target) != mode0
8086 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
8087 target = gen_reg_rtx (mode0);
8089 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8090 op0 = copy_to_mode_reg (mode0, op0);
8091 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
8092 op1 = copy_to_mode_reg (mode0, op1);
8093 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
8094 op2 = copy_to_mode_reg (mode0, op2);
8095 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
8096 op3 = copy_to_mode_reg (mode0, op3);
8098 /* Generate the compare. */
8099 scratch = gen_reg_rtx (CCmode);
8100 pat = GEN_FCN (icode) (scratch, op0, op1);
8101 if (! pat)
8102 return const0_rtx;
8103 emit_insn (pat);
8105 if (mode0 == V2SImode)
8106 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
8107 else
8108 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
8110 return target;
8113 /* Expand an expression EXP that calls a built-in function,
8114 with result going to TARGET if that's convenient
8115 (and in mode MODE if that's convenient).
8116 SUBTARGET may be used as the target for computing one of EXP's operands.
8117 IGNORE is nonzero if the value is to be ignored. */
8119 static rtx
8120 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8121 enum machine_mode mode ATTRIBUTE_UNUSED,
8122 int ignore ATTRIBUTE_UNUSED)
8124 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8125 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8126 struct builtin_description *d;
8127 size_t i;
8128 rtx ret;
8129 bool success;
8131 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
8132 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
8134 int icode = (int) CODE_FOR_altivec_lvsr;
8135 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8136 enum machine_mode mode = insn_data[icode].operand[1].mode;
8137 tree arg;
8138 rtx op, addr, pat;
8140 gcc_assert (TARGET_ALTIVEC);
8142 arg = CALL_EXPR_ARG (exp, 0);
8143 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
8144 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
8145 addr = memory_address (mode, op);
8146 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
8147 op = addr;
8148 else
8150 /* For the load case need to negate the address. */
8151 op = gen_reg_rtx (GET_MODE (addr));
8152 emit_insn (gen_rtx_SET (VOIDmode, op,
8153 gen_rtx_NEG (GET_MODE (addr), addr)));
8155 op = gen_rtx_MEM (mode, op);
8157 if (target == 0
8158 || GET_MODE (target) != tmode
8159 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8160 target = gen_reg_rtx (tmode);
8162 /*pat = gen_altivec_lvsr (target, op);*/
8163 pat = GEN_FCN (icode) (target, op);
8164 if (!pat)
8165 return 0;
8166 emit_insn (pat);
8168 return target;
8171 /* FIXME: There's got to be a nicer way to handle this case than
8172 constructing a new CALL_EXPR. */
8173 if (fcode == ALTIVEC_BUILTIN_VCFUX
8174 || fcode == ALTIVEC_BUILTIN_VCFSX)
8176 if (call_expr_nargs (exp) == 1)
8177 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
8178 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
8181 if (TARGET_ALTIVEC)
8183 ret = altivec_expand_builtin (exp, target, &success);
8185 if (success)
8186 return ret;
8188 if (TARGET_SPE)
8190 ret = spe_expand_builtin (exp, target, &success);
8192 if (success)
8193 return ret;
8196 gcc_assert (TARGET_ALTIVEC || TARGET_SPE);
8198 /* Handle simple unary operations. */
8199 d = (struct builtin_description *) bdesc_1arg;
8200 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
8201 if (d->code == fcode)
8202 return rs6000_expand_unop_builtin (d->icode, exp, target);
8204 /* Handle simple binary operations. */
8205 d = (struct builtin_description *) bdesc_2arg;
8206 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
8207 if (d->code == fcode)
8208 return rs6000_expand_binop_builtin (d->icode, exp, target);
8210 /* Handle simple ternary operations. */
8211 d = (struct builtin_description *) bdesc_3arg;
8212 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
8213 if (d->code == fcode)
8214 return rs6000_expand_ternop_builtin (d->icode, exp, target);
8216 gcc_unreachable ();
8219 static tree
8220 build_opaque_vector_type (tree node, int nunits)
8222 node = copy_node (node);
8223 TYPE_MAIN_VARIANT (node) = node;
8224 return build_vector_type (node, nunits);
8227 static void
8228 rs6000_init_builtins (void)
8230 V2SI_type_node = build_vector_type (intSI_type_node, 2);
8231 V2SF_type_node = build_vector_type (float_type_node, 2);
8232 V4HI_type_node = build_vector_type (intHI_type_node, 4);
8233 V4SI_type_node = build_vector_type (intSI_type_node, 4);
8234 V4SF_type_node = build_vector_type (float_type_node, 4);
8235 V8HI_type_node = build_vector_type (intHI_type_node, 8);
8236 V16QI_type_node = build_vector_type (intQI_type_node, 16);
8238 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
8239 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
8240 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
8242 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
8243 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
8244 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
8245 opaque_V4SI_type_node = copy_node (V4SI_type_node);
8247 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
8248 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
8249 'vector unsigned short'. */
8251 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
8252 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8253 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
8254 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8256 long_integer_type_internal_node = long_integer_type_node;
8257 long_unsigned_type_internal_node = long_unsigned_type_node;
8258 intQI_type_internal_node = intQI_type_node;
8259 uintQI_type_internal_node = unsigned_intQI_type_node;
8260 intHI_type_internal_node = intHI_type_node;
8261 uintHI_type_internal_node = unsigned_intHI_type_node;
8262 intSI_type_internal_node = intSI_type_node;
8263 uintSI_type_internal_node = unsigned_intSI_type_node;
8264 float_type_internal_node = float_type_node;
8265 void_type_internal_node = void_type_node;
8267 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8268 get_identifier ("__bool char"),
8269 bool_char_type_node));
8270 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8271 get_identifier ("__bool short"),
8272 bool_short_type_node));
8273 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8274 get_identifier ("__bool int"),
8275 bool_int_type_node));
8276 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8277 get_identifier ("__pixel"),
8278 pixel_type_node));
8280 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
8281 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
8282 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
8283 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
8285 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8286 get_identifier ("__vector unsigned char"),
8287 unsigned_V16QI_type_node));
8288 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8289 get_identifier ("__vector signed char"),
8290 V16QI_type_node));
8291 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8292 get_identifier ("__vector __bool char"),
8293 bool_V16QI_type_node));
8295 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8296 get_identifier ("__vector unsigned short"),
8297 unsigned_V8HI_type_node));
8298 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8299 get_identifier ("__vector signed short"),
8300 V8HI_type_node));
8301 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8302 get_identifier ("__vector __bool short"),
8303 bool_V8HI_type_node));
8305 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8306 get_identifier ("__vector unsigned int"),
8307 unsigned_V4SI_type_node));
8308 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8309 get_identifier ("__vector signed int"),
8310 V4SI_type_node));
8311 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8312 get_identifier ("__vector __bool int"),
8313 bool_V4SI_type_node));
8315 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8316 get_identifier ("__vector float"),
8317 V4SF_type_node));
8318 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8319 get_identifier ("__vector __pixel"),
8320 pixel_V8HI_type_node));
8322 if (TARGET_SPE)
8323 spe_init_builtins ();
8324 if (TARGET_ALTIVEC)
8325 altivec_init_builtins ();
8326 if (TARGET_ALTIVEC || TARGET_SPE)
8327 rs6000_common_init_builtins ();
8329 #if TARGET_XCOFF
8330 /* AIX libm provides clog as __clog. */
8331 if (built_in_decls [BUILT_IN_CLOG])
8332 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
8333 #endif
8336 /* Search through a set of builtins and enable the mask bits.
8337 DESC is an array of builtins.
8338 SIZE is the total number of builtins.
8339 START is the builtin enum at which to start.
8340 END is the builtin enum at which to end. */
8341 static void
8342 enable_mask_for_builtins (struct builtin_description *desc, int size,
8343 enum rs6000_builtins start,
8344 enum rs6000_builtins end)
8346 int i;
8348 for (i = 0; i < size; ++i)
8349 if (desc[i].code == start)
8350 break;
8352 if (i == size)
8353 return;
8355 for (; i < size; ++i)
8357 /* Flip all the bits on. */
8358 desc[i].mask = target_flags;
8359 if (desc[i].code == end)
8360 break;
8364 static void
8365 spe_init_builtins (void)
8367 tree endlink = void_list_node;
8368 tree puint_type_node = build_pointer_type (unsigned_type_node);
8369 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
8370 struct builtin_description *d;
8371 size_t i;
8373 tree v2si_ftype_4_v2si
8374 = build_function_type
8375 (opaque_V2SI_type_node,
8376 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8377 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8378 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8379 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8380 endlink)))));
8382 tree v2sf_ftype_4_v2sf
8383 = build_function_type
8384 (opaque_V2SF_type_node,
8385 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8386 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8387 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8388 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8389 endlink)))));
8391 tree int_ftype_int_v2si_v2si
8392 = build_function_type
8393 (integer_type_node,
8394 tree_cons (NULL_TREE, integer_type_node,
8395 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8396 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8397 endlink))));
8399 tree int_ftype_int_v2sf_v2sf
8400 = build_function_type
8401 (integer_type_node,
8402 tree_cons (NULL_TREE, integer_type_node,
8403 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8404 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8405 endlink))));
8407 tree void_ftype_v2si_puint_int
8408 = build_function_type (void_type_node,
8409 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8410 tree_cons (NULL_TREE, puint_type_node,
8411 tree_cons (NULL_TREE,
8412 integer_type_node,
8413 endlink))));
8415 tree void_ftype_v2si_puint_char
8416 = build_function_type (void_type_node,
8417 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8418 tree_cons (NULL_TREE, puint_type_node,
8419 tree_cons (NULL_TREE,
8420 char_type_node,
8421 endlink))));
8423 tree void_ftype_v2si_pv2si_int
8424 = build_function_type (void_type_node,
8425 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8426 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8427 tree_cons (NULL_TREE,
8428 integer_type_node,
8429 endlink))));
8431 tree void_ftype_v2si_pv2si_char
8432 = build_function_type (void_type_node,
8433 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8434 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8435 tree_cons (NULL_TREE,
8436 char_type_node,
8437 endlink))));
8439 tree void_ftype_int
8440 = build_function_type (void_type_node,
8441 tree_cons (NULL_TREE, integer_type_node, endlink));
8443 tree int_ftype_void
8444 = build_function_type (integer_type_node, endlink);
8446 tree v2si_ftype_pv2si_int
8447 = build_function_type (opaque_V2SI_type_node,
8448 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
8449 tree_cons (NULL_TREE, integer_type_node,
8450 endlink)));
8452 tree v2si_ftype_puint_int
8453 = build_function_type (opaque_V2SI_type_node,
8454 tree_cons (NULL_TREE, puint_type_node,
8455 tree_cons (NULL_TREE, integer_type_node,
8456 endlink)));
8458 tree v2si_ftype_pushort_int
8459 = build_function_type (opaque_V2SI_type_node,
8460 tree_cons (NULL_TREE, pushort_type_node,
8461 tree_cons (NULL_TREE, integer_type_node,
8462 endlink)));
8464 tree v2si_ftype_signed_char
8465 = build_function_type (opaque_V2SI_type_node,
8466 tree_cons (NULL_TREE, signed_char_type_node,
8467 endlink));
8469 /* The initialization of the simple binary and unary builtins is
8470 done in rs6000_common_init_builtins, but we have to enable the
8471 mask bits here manually because we have run out of `target_flags'
8472 bits. We really need to redesign this mask business. */
8474 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
8475 ARRAY_SIZE (bdesc_2arg),
8476 SPE_BUILTIN_EVADDW,
8477 SPE_BUILTIN_EVXOR);
8478 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
8479 ARRAY_SIZE (bdesc_1arg),
8480 SPE_BUILTIN_EVABS,
8481 SPE_BUILTIN_EVSUBFUSIAAW);
8482 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
8483 ARRAY_SIZE (bdesc_spe_predicates),
8484 SPE_BUILTIN_EVCMPEQ,
8485 SPE_BUILTIN_EVFSTSTLT);
8486 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
8487 ARRAY_SIZE (bdesc_spe_evsel),
8488 SPE_BUILTIN_EVSEL_CMPGTS,
8489 SPE_BUILTIN_EVSEL_FSTSTEQ);
8491 (*lang_hooks.decls.pushdecl)
8492 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
8493 opaque_V2SI_type_node));
8495 /* Initialize irregular SPE builtins. */
8497 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
8498 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
8499 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
8500 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
8501 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
8502 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
8503 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
8504 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
8505 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
8506 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
8507 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
8508 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
8509 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
8510 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
8511 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
8512 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
8513 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
8514 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
8516 /* Loads. */
8517 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
8518 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
8519 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
8520 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
8521 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
8522 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
8523 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
8524 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
8525 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
8526 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
8527 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
8528 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
8529 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
8530 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
8531 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
8532 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
8533 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
8534 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
8535 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
8536 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
8537 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
8538 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
8540 /* Predicates. */
8541 d = (struct builtin_description *) bdesc_spe_predicates;
8542 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
8544 tree type;
8546 switch (insn_data[d->icode].operand[1].mode)
8548 case V2SImode:
8549 type = int_ftype_int_v2si_v2si;
8550 break;
8551 case V2SFmode:
8552 type = int_ftype_int_v2sf_v2sf;
8553 break;
8554 default:
8555 gcc_unreachable ();
8558 def_builtin (d->mask, d->name, type, d->code);
8561 /* Evsel predicates. */
8562 d = (struct builtin_description *) bdesc_spe_evsel;
8563 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
8565 tree type;
8567 switch (insn_data[d->icode].operand[1].mode)
8569 case V2SImode:
8570 type = v2si_ftype_4_v2si;
8571 break;
8572 case V2SFmode:
8573 type = v2sf_ftype_4_v2sf;
8574 break;
8575 default:
8576 gcc_unreachable ();
8579 def_builtin (d->mask, d->name, type, d->code);
8583 static void
8584 altivec_init_builtins (void)
8586 struct builtin_description *d;
8587 struct builtin_description_predicates *dp;
8588 size_t i;
8589 tree ftype;
8591 tree pfloat_type_node = build_pointer_type (float_type_node);
8592 tree pint_type_node = build_pointer_type (integer_type_node);
8593 tree pshort_type_node = build_pointer_type (short_integer_type_node);
8594 tree pchar_type_node = build_pointer_type (char_type_node);
8596 tree pvoid_type_node = build_pointer_type (void_type_node);
8598 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
8599 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
8600 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
8601 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
8603 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
8605 tree int_ftype_opaque
8606 = build_function_type_list (integer_type_node,
8607 opaque_V4SI_type_node, NULL_TREE);
8609 tree opaque_ftype_opaque_int
8610 = build_function_type_list (opaque_V4SI_type_node,
8611 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
8612 tree opaque_ftype_opaque_opaque_int
8613 = build_function_type_list (opaque_V4SI_type_node,
8614 opaque_V4SI_type_node, opaque_V4SI_type_node,
8615 integer_type_node, NULL_TREE);
8616 tree int_ftype_int_opaque_opaque
8617 = build_function_type_list (integer_type_node,
8618 integer_type_node, opaque_V4SI_type_node,
8619 opaque_V4SI_type_node, NULL_TREE);
8620 tree int_ftype_int_v4si_v4si
8621 = build_function_type_list (integer_type_node,
8622 integer_type_node, V4SI_type_node,
8623 V4SI_type_node, NULL_TREE);
8624 tree v4sf_ftype_pcfloat
8625 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
8626 tree void_ftype_pfloat_v4sf
8627 = build_function_type_list (void_type_node,
8628 pfloat_type_node, V4SF_type_node, NULL_TREE);
8629 tree v4si_ftype_pcint
8630 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
8631 tree void_ftype_pint_v4si
8632 = build_function_type_list (void_type_node,
8633 pint_type_node, V4SI_type_node, NULL_TREE);
8634 tree v8hi_ftype_pcshort
8635 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
8636 tree void_ftype_pshort_v8hi
8637 = build_function_type_list (void_type_node,
8638 pshort_type_node, V8HI_type_node, NULL_TREE);
8639 tree v16qi_ftype_pcchar
8640 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
8641 tree void_ftype_pchar_v16qi
8642 = build_function_type_list (void_type_node,
8643 pchar_type_node, V16QI_type_node, NULL_TREE);
8644 tree void_ftype_v4si
8645 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
8646 tree v8hi_ftype_void
8647 = build_function_type (V8HI_type_node, void_list_node);
8648 tree void_ftype_void
8649 = build_function_type (void_type_node, void_list_node);
8650 tree void_ftype_int
8651 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
8653 tree opaque_ftype_long_pcvoid
8654 = build_function_type_list (opaque_V4SI_type_node,
8655 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8656 tree v16qi_ftype_long_pcvoid
8657 = build_function_type_list (V16QI_type_node,
8658 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8659 tree v8hi_ftype_long_pcvoid
8660 = build_function_type_list (V8HI_type_node,
8661 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8662 tree v4si_ftype_long_pcvoid
8663 = build_function_type_list (V4SI_type_node,
8664 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8666 tree void_ftype_opaque_long_pvoid
8667 = build_function_type_list (void_type_node,
8668 opaque_V4SI_type_node, long_integer_type_node,
8669 pvoid_type_node, NULL_TREE);
8670 tree void_ftype_v4si_long_pvoid
8671 = build_function_type_list (void_type_node,
8672 V4SI_type_node, long_integer_type_node,
8673 pvoid_type_node, NULL_TREE);
8674 tree void_ftype_v16qi_long_pvoid
8675 = build_function_type_list (void_type_node,
8676 V16QI_type_node, long_integer_type_node,
8677 pvoid_type_node, NULL_TREE);
8678 tree void_ftype_v8hi_long_pvoid
8679 = build_function_type_list (void_type_node,
8680 V8HI_type_node, long_integer_type_node,
8681 pvoid_type_node, NULL_TREE);
8682 tree int_ftype_int_v8hi_v8hi
8683 = build_function_type_list (integer_type_node,
8684 integer_type_node, V8HI_type_node,
8685 V8HI_type_node, NULL_TREE);
8686 tree int_ftype_int_v16qi_v16qi
8687 = build_function_type_list (integer_type_node,
8688 integer_type_node, V16QI_type_node,
8689 V16QI_type_node, NULL_TREE);
8690 tree int_ftype_int_v4sf_v4sf
8691 = build_function_type_list (integer_type_node,
8692 integer_type_node, V4SF_type_node,
8693 V4SF_type_node, NULL_TREE);
8694 tree v4si_ftype_v4si
8695 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
8696 tree v8hi_ftype_v8hi
8697 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
8698 tree v16qi_ftype_v16qi
8699 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
8700 tree v4sf_ftype_v4sf
8701 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8702 tree void_ftype_pcvoid_int_int
8703 = build_function_type_list (void_type_node,
8704 pcvoid_type_node, integer_type_node,
8705 integer_type_node, NULL_TREE);
8707 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
8708 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
8709 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
8710 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
8711 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
8712 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
8713 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
8714 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
8715 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
8716 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
8717 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
8718 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
8719 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
8720 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
8721 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
8722 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
8723 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
8724 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
8725 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
8726 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
8727 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
8728 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
8729 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
8730 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
8731 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
8732 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
8733 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
8734 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
8735 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
8736 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
8737 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
8738 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
8739 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
8740 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
8741 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
8742 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
8743 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
8744 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
8745 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
8746 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
8747 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
8748 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
8749 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
8750 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
8751 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
8752 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
8754 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
8756 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
8757 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
8758 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
8759 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
8760 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
8761 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
8762 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
8763 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
8764 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
8765 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
8767 /* Add the DST variants. */
8768 d = (struct builtin_description *) bdesc_dst;
8769 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8770 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
8772 /* Initialize the predicates. */
8773 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
8774 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
8776 enum machine_mode mode1;
8777 tree type;
8778 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8779 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8781 if (is_overloaded)
8782 mode1 = VOIDmode;
8783 else
8784 mode1 = insn_data[dp->icode].operand[1].mode;
8786 switch (mode1)
8788 case VOIDmode:
8789 type = int_ftype_int_opaque_opaque;
8790 break;
8791 case V4SImode:
8792 type = int_ftype_int_v4si_v4si;
8793 break;
8794 case V8HImode:
8795 type = int_ftype_int_v8hi_v8hi;
8796 break;
8797 case V16QImode:
8798 type = int_ftype_int_v16qi_v16qi;
8799 break;
8800 case V4SFmode:
8801 type = int_ftype_int_v4sf_v4sf;
8802 break;
8803 default:
8804 gcc_unreachable ();
8807 def_builtin (dp->mask, dp->name, type, dp->code);
8810 /* Initialize the abs* operators. */
8811 d = (struct builtin_description *) bdesc_abs;
8812 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
8814 enum machine_mode mode0;
8815 tree type;
8817 mode0 = insn_data[d->icode].operand[0].mode;
8819 switch (mode0)
8821 case V4SImode:
8822 type = v4si_ftype_v4si;
8823 break;
8824 case V8HImode:
8825 type = v8hi_ftype_v8hi;
8826 break;
8827 case V16QImode:
8828 type = v16qi_ftype_v16qi;
8829 break;
8830 case V4SFmode:
8831 type = v4sf_ftype_v4sf;
8832 break;
8833 default:
8834 gcc_unreachable ();
8837 def_builtin (d->mask, d->name, type, d->code);
8840 if (TARGET_ALTIVEC)
8842 tree decl;
8844 /* Initialize target builtin that implements
8845 targetm.vectorize.builtin_mask_for_load. */
8847 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
8848 v16qi_ftype_long_pcvoid,
8849 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
8850 BUILT_IN_MD, NULL, NULL_TREE);
8851 TREE_READONLY (decl) = 1;
8852 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8853 altivec_builtin_mask_for_load = decl;
8856 /* Access to the vec_init patterns. */
8857 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
8858 integer_type_node, integer_type_node,
8859 integer_type_node, NULL_TREE);
8860 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
8861 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
8863 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
8864 short_integer_type_node,
8865 short_integer_type_node,
8866 short_integer_type_node,
8867 short_integer_type_node,
8868 short_integer_type_node,
8869 short_integer_type_node,
8870 short_integer_type_node, NULL_TREE);
8871 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
8872 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
8874 ftype = build_function_type_list (V16QI_type_node, char_type_node,
8875 char_type_node, char_type_node,
8876 char_type_node, char_type_node,
8877 char_type_node, char_type_node,
8878 char_type_node, char_type_node,
8879 char_type_node, char_type_node,
8880 char_type_node, char_type_node,
8881 char_type_node, char_type_node,
8882 char_type_node, NULL_TREE);
8883 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
8884 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
8886 ftype = build_function_type_list (V4SF_type_node, float_type_node,
8887 float_type_node, float_type_node,
8888 float_type_node, NULL_TREE);
8889 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
8890 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
8892 /* Access to the vec_set patterns. */
8893 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
8894 intSI_type_node,
8895 integer_type_node, NULL_TREE);
8896 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
8897 ALTIVEC_BUILTIN_VEC_SET_V4SI);
8899 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
8900 intHI_type_node,
8901 integer_type_node, NULL_TREE);
8902 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
8903 ALTIVEC_BUILTIN_VEC_SET_V8HI);
8905 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
8906 intQI_type_node,
8907 integer_type_node, NULL_TREE);
8908 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
8909 ALTIVEC_BUILTIN_VEC_SET_V16QI);
8911 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
8912 float_type_node,
8913 integer_type_node, NULL_TREE);
8914 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
8915 ALTIVEC_BUILTIN_VEC_SET_V4SF);
8917 /* Access to the vec_extract patterns. */
8918 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
8919 integer_type_node, NULL_TREE);
8920 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
8921 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
8923 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
8924 integer_type_node, NULL_TREE);
8925 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
8926 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
8928 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
8929 integer_type_node, NULL_TREE);
8930 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
8931 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
8933 ftype = build_function_type_list (float_type_node, V4SF_type_node,
8934 integer_type_node, NULL_TREE);
8935 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
8936 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
8939 static void
8940 rs6000_common_init_builtins (void)
8942 struct builtin_description *d;
8943 size_t i;
8945 tree v4sf_ftype_v4sf_v4sf_v16qi
8946 = build_function_type_list (V4SF_type_node,
8947 V4SF_type_node, V4SF_type_node,
8948 V16QI_type_node, NULL_TREE);
8949 tree v4si_ftype_v4si_v4si_v16qi
8950 = build_function_type_list (V4SI_type_node,
8951 V4SI_type_node, V4SI_type_node,
8952 V16QI_type_node, NULL_TREE);
8953 tree v8hi_ftype_v8hi_v8hi_v16qi
8954 = build_function_type_list (V8HI_type_node,
8955 V8HI_type_node, V8HI_type_node,
8956 V16QI_type_node, NULL_TREE);
8957 tree v16qi_ftype_v16qi_v16qi_v16qi
8958 = build_function_type_list (V16QI_type_node,
8959 V16QI_type_node, V16QI_type_node,
8960 V16QI_type_node, NULL_TREE);
8961 tree v4si_ftype_int
8962 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
8963 tree v8hi_ftype_int
8964 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
8965 tree v16qi_ftype_int
8966 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
8967 tree v8hi_ftype_v16qi
8968 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
8969 tree v4sf_ftype_v4sf
8970 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8972 tree v2si_ftype_v2si_v2si
8973 = build_function_type_list (opaque_V2SI_type_node,
8974 opaque_V2SI_type_node,
8975 opaque_V2SI_type_node, NULL_TREE);
8977 tree v2sf_ftype_v2sf_v2sf
8978 = build_function_type_list (opaque_V2SF_type_node,
8979 opaque_V2SF_type_node,
8980 opaque_V2SF_type_node, NULL_TREE);
8982 tree v2si_ftype_int_int
8983 = build_function_type_list (opaque_V2SI_type_node,
8984 integer_type_node, integer_type_node,
8985 NULL_TREE);
8987 tree opaque_ftype_opaque
8988 = build_function_type_list (opaque_V4SI_type_node,
8989 opaque_V4SI_type_node, NULL_TREE);
8991 tree v2si_ftype_v2si
8992 = build_function_type_list (opaque_V2SI_type_node,
8993 opaque_V2SI_type_node, NULL_TREE);
8995 tree v2sf_ftype_v2sf
8996 = build_function_type_list (opaque_V2SF_type_node,
8997 opaque_V2SF_type_node, NULL_TREE);
8999 tree v2sf_ftype_v2si
9000 = build_function_type_list (opaque_V2SF_type_node,
9001 opaque_V2SI_type_node, NULL_TREE);
9003 tree v2si_ftype_v2sf
9004 = build_function_type_list (opaque_V2SI_type_node,
9005 opaque_V2SF_type_node, NULL_TREE);
9007 tree v2si_ftype_v2si_char
9008 = build_function_type_list (opaque_V2SI_type_node,
9009 opaque_V2SI_type_node,
9010 char_type_node, NULL_TREE);
9012 tree v2si_ftype_int_char
9013 = build_function_type_list (opaque_V2SI_type_node,
9014 integer_type_node, char_type_node, NULL_TREE);
9016 tree v2si_ftype_char
9017 = build_function_type_list (opaque_V2SI_type_node,
9018 char_type_node, NULL_TREE);
9020 tree int_ftype_int_int
9021 = build_function_type_list (integer_type_node,
9022 integer_type_node, integer_type_node,
9023 NULL_TREE);
9025 tree opaque_ftype_opaque_opaque
9026 = build_function_type_list (opaque_V4SI_type_node,
9027 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
9028 tree v4si_ftype_v4si_v4si
9029 = build_function_type_list (V4SI_type_node,
9030 V4SI_type_node, V4SI_type_node, NULL_TREE);
9031 tree v4sf_ftype_v4si_int
9032 = build_function_type_list (V4SF_type_node,
9033 V4SI_type_node, integer_type_node, NULL_TREE);
9034 tree v4si_ftype_v4sf_int
9035 = build_function_type_list (V4SI_type_node,
9036 V4SF_type_node, integer_type_node, NULL_TREE);
9037 tree v4si_ftype_v4si_int
9038 = build_function_type_list (V4SI_type_node,
9039 V4SI_type_node, integer_type_node, NULL_TREE);
9040 tree v8hi_ftype_v8hi_int
9041 = build_function_type_list (V8HI_type_node,
9042 V8HI_type_node, integer_type_node, NULL_TREE);
9043 tree v16qi_ftype_v16qi_int
9044 = build_function_type_list (V16QI_type_node,
9045 V16QI_type_node, integer_type_node, NULL_TREE);
9046 tree v16qi_ftype_v16qi_v16qi_int
9047 = build_function_type_list (V16QI_type_node,
9048 V16QI_type_node, V16QI_type_node,
9049 integer_type_node, NULL_TREE);
9050 tree v8hi_ftype_v8hi_v8hi_int
9051 = build_function_type_list (V8HI_type_node,
9052 V8HI_type_node, V8HI_type_node,
9053 integer_type_node, NULL_TREE);
9054 tree v4si_ftype_v4si_v4si_int
9055 = build_function_type_list (V4SI_type_node,
9056 V4SI_type_node, V4SI_type_node,
9057 integer_type_node, NULL_TREE);
9058 tree v4sf_ftype_v4sf_v4sf_int
9059 = build_function_type_list (V4SF_type_node,
9060 V4SF_type_node, V4SF_type_node,
9061 integer_type_node, NULL_TREE);
9062 tree v4sf_ftype_v4sf_v4sf
9063 = build_function_type_list (V4SF_type_node,
9064 V4SF_type_node, V4SF_type_node, NULL_TREE);
9065 tree opaque_ftype_opaque_opaque_opaque
9066 = build_function_type_list (opaque_V4SI_type_node,
9067 opaque_V4SI_type_node, opaque_V4SI_type_node,
9068 opaque_V4SI_type_node, NULL_TREE);
9069 tree v4sf_ftype_v4sf_v4sf_v4si
9070 = build_function_type_list (V4SF_type_node,
9071 V4SF_type_node, V4SF_type_node,
9072 V4SI_type_node, NULL_TREE);
9073 tree v4sf_ftype_v4sf_v4sf_v4sf
9074 = build_function_type_list (V4SF_type_node,
9075 V4SF_type_node, V4SF_type_node,
9076 V4SF_type_node, NULL_TREE);
9077 tree v4si_ftype_v4si_v4si_v4si
9078 = build_function_type_list (V4SI_type_node,
9079 V4SI_type_node, V4SI_type_node,
9080 V4SI_type_node, NULL_TREE);
9081 tree v8hi_ftype_v8hi_v8hi
9082 = build_function_type_list (V8HI_type_node,
9083 V8HI_type_node, V8HI_type_node, NULL_TREE);
9084 tree v8hi_ftype_v8hi_v8hi_v8hi
9085 = build_function_type_list (V8HI_type_node,
9086 V8HI_type_node, V8HI_type_node,
9087 V8HI_type_node, NULL_TREE);
9088 tree v4si_ftype_v8hi_v8hi_v4si
9089 = build_function_type_list (V4SI_type_node,
9090 V8HI_type_node, V8HI_type_node,
9091 V4SI_type_node, NULL_TREE);
9092 tree v4si_ftype_v16qi_v16qi_v4si
9093 = build_function_type_list (V4SI_type_node,
9094 V16QI_type_node, V16QI_type_node,
9095 V4SI_type_node, NULL_TREE);
9096 tree v16qi_ftype_v16qi_v16qi
9097 = build_function_type_list (V16QI_type_node,
9098 V16QI_type_node, V16QI_type_node, NULL_TREE);
9099 tree v4si_ftype_v4sf_v4sf
9100 = build_function_type_list (V4SI_type_node,
9101 V4SF_type_node, V4SF_type_node, NULL_TREE);
9102 tree v8hi_ftype_v16qi_v16qi
9103 = build_function_type_list (V8HI_type_node,
9104 V16QI_type_node, V16QI_type_node, NULL_TREE);
9105 tree v4si_ftype_v8hi_v8hi
9106 = build_function_type_list (V4SI_type_node,
9107 V8HI_type_node, V8HI_type_node, NULL_TREE);
9108 tree v8hi_ftype_v4si_v4si
9109 = build_function_type_list (V8HI_type_node,
9110 V4SI_type_node, V4SI_type_node, NULL_TREE);
9111 tree v16qi_ftype_v8hi_v8hi
9112 = build_function_type_list (V16QI_type_node,
9113 V8HI_type_node, V8HI_type_node, NULL_TREE);
9114 tree v4si_ftype_v16qi_v4si
9115 = build_function_type_list (V4SI_type_node,
9116 V16QI_type_node, V4SI_type_node, NULL_TREE);
9117 tree v4si_ftype_v16qi_v16qi
9118 = build_function_type_list (V4SI_type_node,
9119 V16QI_type_node, V16QI_type_node, NULL_TREE);
9120 tree v4si_ftype_v8hi_v4si
9121 = build_function_type_list (V4SI_type_node,
9122 V8HI_type_node, V4SI_type_node, NULL_TREE);
9123 tree v4si_ftype_v8hi
9124 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
9125 tree int_ftype_v4si_v4si
9126 = build_function_type_list (integer_type_node,
9127 V4SI_type_node, V4SI_type_node, NULL_TREE);
9128 tree int_ftype_v4sf_v4sf
9129 = build_function_type_list (integer_type_node,
9130 V4SF_type_node, V4SF_type_node, NULL_TREE);
9131 tree int_ftype_v16qi_v16qi
9132 = build_function_type_list (integer_type_node,
9133 V16QI_type_node, V16QI_type_node, NULL_TREE);
9134 tree int_ftype_v8hi_v8hi
9135 = build_function_type_list (integer_type_node,
9136 V8HI_type_node, V8HI_type_node, NULL_TREE);
9138 /* Add the simple ternary operators. */
9139 d = (struct builtin_description *) bdesc_3arg;
9140 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
9142 enum machine_mode mode0, mode1, mode2, mode3;
9143 tree type;
9144 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9145 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9147 if (is_overloaded)
9149 mode0 = VOIDmode;
9150 mode1 = VOIDmode;
9151 mode2 = VOIDmode;
9152 mode3 = VOIDmode;
9154 else
9156 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9157 continue;
9159 mode0 = insn_data[d->icode].operand[0].mode;
9160 mode1 = insn_data[d->icode].operand[1].mode;
9161 mode2 = insn_data[d->icode].operand[2].mode;
9162 mode3 = insn_data[d->icode].operand[3].mode;
9165 /* When all four are of the same mode. */
9166 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
9168 switch (mode0)
9170 case VOIDmode:
9171 type = opaque_ftype_opaque_opaque_opaque;
9172 break;
9173 case V4SImode:
9174 type = v4si_ftype_v4si_v4si_v4si;
9175 break;
9176 case V4SFmode:
9177 type = v4sf_ftype_v4sf_v4sf_v4sf;
9178 break;
9179 case V8HImode:
9180 type = v8hi_ftype_v8hi_v8hi_v8hi;
9181 break;
9182 case V16QImode:
9183 type = v16qi_ftype_v16qi_v16qi_v16qi;
9184 break;
9185 default:
9186 gcc_unreachable ();
9189 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
9191 switch (mode0)
9193 case V4SImode:
9194 type = v4si_ftype_v4si_v4si_v16qi;
9195 break;
9196 case V4SFmode:
9197 type = v4sf_ftype_v4sf_v4sf_v16qi;
9198 break;
9199 case V8HImode:
9200 type = v8hi_ftype_v8hi_v8hi_v16qi;
9201 break;
9202 case V16QImode:
9203 type = v16qi_ftype_v16qi_v16qi_v16qi;
9204 break;
9205 default:
9206 gcc_unreachable ();
9209 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
9210 && mode3 == V4SImode)
9211 type = v4si_ftype_v16qi_v16qi_v4si;
9212 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
9213 && mode3 == V4SImode)
9214 type = v4si_ftype_v8hi_v8hi_v4si;
9215 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
9216 && mode3 == V4SImode)
9217 type = v4sf_ftype_v4sf_v4sf_v4si;
9219 /* vchar, vchar, vchar, 4 bit literal. */
9220 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
9221 && mode3 == QImode)
9222 type = v16qi_ftype_v16qi_v16qi_int;
9224 /* vshort, vshort, vshort, 4 bit literal. */
9225 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
9226 && mode3 == QImode)
9227 type = v8hi_ftype_v8hi_v8hi_int;
9229 /* vint, vint, vint, 4 bit literal. */
9230 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
9231 && mode3 == QImode)
9232 type = v4si_ftype_v4si_v4si_int;
9234 /* vfloat, vfloat, vfloat, 4 bit literal. */
9235 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
9236 && mode3 == QImode)
9237 type = v4sf_ftype_v4sf_v4sf_int;
9239 else
9240 gcc_unreachable ();
9242 def_builtin (d->mask, d->name, type, d->code);
9245 /* Add the simple binary operators. */
9246 d = (struct builtin_description *) bdesc_2arg;
9247 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
9249 enum machine_mode mode0, mode1, mode2;
9250 tree type;
9251 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9252 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9254 if (is_overloaded)
9256 mode0 = VOIDmode;
9257 mode1 = VOIDmode;
9258 mode2 = VOIDmode;
9260 else
9262 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9263 continue;
9265 mode0 = insn_data[d->icode].operand[0].mode;
9266 mode1 = insn_data[d->icode].operand[1].mode;
9267 mode2 = insn_data[d->icode].operand[2].mode;
9270 /* When all three operands are of the same mode. */
9271 if (mode0 == mode1 && mode1 == mode2)
9273 switch (mode0)
9275 case VOIDmode:
9276 type = opaque_ftype_opaque_opaque;
9277 break;
9278 case V4SFmode:
9279 type = v4sf_ftype_v4sf_v4sf;
9280 break;
9281 case V4SImode:
9282 type = v4si_ftype_v4si_v4si;
9283 break;
9284 case V16QImode:
9285 type = v16qi_ftype_v16qi_v16qi;
9286 break;
9287 case V8HImode:
9288 type = v8hi_ftype_v8hi_v8hi;
9289 break;
9290 case V2SImode:
9291 type = v2si_ftype_v2si_v2si;
9292 break;
9293 case V2SFmode:
9294 type = v2sf_ftype_v2sf_v2sf;
9295 break;
9296 case SImode:
9297 type = int_ftype_int_int;
9298 break;
9299 default:
9300 gcc_unreachable ();
9304 /* A few other combos we really don't want to do manually. */
9306 /* vint, vfloat, vfloat. */
9307 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
9308 type = v4si_ftype_v4sf_v4sf;
9310 /* vshort, vchar, vchar. */
9311 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
9312 type = v8hi_ftype_v16qi_v16qi;
9314 /* vint, vshort, vshort. */
9315 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
9316 type = v4si_ftype_v8hi_v8hi;
9318 /* vshort, vint, vint. */
9319 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
9320 type = v8hi_ftype_v4si_v4si;
9322 /* vchar, vshort, vshort. */
9323 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
9324 type = v16qi_ftype_v8hi_v8hi;
9326 /* vint, vchar, vint. */
9327 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
9328 type = v4si_ftype_v16qi_v4si;
9330 /* vint, vchar, vchar. */
9331 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
9332 type = v4si_ftype_v16qi_v16qi;
9334 /* vint, vshort, vint. */
9335 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
9336 type = v4si_ftype_v8hi_v4si;
9338 /* vint, vint, 5 bit literal. */
9339 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
9340 type = v4si_ftype_v4si_int;
9342 /* vshort, vshort, 5 bit literal. */
9343 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
9344 type = v8hi_ftype_v8hi_int;
9346 /* vchar, vchar, 5 bit literal. */
9347 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
9348 type = v16qi_ftype_v16qi_int;
9350 /* vfloat, vint, 5 bit literal. */
9351 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
9352 type = v4sf_ftype_v4si_int;
9354 /* vint, vfloat, 5 bit literal. */
9355 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
9356 type = v4si_ftype_v4sf_int;
9358 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
9359 type = v2si_ftype_int_int;
9361 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
9362 type = v2si_ftype_v2si_char;
9364 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
9365 type = v2si_ftype_int_char;
9367 else
9369 /* int, x, x. */
9370 gcc_assert (mode0 == SImode);
9371 switch (mode1)
9373 case V4SImode:
9374 type = int_ftype_v4si_v4si;
9375 break;
9376 case V4SFmode:
9377 type = int_ftype_v4sf_v4sf;
9378 break;
9379 case V16QImode:
9380 type = int_ftype_v16qi_v16qi;
9381 break;
9382 case V8HImode:
9383 type = int_ftype_v8hi_v8hi;
9384 break;
9385 default:
9386 gcc_unreachable ();
9390 def_builtin (d->mask, d->name, type, d->code);
9393 /* Add the simple unary operators. */
9394 d = (struct builtin_description *) bdesc_1arg;
9395 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
9397 enum machine_mode mode0, mode1;
9398 tree type;
9399 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9400 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9402 if (is_overloaded)
9404 mode0 = VOIDmode;
9405 mode1 = VOIDmode;
9407 else
9409 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9410 continue;
9412 mode0 = insn_data[d->icode].operand[0].mode;
9413 mode1 = insn_data[d->icode].operand[1].mode;
9416 if (mode0 == V4SImode && mode1 == QImode)
9417 type = v4si_ftype_int;
9418 else if (mode0 == V8HImode && mode1 == QImode)
9419 type = v8hi_ftype_int;
9420 else if (mode0 == V16QImode && mode1 == QImode)
9421 type = v16qi_ftype_int;
9422 else if (mode0 == VOIDmode && mode1 == VOIDmode)
9423 type = opaque_ftype_opaque;
9424 else if (mode0 == V4SFmode && mode1 == V4SFmode)
9425 type = v4sf_ftype_v4sf;
9426 else if (mode0 == V8HImode && mode1 == V16QImode)
9427 type = v8hi_ftype_v16qi;
9428 else if (mode0 == V4SImode && mode1 == V8HImode)
9429 type = v4si_ftype_v8hi;
9430 else if (mode0 == V2SImode && mode1 == V2SImode)
9431 type = v2si_ftype_v2si;
9432 else if (mode0 == V2SFmode && mode1 == V2SFmode)
9433 type = v2sf_ftype_v2sf;
9434 else if (mode0 == V2SFmode && mode1 == V2SImode)
9435 type = v2sf_ftype_v2si;
9436 else if (mode0 == V2SImode && mode1 == V2SFmode)
9437 type = v2si_ftype_v2sf;
9438 else if (mode0 == V2SImode && mode1 == QImode)
9439 type = v2si_ftype_char;
9440 else
9441 gcc_unreachable ();
9443 def_builtin (d->mask, d->name, type, d->code);
9447 static void
9448 rs6000_init_libfuncs (void)
9450 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
9451 && !TARGET_POWER2 && !TARGET_POWERPC)
9453 /* AIX library routines for float->int conversion. */
9454 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
9455 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
9456 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
9457 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
9460 if (!TARGET_IEEEQUAD)
9461 /* AIX/Darwin/64-bit Linux quad floating point routines. */
9462 if (!TARGET_XL_COMPAT)
9464 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
9465 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
9466 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
9467 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
9469 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
9471 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
9472 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
9473 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
9474 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
9475 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
9476 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
9477 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
9478 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
9480 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
9481 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
9482 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
9483 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
9484 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
9485 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
9486 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
9487 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
9490 else
9492 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
9493 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
9494 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
9495 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
9497 else
9499 /* 32-bit SVR4 quad floating point routines. */
9501 set_optab_libfunc (add_optab, TFmode, "_q_add");
9502 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
9503 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
9504 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
9505 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
9506 if (TARGET_PPC_GPOPT || TARGET_POWER2)
9507 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
9509 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
9510 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
9511 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
9512 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
9513 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
9514 set_optab_libfunc (le_optab, TFmode, "_q_fle");
9516 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
9517 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
9518 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
9519 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
9520 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
9521 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
9522 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
9523 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
9528 /* Expand a block clear operation, and return 1 if successful. Return 0
9529 if we should let the compiler generate normal code.
9531 operands[0] is the destination
9532 operands[1] is the length
9533 operands[3] is the alignment */
9536 expand_block_clear (rtx operands[])
9538 rtx orig_dest = operands[0];
9539 rtx bytes_rtx = operands[1];
9540 rtx align_rtx = operands[3];
9541 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
9542 HOST_WIDE_INT align;
9543 HOST_WIDE_INT bytes;
9544 int offset;
9545 int clear_bytes;
9546 int clear_step;
9548 /* If this is not a fixed size move, just call memcpy */
9549 if (! constp)
9550 return 0;
9552 /* This must be a fixed size alignment */
9553 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9554 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9556 /* Anything to clear? */
9557 bytes = INTVAL (bytes_rtx);
9558 if (bytes <= 0)
9559 return 1;
9561 /* Use the builtin memset after a point, to avoid huge code bloat.
9562 When optimize_size, avoid any significant code bloat; calling
9563 memset is about 4 instructions, so allow for one instruction to
9564 load zero and three to do clearing. */
9565 if (TARGET_ALTIVEC && align >= 128)
9566 clear_step = 16;
9567 else if (TARGET_POWERPC64 && align >= 32)
9568 clear_step = 8;
9569 else
9570 clear_step = 4;
9572 if (optimize_size && bytes > 3 * clear_step)
9573 return 0;
9574 if (! optimize_size && bytes > 8 * clear_step)
9575 return 0;
9577 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
9579 enum machine_mode mode = BLKmode;
9580 rtx dest;
9582 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
9584 clear_bytes = 16;
9585 mode = V4SImode;
9587 else if (bytes >= 8 && TARGET_POWERPC64
9588 /* 64-bit loads and stores require word-aligned
9589 displacements. */
9590 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9592 clear_bytes = 8;
9593 mode = DImode;
9595 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9596 { /* move 4 bytes */
9597 clear_bytes = 4;
9598 mode = SImode;
9600 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9601 { /* move 2 bytes */
9602 clear_bytes = 2;
9603 mode = HImode;
9605 else /* move 1 byte at a time */
9607 clear_bytes = 1;
9608 mode = QImode;
9611 dest = adjust_address (orig_dest, mode, offset);
9613 emit_move_insn (dest, CONST0_RTX (mode));
9616 return 1;
9620 /* Expand a block move operation, and return 1 if successful. Return 0
9621 if we should let the compiler generate normal code.
9623 operands[0] is the destination
9624 operands[1] is the source
9625 operands[2] is the length
9626 operands[3] is the alignment */
9628 #define MAX_MOVE_REG 4
9631 expand_block_move (rtx operands[])
9633 rtx orig_dest = operands[0];
9634 rtx orig_src = operands[1];
9635 rtx bytes_rtx = operands[2];
9636 rtx align_rtx = operands[3];
9637 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
9638 int align;
9639 int bytes;
9640 int offset;
9641 int move_bytes;
9642 rtx stores[MAX_MOVE_REG];
9643 int num_reg = 0;
9645 /* If this is not a fixed size move, just call memcpy */
9646 if (! constp)
9647 return 0;
9649 /* This must be a fixed size alignment */
9650 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9651 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9653 /* Anything to move? */
9654 bytes = INTVAL (bytes_rtx);
9655 if (bytes <= 0)
9656 return 1;
9658 /* store_one_arg depends on expand_block_move to handle at least the size of
9659 reg_parm_stack_space. */
9660 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
9661 return 0;
9663 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
9665 union {
9666 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
9667 rtx (*mov) (rtx, rtx);
9668 } gen_func;
9669 enum machine_mode mode = BLKmode;
9670 rtx src, dest;
9672 /* Altivec first, since it will be faster than a string move
9673 when it applies, and usually not significantly larger. */
9674 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
9676 move_bytes = 16;
9677 mode = V4SImode;
9678 gen_func.mov = gen_movv4si;
9680 else if (TARGET_STRING
9681 && bytes > 24 /* move up to 32 bytes at a time */
9682 && ! fixed_regs[5]
9683 && ! fixed_regs[6]
9684 && ! fixed_regs[7]
9685 && ! fixed_regs[8]
9686 && ! fixed_regs[9]
9687 && ! fixed_regs[10]
9688 && ! fixed_regs[11]
9689 && ! fixed_regs[12])
9691 move_bytes = (bytes > 32) ? 32 : bytes;
9692 gen_func.movmemsi = gen_movmemsi_8reg;
9694 else if (TARGET_STRING
9695 && bytes > 16 /* move up to 24 bytes at a time */
9696 && ! fixed_regs[5]
9697 && ! fixed_regs[6]
9698 && ! fixed_regs[7]
9699 && ! fixed_regs[8]
9700 && ! fixed_regs[9]
9701 && ! fixed_regs[10])
9703 move_bytes = (bytes > 24) ? 24 : bytes;
9704 gen_func.movmemsi = gen_movmemsi_6reg;
9706 else if (TARGET_STRING
9707 && bytes > 8 /* move up to 16 bytes at a time */
9708 && ! fixed_regs[5]
9709 && ! fixed_regs[6]
9710 && ! fixed_regs[7]
9711 && ! fixed_regs[8])
9713 move_bytes = (bytes > 16) ? 16 : bytes;
9714 gen_func.movmemsi = gen_movmemsi_4reg;
9716 else if (bytes >= 8 && TARGET_POWERPC64
9717 /* 64-bit loads and stores require word-aligned
9718 displacements. */
9719 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9721 move_bytes = 8;
9722 mode = DImode;
9723 gen_func.mov = gen_movdi;
9725 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
9726 { /* move up to 8 bytes at a time */
9727 move_bytes = (bytes > 8) ? 8 : bytes;
9728 gen_func.movmemsi = gen_movmemsi_2reg;
9730 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9731 { /* move 4 bytes */
9732 move_bytes = 4;
9733 mode = SImode;
9734 gen_func.mov = gen_movsi;
9736 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9737 { /* move 2 bytes */
9738 move_bytes = 2;
9739 mode = HImode;
9740 gen_func.mov = gen_movhi;
9742 else if (TARGET_STRING && bytes > 1)
9743 { /* move up to 4 bytes at a time */
9744 move_bytes = (bytes > 4) ? 4 : bytes;
9745 gen_func.movmemsi = gen_movmemsi_1reg;
9747 else /* move 1 byte at a time */
9749 move_bytes = 1;
9750 mode = QImode;
9751 gen_func.mov = gen_movqi;
9754 src = adjust_address (orig_src, mode, offset);
9755 dest = adjust_address (orig_dest, mode, offset);
9757 if (mode != BLKmode)
9759 rtx tmp_reg = gen_reg_rtx (mode);
9761 emit_insn ((*gen_func.mov) (tmp_reg, src));
9762 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
9765 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
9767 int i;
9768 for (i = 0; i < num_reg; i++)
9769 emit_insn (stores[i]);
9770 num_reg = 0;
9773 if (mode == BLKmode)
9775 /* Move the address into scratch registers. The movmemsi
9776 patterns require zero offset. */
9777 if (!REG_P (XEXP (src, 0)))
9779 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
9780 src = replace_equiv_address (src, src_reg);
9782 set_mem_size (src, GEN_INT (move_bytes));
9784 if (!REG_P (XEXP (dest, 0)))
9786 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
9787 dest = replace_equiv_address (dest, dest_reg);
9789 set_mem_size (dest, GEN_INT (move_bytes));
9791 emit_insn ((*gen_func.movmemsi) (dest, src,
9792 GEN_INT (move_bytes & 31),
9793 align_rtx));
9797 return 1;
9801 /* Return a string to perform a load_multiple operation.
9802 operands[0] is the vector.
9803 operands[1] is the source address.
9804 operands[2] is the first destination register. */
9806 const char *
9807 rs6000_output_load_multiple (rtx operands[3])
9809 /* We have to handle the case where the pseudo used to contain the address
9810 is assigned to one of the output registers. */
9811 int i, j;
9812 int words = XVECLEN (operands[0], 0);
9813 rtx xop[10];
9815 if (XVECLEN (operands[0], 0) == 1)
9816 return "{l|lwz} %2,0(%1)";
9818 for (i = 0; i < words; i++)
9819 if (refers_to_regno_p (REGNO (operands[2]) + i,
9820 REGNO (operands[2]) + i + 1, operands[1], 0))
9822 if (i == words-1)
9824 xop[0] = GEN_INT (4 * (words-1));
9825 xop[1] = operands[1];
9826 xop[2] = operands[2];
9827 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
9828 return "";
9830 else if (i == 0)
9832 xop[0] = GEN_INT (4 * (words-1));
9833 xop[1] = operands[1];
9834 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
9835 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);
9836 return "";
9838 else
9840 for (j = 0; j < words; j++)
9841 if (j != i)
9843 xop[0] = GEN_INT (j * 4);
9844 xop[1] = operands[1];
9845 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
9846 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
9848 xop[0] = GEN_INT (i * 4);
9849 xop[1] = operands[1];
9850 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
9851 return "";
9855 return "{lsi|lswi} %2,%1,%N0";
9859 /* A validation routine: say whether CODE, a condition code, and MODE
9860 match. The other alternatives either don't make sense or should
9861 never be generated. */
9863 void
9864 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
9866 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
9867 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
9868 && GET_MODE_CLASS (mode) == MODE_CC);
9870 /* These don't make sense. */
9871 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
9872 || mode != CCUNSmode);
9874 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
9875 || mode == CCUNSmode);
9877 gcc_assert (mode == CCFPmode
9878 || (code != ORDERED && code != UNORDERED
9879 && code != UNEQ && code != LTGT
9880 && code != UNGT && code != UNLT
9881 && code != UNGE && code != UNLE));
9883 /* These should never be generated except for
9884 flag_finite_math_only. */
9885 gcc_assert (mode != CCFPmode
9886 || flag_finite_math_only
9887 || (code != LE && code != GE
9888 && code != UNEQ && code != LTGT
9889 && code != UNGT && code != UNLT));
9891 /* These are invalid; the information is not there. */
9892 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
9896 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9897 mask required to convert the result of a rotate insn into a shift
9898 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9901 includes_lshift_p (rtx shiftop, rtx andop)
9903 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9905 shift_mask <<= INTVAL (shiftop);
9907 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9910 /* Similar, but for right shift. */
9913 includes_rshift_p (rtx shiftop, rtx andop)
9915 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9917 shift_mask >>= INTVAL (shiftop);
9919 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9922 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9923 to perform a left shift. It must have exactly SHIFTOP least
9924 significant 0's, then one or more 1's, then zero or more 0's. */
9927 includes_rldic_lshift_p (rtx shiftop, rtx andop)
9929 if (GET_CODE (andop) == CONST_INT)
9931 HOST_WIDE_INT c, lsb, shift_mask;
9933 c = INTVAL (andop);
9934 if (c == 0 || c == ~0)
9935 return 0;
9937 shift_mask = ~0;
9938 shift_mask <<= INTVAL (shiftop);
9940 /* Find the least significant one bit. */
9941 lsb = c & -c;
9943 /* It must coincide with the LSB of the shift mask. */
9944 if (-lsb != shift_mask)
9945 return 0;
9947 /* Invert to look for the next transition (if any). */
9948 c = ~c;
9950 /* Remove the low group of ones (originally low group of zeros). */
9951 c &= -lsb;
9953 /* Again find the lsb, and check we have all 1's above. */
9954 lsb = c & -c;
9955 return c == -lsb;
9957 else if (GET_CODE (andop) == CONST_DOUBLE
9958 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9960 HOST_WIDE_INT low, high, lsb;
9961 HOST_WIDE_INT shift_mask_low, shift_mask_high;
9963 low = CONST_DOUBLE_LOW (andop);
9964 if (HOST_BITS_PER_WIDE_INT < 64)
9965 high = CONST_DOUBLE_HIGH (andop);
9967 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
9968 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
9969 return 0;
9971 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9973 shift_mask_high = ~0;
9974 if (INTVAL (shiftop) > 32)
9975 shift_mask_high <<= INTVAL (shiftop) - 32;
9977 lsb = high & -high;
9979 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
9980 return 0;
9982 high = ~high;
9983 high &= -lsb;
9985 lsb = high & -high;
9986 return high == -lsb;
9989 shift_mask_low = ~0;
9990 shift_mask_low <<= INTVAL (shiftop);
9992 lsb = low & -low;
9994 if (-lsb != shift_mask_low)
9995 return 0;
9997 if (HOST_BITS_PER_WIDE_INT < 64)
9998 high = ~high;
9999 low = ~low;
10000 low &= -lsb;
10002 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
10004 lsb = high & -high;
10005 return high == -lsb;
10008 lsb = low & -low;
10009 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
10011 else
10012 return 0;
10015 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
10016 to perform a left shift. It must have SHIFTOP or more least
10017 significant 0's, with the remainder of the word 1's. */
10020 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
10022 if (GET_CODE (andop) == CONST_INT)
10024 HOST_WIDE_INT c, lsb, shift_mask;
10026 shift_mask = ~0;
10027 shift_mask <<= INTVAL (shiftop);
10028 c = INTVAL (andop);
10030 /* Find the least significant one bit. */
10031 lsb = c & -c;
10033 /* It must be covered by the shift mask.
10034 This test also rejects c == 0. */
10035 if ((lsb & shift_mask) == 0)
10036 return 0;
10038 /* Check we have all 1's above the transition, and reject all 1's. */
10039 return c == -lsb && lsb != 1;
10041 else if (GET_CODE (andop) == CONST_DOUBLE
10042 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
10044 HOST_WIDE_INT low, lsb, shift_mask_low;
10046 low = CONST_DOUBLE_LOW (andop);
10048 if (HOST_BITS_PER_WIDE_INT < 64)
10050 HOST_WIDE_INT high, shift_mask_high;
10052 high = CONST_DOUBLE_HIGH (andop);
10054 if (low == 0)
10056 shift_mask_high = ~0;
10057 if (INTVAL (shiftop) > 32)
10058 shift_mask_high <<= INTVAL (shiftop) - 32;
10060 lsb = high & -high;
10062 if ((lsb & shift_mask_high) == 0)
10063 return 0;
10065 return high == -lsb;
10067 if (high != ~0)
10068 return 0;
10071 shift_mask_low = ~0;
10072 shift_mask_low <<= INTVAL (shiftop);
10074 lsb = low & -low;
10076 if ((lsb & shift_mask_low) == 0)
10077 return 0;
10079 return low == -lsb && lsb != 1;
10081 else
10082 return 0;
10085 /* Return 1 if operands will generate a valid arguments to rlwimi
10086 instruction for insert with right shift in 64-bit mode. The mask may
10087 not start on the first bit or stop on the last bit because wrap-around
10088 effects of instruction do not correspond to semantics of RTL insn. */
10091 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
10093 if (INTVAL (startop) > 32
10094 && INTVAL (startop) < 64
10095 && INTVAL (sizeop) > 1
10096 && INTVAL (sizeop) + INTVAL (startop) < 64
10097 && INTVAL (shiftop) > 0
10098 && INTVAL (sizeop) + INTVAL (shiftop) < 32
10099 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
10100 return 1;
10102 return 0;
10105 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
10106 for lfq and stfq insns iff the registers are hard registers. */
10109 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
10111 /* We might have been passed a SUBREG. */
10112 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
10113 return 0;
10115 /* We might have been passed non floating point registers. */
10116 if (!FP_REGNO_P (REGNO (reg1))
10117 || !FP_REGNO_P (REGNO (reg2)))
10118 return 0;
10120 return (REGNO (reg1) == REGNO (reg2) - 1);
10123 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
10124 addr1 and addr2 must be in consecutive memory locations
10125 (addr2 == addr1 + 8). */
10128 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
10130 rtx addr1, addr2;
10131 unsigned int reg1, reg2;
10132 int offset1, offset2;
10134 /* The mems cannot be volatile. */
10135 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
10136 return 0;
10138 addr1 = XEXP (mem1, 0);
10139 addr2 = XEXP (mem2, 0);
10141 /* Extract an offset (if used) from the first addr. */
10142 if (GET_CODE (addr1) == PLUS)
10144 /* If not a REG, return zero. */
10145 if (GET_CODE (XEXP (addr1, 0)) != REG)
10146 return 0;
10147 else
10149 reg1 = REGNO (XEXP (addr1, 0));
10150 /* The offset must be constant! */
10151 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
10152 return 0;
10153 offset1 = INTVAL (XEXP (addr1, 1));
10156 else if (GET_CODE (addr1) != REG)
10157 return 0;
10158 else
10160 reg1 = REGNO (addr1);
10161 /* This was a simple (mem (reg)) expression. Offset is 0. */
10162 offset1 = 0;
10165 /* And now for the second addr. */
10166 if (GET_CODE (addr2) == PLUS)
10168 /* If not a REG, return zero. */
10169 if (GET_CODE (XEXP (addr2, 0)) != REG)
10170 return 0;
10171 else
10173 reg2 = REGNO (XEXP (addr2, 0));
10174 /* The offset must be constant. */
10175 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
10176 return 0;
10177 offset2 = INTVAL (XEXP (addr2, 1));
10180 else if (GET_CODE (addr2) != REG)
10181 return 0;
10182 else
10184 reg2 = REGNO (addr2);
10185 /* This was a simple (mem (reg)) expression. Offset is 0. */
10186 offset2 = 0;
10189 /* Both of these must have the same base register. */
10190 if (reg1 != reg2)
10191 return 0;
10193 /* The offset for the second addr must be 8 more than the first addr. */
10194 if (offset2 != offset1 + 8)
10195 return 0;
10197 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
10198 instructions. */
10199 return 1;
10202 /* Return the register class of a scratch register needed to copy IN into
10203 or out of a register in CLASS in MODE. If it can be done directly,
10204 NO_REGS is returned. */
10206 enum reg_class
10207 rs6000_secondary_reload_class (enum reg_class class,
10208 enum machine_mode mode ATTRIBUTE_UNUSED,
10209 rtx in)
10211 int regno;
10213 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
10214 #if TARGET_MACHO
10215 && MACHOPIC_INDIRECT
10216 #endif
10219 /* We cannot copy a symbolic operand directly into anything
10220 other than BASE_REGS for TARGET_ELF. So indicate that a
10221 register from BASE_REGS is needed as an intermediate
10222 register.
10224 On Darwin, pic addresses require a load from memory, which
10225 needs a base register. */
10226 if (class != BASE_REGS
10227 && (GET_CODE (in) == SYMBOL_REF
10228 || GET_CODE (in) == HIGH
10229 || GET_CODE (in) == LABEL_REF
10230 || GET_CODE (in) == CONST))
10231 return BASE_REGS;
10234 if (GET_CODE (in) == REG)
10236 regno = REGNO (in);
10237 if (regno >= FIRST_PSEUDO_REGISTER)
10239 regno = true_regnum (in);
10240 if (regno >= FIRST_PSEUDO_REGISTER)
10241 regno = -1;
10244 else if (GET_CODE (in) == SUBREG)
10246 regno = true_regnum (in);
10247 if (regno >= FIRST_PSEUDO_REGISTER)
10248 regno = -1;
10250 else
10251 regno = -1;
10253 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
10254 into anything. */
10255 if (class == GENERAL_REGS || class == BASE_REGS
10256 || (regno >= 0 && INT_REGNO_P (regno)))
10257 return NO_REGS;
10259 /* Constants, memory, and FP registers can go into FP registers. */
10260 if ((regno == -1 || FP_REGNO_P (regno))
10261 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
10262 return NO_REGS;
10264 /* Memory, and AltiVec registers can go into AltiVec registers. */
10265 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
10266 && class == ALTIVEC_REGS)
10267 return NO_REGS;
10269 /* We can copy among the CR registers. */
10270 if ((class == CR_REGS || class == CR0_REGS)
10271 && regno >= 0 && CR_REGNO_P (regno))
10272 return NO_REGS;
10274 /* Otherwise, we need GENERAL_REGS. */
10275 return GENERAL_REGS;
10278 /* Given a comparison operation, return the bit number in CCR to test. We
10279 know this is a valid comparison.
10281 SCC_P is 1 if this is for an scc. That means that %D will have been
10282 used instead of %C, so the bits will be in different places.
10284 Return -1 if OP isn't a valid comparison for some reason. */
10287 ccr_bit (rtx op, int scc_p)
10289 enum rtx_code code = GET_CODE (op);
10290 enum machine_mode cc_mode;
10291 int cc_regnum;
10292 int base_bit;
10293 rtx reg;
10295 if (!COMPARISON_P (op))
10296 return -1;
10298 reg = XEXP (op, 0);
10300 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
10302 cc_mode = GET_MODE (reg);
10303 cc_regnum = REGNO (reg);
10304 base_bit = 4 * (cc_regnum - CR0_REGNO);
10306 validate_condition_mode (code, cc_mode);
10308 /* When generating a sCOND operation, only positive conditions are
10309 allowed. */
10310 gcc_assert (!scc_p
10311 || code == EQ || code == GT || code == LT || code == UNORDERED
10312 || code == GTU || code == LTU);
10314 switch (code)
10316 case NE:
10317 return scc_p ? base_bit + 3 : base_bit + 2;
10318 case EQ:
10319 return base_bit + 2;
10320 case GT: case GTU: case UNLE:
10321 return base_bit + 1;
10322 case LT: case LTU: case UNGE:
10323 return base_bit;
10324 case ORDERED: case UNORDERED:
10325 return base_bit + 3;
10327 case GE: case GEU:
10328 /* If scc, we will have done a cror to put the bit in the
10329 unordered position. So test that bit. For integer, this is ! LT
10330 unless this is an scc insn. */
10331 return scc_p ? base_bit + 3 : base_bit;
10333 case LE: case LEU:
10334 return scc_p ? base_bit + 3 : base_bit + 1;
10336 default:
10337 gcc_unreachable ();
10341 /* Return the GOT register. */
10344 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
10346 /* The second flow pass currently (June 1999) can't update
10347 regs_ever_live without disturbing other parts of the compiler, so
10348 update it here to make the prolog/epilogue code happy. */
10349 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
10350 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
10352 current_function_uses_pic_offset_table = 1;
10354 return pic_offset_table_rtx;
10357 /* Function to init struct machine_function.
10358 This will be called, via a pointer variable,
10359 from push_function_context. */
10361 static struct machine_function *
10362 rs6000_init_machine_status (void)
10364 return ggc_alloc_cleared (sizeof (machine_function));
10367 /* These macros test for integers and extract the low-order bits. */
10368 #define INT_P(X) \
10369 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
10370 && GET_MODE (X) == VOIDmode)
10372 #define INT_LOWPART(X) \
10373 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
10376 extract_MB (rtx op)
10378 int i;
10379 unsigned long val = INT_LOWPART (op);
10381 /* If the high bit is zero, the value is the first 1 bit we find
10382 from the left. */
10383 if ((val & 0x80000000) == 0)
10385 gcc_assert (val & 0xffffffff);
10387 i = 1;
10388 while (((val <<= 1) & 0x80000000) == 0)
10389 ++i;
10390 return i;
10393 /* If the high bit is set and the low bit is not, or the mask is all
10394 1's, the value is zero. */
10395 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
10396 return 0;
10398 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10399 from the right. */
10400 i = 31;
10401 while (((val >>= 1) & 1) != 0)
10402 --i;
10404 return i;
10408 extract_ME (rtx op)
10410 int i;
10411 unsigned long val = INT_LOWPART (op);
10413 /* If the low bit is zero, the value is the first 1 bit we find from
10414 the right. */
10415 if ((val & 1) == 0)
10417 gcc_assert (val & 0xffffffff);
10419 i = 30;
10420 while (((val >>= 1) & 1) == 0)
10421 --i;
10423 return i;
10426 /* If the low bit is set and the high bit is not, or the mask is all
10427 1's, the value is 31. */
10428 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
10429 return 31;
10431 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10432 from the left. */
10433 i = 0;
10434 while (((val <<= 1) & 0x80000000) != 0)
10435 ++i;
10437 return i;
10440 /* Locate some local-dynamic symbol still in use by this function
10441 so that we can print its name in some tls_ld pattern. */
10443 static const char *
10444 rs6000_get_some_local_dynamic_name (void)
10446 rtx insn;
10448 if (cfun->machine->some_ld_name)
10449 return cfun->machine->some_ld_name;
10451 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
10452 if (INSN_P (insn)
10453 && for_each_rtx (&PATTERN (insn),
10454 rs6000_get_some_local_dynamic_name_1, 0))
10455 return cfun->machine->some_ld_name;
10457 gcc_unreachable ();
10460 /* Helper function for rs6000_get_some_local_dynamic_name. */
10462 static int
10463 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
10465 rtx x = *px;
10467 if (GET_CODE (x) == SYMBOL_REF)
10469 const char *str = XSTR (x, 0);
10470 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
10472 cfun->machine->some_ld_name = str;
10473 return 1;
10477 return 0;
10480 /* Write out a function code label. */
10482 void
10483 rs6000_output_function_entry (FILE *file, const char *fname)
10485 if (fname[0] != '.')
10487 switch (DEFAULT_ABI)
10489 default:
10490 gcc_unreachable ();
10492 case ABI_AIX:
10493 if (DOT_SYMBOLS)
10494 putc ('.', file);
10495 else
10496 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
10497 break;
10499 case ABI_V4:
10500 case ABI_DARWIN:
10501 break;
10504 if (TARGET_AIX)
10505 RS6000_OUTPUT_BASENAME (file, fname);
10506 else
10507 assemble_name (file, fname);
10510 /* Print an operand. Recognize special options, documented below. */
10512 #if TARGET_ELF
10513 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
10514 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
10515 #else
10516 #define SMALL_DATA_RELOC "sda21"
10517 #define SMALL_DATA_REG 0
10518 #endif
10520 void
10521 print_operand (FILE *file, rtx x, int code)
10523 int i;
10524 HOST_WIDE_INT val;
10525 unsigned HOST_WIDE_INT uval;
10527 switch (code)
10529 case '.':
10530 /* Write out an instruction after the call which may be replaced
10531 with glue code by the loader. This depends on the AIX version. */
10532 asm_fprintf (file, RS6000_CALL_GLUE);
10533 return;
10535 /* %a is output_address. */
10537 case 'A':
10538 /* If X is a constant integer whose low-order 5 bits are zero,
10539 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10540 in the AIX assembler where "sri" with a zero shift count
10541 writes a trash instruction. */
10542 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
10543 putc ('l', file);
10544 else
10545 putc ('r', file);
10546 return;
10548 case 'b':
10549 /* If constant, low-order 16 bits of constant, unsigned.
10550 Otherwise, write normally. */
10551 if (INT_P (x))
10552 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
10553 else
10554 print_operand (file, x, 0);
10555 return;
10557 case 'B':
10558 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10559 for 64-bit mask direction. */
10560 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
10561 return;
10563 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10564 output_operand. */
10566 case 'c':
10567 /* X is a CR register. Print the number of the GT bit of the CR. */
10568 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10569 output_operand_lossage ("invalid %%E value");
10570 else
10571 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
10572 return;
10574 case 'D':
10575 /* Like 'J' but get to the GT bit only. */
10576 gcc_assert (GET_CODE (x) == REG);
10578 /* Bit 1 is GT bit. */
10579 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
10581 /* Add one for shift count in rlinm for scc. */
10582 fprintf (file, "%d", i + 1);
10583 return;
10585 case 'E':
10586 /* X is a CR register. Print the number of the EQ bit of the CR */
10587 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10588 output_operand_lossage ("invalid %%E value");
10589 else
10590 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
10591 return;
10593 case 'f':
10594 /* X is a CR register. Print the shift count needed to move it
10595 to the high-order four bits. */
10596 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10597 output_operand_lossage ("invalid %%f value");
10598 else
10599 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
10600 return;
10602 case 'F':
10603 /* Similar, but print the count for the rotate in the opposite
10604 direction. */
10605 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10606 output_operand_lossage ("invalid %%F value");
10607 else
10608 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
10609 return;
10611 case 'G':
10612 /* X is a constant integer. If it is negative, print "m",
10613 otherwise print "z". This is to make an aze or ame insn. */
10614 if (GET_CODE (x) != CONST_INT)
10615 output_operand_lossage ("invalid %%G value");
10616 else if (INTVAL (x) >= 0)
10617 putc ('z', file);
10618 else
10619 putc ('m', file);
10620 return;
10622 case 'h':
10623 /* If constant, output low-order five bits. Otherwise, write
10624 normally. */
10625 if (INT_P (x))
10626 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
10627 else
10628 print_operand (file, x, 0);
10629 return;
10631 case 'H':
10632 /* If constant, output low-order six bits. Otherwise, write
10633 normally. */
10634 if (INT_P (x))
10635 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
10636 else
10637 print_operand (file, x, 0);
10638 return;
10640 case 'I':
10641 /* Print `i' if this is a constant, else nothing. */
10642 if (INT_P (x))
10643 putc ('i', file);
10644 return;
10646 case 'j':
10647 /* Write the bit number in CCR for jump. */
10648 i = ccr_bit (x, 0);
10649 if (i == -1)
10650 output_operand_lossage ("invalid %%j code");
10651 else
10652 fprintf (file, "%d", i);
10653 return;
10655 case 'J':
10656 /* Similar, but add one for shift count in rlinm for scc and pass
10657 scc flag to `ccr_bit'. */
10658 i = ccr_bit (x, 1);
10659 if (i == -1)
10660 output_operand_lossage ("invalid %%J code");
10661 else
10662 /* If we want bit 31, write a shift count of zero, not 32. */
10663 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10664 return;
10666 case 'k':
10667 /* X must be a constant. Write the 1's complement of the
10668 constant. */
10669 if (! INT_P (x))
10670 output_operand_lossage ("invalid %%k value");
10671 else
10672 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
10673 return;
10675 case 'K':
10676 /* X must be a symbolic constant on ELF. Write an
10677 expression suitable for an 'addi' that adds in the low 16
10678 bits of the MEM. */
10679 if (GET_CODE (x) != CONST)
10681 print_operand_address (file, x);
10682 fputs ("@l", file);
10684 else
10686 if (GET_CODE (XEXP (x, 0)) != PLUS
10687 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
10688 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
10689 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
10690 output_operand_lossage ("invalid %%K value");
10691 print_operand_address (file, XEXP (XEXP (x, 0), 0));
10692 fputs ("@l", file);
10693 /* For GNU as, there must be a non-alphanumeric character
10694 between 'l' and the number. The '-' is added by
10695 print_operand() already. */
10696 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
10697 fputs ("+", file);
10698 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
10700 return;
10702 /* %l is output_asm_label. */
10704 case 'L':
10705 /* Write second word of DImode or DFmode reference. Works on register
10706 or non-indexed memory only. */
10707 if (GET_CODE (x) == REG)
10708 fputs (reg_names[REGNO (x) + 1], file);
10709 else if (GET_CODE (x) == MEM)
10711 /* Handle possible auto-increment. Since it is pre-increment and
10712 we have already done it, we can just use an offset of word. */
10713 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10714 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10715 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
10716 UNITS_PER_WORD));
10717 else
10718 output_address (XEXP (adjust_address_nv (x, SImode,
10719 UNITS_PER_WORD),
10720 0));
10722 if (small_data_operand (x, GET_MODE (x)))
10723 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10724 reg_names[SMALL_DATA_REG]);
10726 return;
10728 case 'm':
10729 /* MB value for a mask operand. */
10730 if (! mask_operand (x, SImode))
10731 output_operand_lossage ("invalid %%m value");
10733 fprintf (file, "%d", extract_MB (x));
10734 return;
10736 case 'M':
10737 /* ME value for a mask operand. */
10738 if (! mask_operand (x, SImode))
10739 output_operand_lossage ("invalid %%M value");
10741 fprintf (file, "%d", extract_ME (x));
10742 return;
10744 /* %n outputs the negative of its operand. */
10746 case 'N':
10747 /* Write the number of elements in the vector times 4. */
10748 if (GET_CODE (x) != PARALLEL)
10749 output_operand_lossage ("invalid %%N value");
10750 else
10751 fprintf (file, "%d", XVECLEN (x, 0) * 4);
10752 return;
10754 case 'O':
10755 /* Similar, but subtract 1 first. */
10756 if (GET_CODE (x) != PARALLEL)
10757 output_operand_lossage ("invalid %%O value");
10758 else
10759 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
10760 return;
10762 case 'p':
10763 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10764 if (! INT_P (x)
10765 || INT_LOWPART (x) < 0
10766 || (i = exact_log2 (INT_LOWPART (x))) < 0)
10767 output_operand_lossage ("invalid %%p value");
10768 else
10769 fprintf (file, "%d", i);
10770 return;
10772 case 'P':
10773 /* The operand must be an indirect memory reference. The result
10774 is the register name. */
10775 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
10776 || REGNO (XEXP (x, 0)) >= 32)
10777 output_operand_lossage ("invalid %%P value");
10778 else
10779 fputs (reg_names[REGNO (XEXP (x, 0))], file);
10780 return;
10782 case 'q':
10783 /* This outputs the logical code corresponding to a boolean
10784 expression. The expression may have one or both operands
10785 negated (if one, only the first one). For condition register
10786 logical operations, it will also treat the negated
10787 CR codes as NOTs, but not handle NOTs of them. */
10789 const char *const *t = 0;
10790 const char *s;
10791 enum rtx_code code = GET_CODE (x);
10792 static const char * const tbl[3][3] = {
10793 { "and", "andc", "nor" },
10794 { "or", "orc", "nand" },
10795 { "xor", "eqv", "xor" } };
10797 if (code == AND)
10798 t = tbl[0];
10799 else if (code == IOR)
10800 t = tbl[1];
10801 else if (code == XOR)
10802 t = tbl[2];
10803 else
10804 output_operand_lossage ("invalid %%q value");
10806 if (GET_CODE (XEXP (x, 0)) != NOT)
10807 s = t[0];
10808 else
10810 if (GET_CODE (XEXP (x, 1)) == NOT)
10811 s = t[2];
10812 else
10813 s = t[1];
10816 fputs (s, file);
10818 return;
10820 case 'Q':
10821 if (TARGET_MFCRF)
10822 fputc (',', file);
10823 /* FALLTHRU */
10824 else
10825 return;
10827 case 'R':
10828 /* X is a CR register. Print the mask for `mtcrf'. */
10829 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10830 output_operand_lossage ("invalid %%R value");
10831 else
10832 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
10833 return;
10835 case 's':
10836 /* Low 5 bits of 32 - value */
10837 if (! INT_P (x))
10838 output_operand_lossage ("invalid %%s value");
10839 else
10840 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
10841 return;
10843 case 'S':
10844 /* PowerPC64 mask position. All 0's is excluded.
10845 CONST_INT 32-bit mask is considered sign-extended so any
10846 transition must occur within the CONST_INT, not on the boundary. */
10847 if (! mask64_operand (x, DImode))
10848 output_operand_lossage ("invalid %%S value");
10850 uval = INT_LOWPART (x);
10852 if (uval & 1) /* Clear Left */
10854 #if HOST_BITS_PER_WIDE_INT > 64
10855 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10856 #endif
10857 i = 64;
10859 else /* Clear Right */
10861 uval = ~uval;
10862 #if HOST_BITS_PER_WIDE_INT > 64
10863 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10864 #endif
10865 i = 63;
10867 while (uval != 0)
10868 --i, uval >>= 1;
10869 gcc_assert (i >= 0);
10870 fprintf (file, "%d", i);
10871 return;
10873 case 't':
10874 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10875 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
10877 /* Bit 3 is OV bit. */
10878 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
10880 /* If we want bit 31, write a shift count of zero, not 32. */
10881 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10882 return;
10884 case 'T':
10885 /* Print the symbolic name of a branch target register. */
10886 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
10887 && REGNO (x) != COUNT_REGISTER_REGNUM))
10888 output_operand_lossage ("invalid %%T value");
10889 else if (REGNO (x) == LINK_REGISTER_REGNUM)
10890 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
10891 else
10892 fputs ("ctr", file);
10893 return;
10895 case 'u':
10896 /* High-order 16 bits of constant for use in unsigned operand. */
10897 if (! INT_P (x))
10898 output_operand_lossage ("invalid %%u value");
10899 else
10900 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10901 (INT_LOWPART (x) >> 16) & 0xffff);
10902 return;
10904 case 'v':
10905 /* High-order 16 bits of constant for use in signed operand. */
10906 if (! INT_P (x))
10907 output_operand_lossage ("invalid %%v value");
10908 else
10909 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10910 (INT_LOWPART (x) >> 16) & 0xffff);
10911 return;
10913 case 'U':
10914 /* Print `u' if this has an auto-increment or auto-decrement. */
10915 if (GET_CODE (x) == MEM
10916 && (GET_CODE (XEXP (x, 0)) == PRE_INC
10917 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
10918 putc ('u', file);
10919 return;
10921 case 'V':
10922 /* Print the trap code for this operand. */
10923 switch (GET_CODE (x))
10925 case EQ:
10926 fputs ("eq", file); /* 4 */
10927 break;
10928 case NE:
10929 fputs ("ne", file); /* 24 */
10930 break;
10931 case LT:
10932 fputs ("lt", file); /* 16 */
10933 break;
10934 case LE:
10935 fputs ("le", file); /* 20 */
10936 break;
10937 case GT:
10938 fputs ("gt", file); /* 8 */
10939 break;
10940 case GE:
10941 fputs ("ge", file); /* 12 */
10942 break;
10943 case LTU:
10944 fputs ("llt", file); /* 2 */
10945 break;
10946 case LEU:
10947 fputs ("lle", file); /* 6 */
10948 break;
10949 case GTU:
10950 fputs ("lgt", file); /* 1 */
10951 break;
10952 case GEU:
10953 fputs ("lge", file); /* 5 */
10954 break;
10955 default:
10956 gcc_unreachable ();
10958 break;
10960 case 'w':
10961 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10962 normally. */
10963 if (INT_P (x))
10964 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
10965 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
10966 else
10967 print_operand (file, x, 0);
10968 return;
10970 case 'W':
10971 /* MB value for a PowerPC64 rldic operand. */
10972 val = (GET_CODE (x) == CONST_INT
10973 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
10975 if (val < 0)
10976 i = -1;
10977 else
10978 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
10979 if ((val <<= 1) < 0)
10980 break;
10982 #if HOST_BITS_PER_WIDE_INT == 32
10983 if (GET_CODE (x) == CONST_INT && i >= 0)
10984 i += 32; /* zero-extend high-part was all 0's */
10985 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
10987 val = CONST_DOUBLE_LOW (x);
10989 gcc_assert (val);
10990 if (val < 0)
10991 --i;
10992 else
10993 for ( ; i < 64; i++)
10994 if ((val <<= 1) < 0)
10995 break;
10997 #endif
10999 fprintf (file, "%d", i + 1);
11000 return;
11002 case 'X':
11003 if (GET_CODE (x) == MEM
11004 && legitimate_indexed_address_p (XEXP (x, 0), 0))
11005 putc ('x', file);
11006 return;
11008 case 'Y':
11009 /* Like 'L', for third word of TImode */
11010 if (GET_CODE (x) == REG)
11011 fputs (reg_names[REGNO (x) + 2], file);
11012 else if (GET_CODE (x) == MEM)
11014 if (GET_CODE (XEXP (x, 0)) == PRE_INC
11015 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
11016 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
11017 else
11018 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
11019 if (small_data_operand (x, GET_MODE (x)))
11020 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11021 reg_names[SMALL_DATA_REG]);
11023 return;
11025 case 'z':
11026 /* X is a SYMBOL_REF. Write out the name preceded by a
11027 period and without any trailing data in brackets. Used for function
11028 names. If we are configured for System V (or the embedded ABI) on
11029 the PowerPC, do not emit the period, since those systems do not use
11030 TOCs and the like. */
11031 gcc_assert (GET_CODE (x) == SYMBOL_REF);
11033 /* Mark the decl as referenced so that cgraph will output the
11034 function. */
11035 if (SYMBOL_REF_DECL (x))
11036 mark_decl_referenced (SYMBOL_REF_DECL (x));
11038 /* For macho, check to see if we need a stub. */
11039 if (TARGET_MACHO)
11041 const char *name = XSTR (x, 0);
11042 #if TARGET_MACHO
11043 if (MACHOPIC_INDIRECT
11044 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
11045 name = machopic_indirection_name (x, /*stub_p=*/true);
11046 #endif
11047 assemble_name (file, name);
11049 else if (!DOT_SYMBOLS)
11050 assemble_name (file, XSTR (x, 0));
11051 else
11052 rs6000_output_function_entry (file, XSTR (x, 0));
11053 return;
11055 case 'Z':
11056 /* Like 'L', for last word of TImode. */
11057 if (GET_CODE (x) == REG)
11058 fputs (reg_names[REGNO (x) + 3], file);
11059 else if (GET_CODE (x) == MEM)
11061 if (GET_CODE (XEXP (x, 0)) == PRE_INC
11062 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
11063 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
11064 else
11065 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
11066 if (small_data_operand (x, GET_MODE (x)))
11067 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11068 reg_names[SMALL_DATA_REG]);
11070 return;
11072 /* Print AltiVec or SPE memory operand. */
11073 case 'y':
11075 rtx tmp;
11077 gcc_assert (GET_CODE (x) == MEM);
11079 tmp = XEXP (x, 0);
11081 /* Ugly hack because %y is overloaded. */
11082 if ((TARGET_SPE || TARGET_E500_DOUBLE)
11083 && (GET_MODE_SIZE (GET_MODE (x)) == 8
11084 || GET_MODE (x) == TFmode
11085 || GET_MODE (x) == TImode))
11087 /* Handle [reg]. */
11088 if (GET_CODE (tmp) == REG)
11090 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
11091 break;
11093 /* Handle [reg+UIMM]. */
11094 else if (GET_CODE (tmp) == PLUS &&
11095 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
11097 int x;
11099 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
11101 x = INTVAL (XEXP (tmp, 1));
11102 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
11103 break;
11106 /* Fall through. Must be [reg+reg]. */
11108 if (TARGET_ALTIVEC
11109 && GET_CODE (tmp) == AND
11110 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
11111 && INTVAL (XEXP (tmp, 1)) == -16)
11112 tmp = XEXP (tmp, 0);
11113 if (GET_CODE (tmp) == REG)
11114 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
11115 else
11117 gcc_assert (GET_CODE (tmp) == PLUS
11118 && REG_P (XEXP (tmp, 0))
11119 && REG_P (XEXP (tmp, 1)));
11121 if (REGNO (XEXP (tmp, 0)) == 0)
11122 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
11123 reg_names[ REGNO (XEXP (tmp, 0)) ]);
11124 else
11125 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
11126 reg_names[ REGNO (XEXP (tmp, 1)) ]);
11128 break;
11131 case 0:
11132 if (GET_CODE (x) == REG)
11133 fprintf (file, "%s", reg_names[REGNO (x)]);
11134 else if (GET_CODE (x) == MEM)
11136 /* We need to handle PRE_INC and PRE_DEC here, since we need to
11137 know the width from the mode. */
11138 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
11139 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
11140 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
11141 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
11142 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
11143 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
11144 else
11145 output_address (XEXP (x, 0));
11147 else
11148 output_addr_const (file, x);
11149 return;
11151 case '&':
11152 assemble_name (file, rs6000_get_some_local_dynamic_name ());
11153 return;
11155 default:
11156 output_operand_lossage ("invalid %%xn code");
11160 /* Print the address of an operand. */
11162 void
11163 print_operand_address (FILE *file, rtx x)
11165 if (GET_CODE (x) == REG)
11166 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
11167 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
11168 || GET_CODE (x) == LABEL_REF)
11170 output_addr_const (file, x);
11171 if (small_data_operand (x, GET_MODE (x)))
11172 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11173 reg_names[SMALL_DATA_REG]);
11174 else
11175 gcc_assert (!TARGET_TOC);
11177 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
11179 gcc_assert (REG_P (XEXP (x, 0)));
11180 if (REGNO (XEXP (x, 0)) == 0)
11181 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
11182 reg_names[ REGNO (XEXP (x, 0)) ]);
11183 else
11184 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
11185 reg_names[ REGNO (XEXP (x, 1)) ]);
11187 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
11188 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
11189 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
11190 #if TARGET_ELF
11191 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
11192 && CONSTANT_P (XEXP (x, 1)))
11194 output_addr_const (file, XEXP (x, 1));
11195 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
11197 #endif
11198 #if TARGET_MACHO
11199 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
11200 && CONSTANT_P (XEXP (x, 1)))
11202 fprintf (file, "lo16(");
11203 output_addr_const (file, XEXP (x, 1));
11204 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
11206 #endif
11207 else if (legitimate_constant_pool_address_p (x))
11209 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
11211 rtx contains_minus = XEXP (x, 1);
11212 rtx minus, symref;
11213 const char *name;
11215 /* Find the (minus (sym) (toc)) buried in X, and temporarily
11216 turn it into (sym) for output_addr_const. */
11217 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
11218 contains_minus = XEXP (contains_minus, 0);
11220 minus = XEXP (contains_minus, 0);
11221 symref = XEXP (minus, 0);
11222 XEXP (contains_minus, 0) = symref;
11223 if (TARGET_ELF)
11225 char *newname;
11227 name = XSTR (symref, 0);
11228 newname = alloca (strlen (name) + sizeof ("@toc"));
11229 strcpy (newname, name);
11230 strcat (newname, "@toc");
11231 XSTR (symref, 0) = newname;
11233 output_addr_const (file, XEXP (x, 1));
11234 if (TARGET_ELF)
11235 XSTR (symref, 0) = name;
11236 XEXP (contains_minus, 0) = minus;
11238 else
11239 output_addr_const (file, XEXP (x, 1));
11241 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
11243 else
11244 gcc_unreachable ();
11247 /* Target hook for assembling integer objects. The PowerPC version has
11248 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
11249 is defined. It also needs to handle DI-mode objects on 64-bit
11250 targets. */
11252 static bool
11253 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
11255 #ifdef RELOCATABLE_NEEDS_FIXUP
11256 /* Special handling for SI values. */
11257 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
11259 static int recurse = 0;
11261 /* For -mrelocatable, we mark all addresses that need to be fixed up
11262 in the .fixup section. */
11263 if (TARGET_RELOCATABLE
11264 && in_section != toc_section
11265 && in_section != text_section
11266 && !unlikely_text_section_p (in_section)
11267 && !recurse
11268 && GET_CODE (x) != CONST_INT
11269 && GET_CODE (x) != CONST_DOUBLE
11270 && CONSTANT_P (x))
11272 char buf[256];
11274 recurse = 1;
11275 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
11276 fixuplabelno++;
11277 ASM_OUTPUT_LABEL (asm_out_file, buf);
11278 fprintf (asm_out_file, "\t.long\t(");
11279 output_addr_const (asm_out_file, x);
11280 fprintf (asm_out_file, ")@fixup\n");
11281 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
11282 ASM_OUTPUT_ALIGN (asm_out_file, 2);
11283 fprintf (asm_out_file, "\t.long\t");
11284 assemble_name (asm_out_file, buf);
11285 fprintf (asm_out_file, "\n\t.previous\n");
11286 recurse = 0;
11287 return true;
11289 /* Remove initial .'s to turn a -mcall-aixdesc function
11290 address into the address of the descriptor, not the function
11291 itself. */
11292 else if (GET_CODE (x) == SYMBOL_REF
11293 && XSTR (x, 0)[0] == '.'
11294 && DEFAULT_ABI == ABI_AIX)
11296 const char *name = XSTR (x, 0);
11297 while (*name == '.')
11298 name++;
11300 fprintf (asm_out_file, "\t.long\t%s\n", name);
11301 return true;
11304 #endif /* RELOCATABLE_NEEDS_FIXUP */
11305 return default_assemble_integer (x, size, aligned_p);
11308 #ifdef HAVE_GAS_HIDDEN
11309 /* Emit an assembler directive to set symbol visibility for DECL to
11310 VISIBILITY_TYPE. */
11312 static void
11313 rs6000_assemble_visibility (tree decl, int vis)
11315 /* Functions need to have their entry point symbol visibility set as
11316 well as their descriptor symbol visibility. */
11317 if (DEFAULT_ABI == ABI_AIX
11318 && DOT_SYMBOLS
11319 && TREE_CODE (decl) == FUNCTION_DECL)
11321 static const char * const visibility_types[] = {
11322 NULL, "internal", "hidden", "protected"
11325 const char *name, *type;
11327 name = ((* targetm.strip_name_encoding)
11328 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
11329 type = visibility_types[vis];
11331 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
11332 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
11334 else
11335 default_assemble_visibility (decl, vis);
11337 #endif
11339 enum rtx_code
11340 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
11342 /* Reversal of FP compares takes care -- an ordered compare
11343 becomes an unordered compare and vice versa. */
11344 if (mode == CCFPmode
11345 && (!flag_finite_math_only
11346 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
11347 || code == UNEQ || code == LTGT))
11348 return reverse_condition_maybe_unordered (code);
11349 else
11350 return reverse_condition (code);
11353 /* Generate a compare for CODE. Return a brand-new rtx that
11354 represents the result of the compare. */
11356 static rtx
11357 rs6000_generate_compare (enum rtx_code code)
11359 enum machine_mode comp_mode;
11360 rtx compare_result;
11362 if (rs6000_compare_fp_p)
11363 comp_mode = CCFPmode;
11364 else if (code == GTU || code == LTU
11365 || code == GEU || code == LEU)
11366 comp_mode = CCUNSmode;
11367 else if ((code == EQ || code == NE)
11368 && GET_CODE (rs6000_compare_op0) == SUBREG
11369 && GET_CODE (rs6000_compare_op1) == SUBREG
11370 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
11371 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
11372 /* These are unsigned values, perhaps there will be a later
11373 ordering compare that can be shared with this one.
11374 Unfortunately we cannot detect the signedness of the operands
11375 for non-subregs. */
11376 comp_mode = CCUNSmode;
11377 else
11378 comp_mode = CCmode;
11380 /* First, the compare. */
11381 compare_result = gen_reg_rtx (comp_mode);
11383 /* E500 FP compare instructions on the GPRs. Yuck! */
11384 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
11385 && rs6000_compare_fp_p)
11387 rtx cmp, or_result, compare_result2;
11388 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
11390 if (op_mode == VOIDmode)
11391 op_mode = GET_MODE (rs6000_compare_op1);
11393 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
11394 This explains the following mess. */
11396 switch (code)
11398 case EQ: case UNEQ: case NE: case LTGT:
11399 switch (op_mode)
11401 case SFmode:
11402 cmp = flag_unsafe_math_optimizations
11403 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
11404 rs6000_compare_op1)
11405 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
11406 rs6000_compare_op1);
11407 break;
11409 case DFmode:
11410 cmp = flag_unsafe_math_optimizations
11411 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
11412 rs6000_compare_op1)
11413 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
11414 rs6000_compare_op1);
11415 break;
11417 case TFmode:
11418 cmp = flag_unsafe_math_optimizations
11419 ? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
11420 rs6000_compare_op1)
11421 : gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
11422 rs6000_compare_op1);
11423 break;
11425 default:
11426 gcc_unreachable ();
11428 break;
11430 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
11431 switch (op_mode)
11433 case SFmode:
11434 cmp = flag_unsafe_math_optimizations
11435 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
11436 rs6000_compare_op1)
11437 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
11438 rs6000_compare_op1);
11439 break;
11441 case DFmode:
11442 cmp = flag_unsafe_math_optimizations
11443 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
11444 rs6000_compare_op1)
11445 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
11446 rs6000_compare_op1);
11447 break;
11449 case TFmode:
11450 cmp = flag_unsafe_math_optimizations
11451 ? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
11452 rs6000_compare_op1)
11453 : gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
11454 rs6000_compare_op1);
11455 break;
11457 default:
11458 gcc_unreachable ();
11460 break;
11462 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
11463 switch (op_mode)
11465 case SFmode:
11466 cmp = flag_unsafe_math_optimizations
11467 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
11468 rs6000_compare_op1)
11469 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
11470 rs6000_compare_op1);
11471 break;
11473 case DFmode:
11474 cmp = flag_unsafe_math_optimizations
11475 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
11476 rs6000_compare_op1)
11477 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
11478 rs6000_compare_op1);
11479 break;
11481 case TFmode:
11482 cmp = flag_unsafe_math_optimizations
11483 ? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
11484 rs6000_compare_op1)
11485 : gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
11486 rs6000_compare_op1);
11487 break;
11489 default:
11490 gcc_unreachable ();
11492 break;
11493 default:
11494 gcc_unreachable ();
11497 /* Synthesize LE and GE from LT/GT || EQ. */
11498 if (code == LE || code == GE || code == LEU || code == GEU)
11500 emit_insn (cmp);
11502 switch (code)
11504 case LE: code = LT; break;
11505 case GE: code = GT; break;
11506 case LEU: code = LT; break;
11507 case GEU: code = GT; break;
11508 default: gcc_unreachable ();
11511 compare_result2 = gen_reg_rtx (CCFPmode);
11513 /* Do the EQ. */
11514 switch (op_mode)
11516 case SFmode:
11517 cmp = flag_unsafe_math_optimizations
11518 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
11519 rs6000_compare_op1)
11520 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
11521 rs6000_compare_op1);
11522 break;
11524 case DFmode:
11525 cmp = flag_unsafe_math_optimizations
11526 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
11527 rs6000_compare_op1)
11528 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
11529 rs6000_compare_op1);
11530 break;
11532 case TFmode:
11533 cmp = flag_unsafe_math_optimizations
11534 ? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
11535 rs6000_compare_op1)
11536 : gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
11537 rs6000_compare_op1);
11538 break;
11540 default:
11541 gcc_unreachable ();
11543 emit_insn (cmp);
11545 /* OR them together. */
11546 or_result = gen_reg_rtx (CCFPmode);
11547 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
11548 compare_result2);
11549 compare_result = or_result;
11550 code = EQ;
11552 else
11554 if (code == NE || code == LTGT)
11555 code = NE;
11556 else
11557 code = EQ;
11560 emit_insn (cmp);
11562 else
11564 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11565 CLOBBERs to match cmptf_internal2 pattern. */
11566 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
11567 && GET_MODE (rs6000_compare_op0) == TFmode
11568 && !TARGET_IEEEQUAD
11569 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
11570 emit_insn (gen_rtx_PARALLEL (VOIDmode,
11571 gen_rtvec (9,
11572 gen_rtx_SET (VOIDmode,
11573 compare_result,
11574 gen_rtx_COMPARE (comp_mode,
11575 rs6000_compare_op0,
11576 rs6000_compare_op1)),
11577 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11578 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11579 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11580 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11581 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11582 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11583 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11584 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
11585 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
11586 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
11588 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
11589 comp_mode = CCEQmode;
11590 compare_result = gen_reg_rtx (CCEQmode);
11591 if (TARGET_64BIT)
11592 emit_insn (gen_stack_protect_testdi (compare_result,
11593 rs6000_compare_op0, op1));
11594 else
11595 emit_insn (gen_stack_protect_testsi (compare_result,
11596 rs6000_compare_op0, op1));
11598 else
11599 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
11600 gen_rtx_COMPARE (comp_mode,
11601 rs6000_compare_op0,
11602 rs6000_compare_op1)));
11605 /* Some kinds of FP comparisons need an OR operation;
11606 under flag_finite_math_only we don't bother. */
11607 if (rs6000_compare_fp_p
11608 && !flag_finite_math_only
11609 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
11610 && (code == LE || code == GE
11611 || code == UNEQ || code == LTGT
11612 || code == UNGT || code == UNLT))
11614 enum rtx_code or1, or2;
11615 rtx or1_rtx, or2_rtx, compare2_rtx;
11616 rtx or_result = gen_reg_rtx (CCEQmode);
11618 switch (code)
11620 case LE: or1 = LT; or2 = EQ; break;
11621 case GE: or1 = GT; or2 = EQ; break;
11622 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
11623 case LTGT: or1 = LT; or2 = GT; break;
11624 case UNGT: or1 = UNORDERED; or2 = GT; break;
11625 case UNLT: or1 = UNORDERED; or2 = LT; break;
11626 default: gcc_unreachable ();
11628 validate_condition_mode (or1, comp_mode);
11629 validate_condition_mode (or2, comp_mode);
11630 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
11631 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
11632 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
11633 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
11634 const_true_rtx);
11635 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
11637 compare_result = or_result;
11638 code = EQ;
11641 validate_condition_mode (code, GET_MODE (compare_result));
11643 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
11647 /* Emit the RTL for an sCOND pattern. */
11649 void
11650 rs6000_emit_sCOND (enum rtx_code code, rtx result)
11652 rtx condition_rtx;
11653 enum machine_mode op_mode;
11654 enum rtx_code cond_code;
11656 condition_rtx = rs6000_generate_compare (code);
11657 cond_code = GET_CODE (condition_rtx);
11659 if (rs6000_compare_fp_p
11660 && !TARGET_FPRS && TARGET_HARD_FLOAT)
11662 rtx t;
11664 PUT_MODE (condition_rtx, SImode);
11665 t = XEXP (condition_rtx, 0);
11667 gcc_assert (cond_code == NE || cond_code == EQ);
11669 if (cond_code == NE)
11670 emit_insn (gen_e500_flip_gt_bit (t, t));
11672 emit_insn (gen_move_from_CR_gt_bit (result, t));
11673 return;
11676 if (cond_code == NE
11677 || cond_code == GE || cond_code == LE
11678 || cond_code == GEU || cond_code == LEU
11679 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
11681 rtx not_result = gen_reg_rtx (CCEQmode);
11682 rtx not_op, rev_cond_rtx;
11683 enum machine_mode cc_mode;
11685 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
11687 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
11688 SImode, XEXP (condition_rtx, 0), const0_rtx);
11689 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
11690 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
11691 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
11694 op_mode = GET_MODE (rs6000_compare_op0);
11695 if (op_mode == VOIDmode)
11696 op_mode = GET_MODE (rs6000_compare_op1);
11698 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
11700 PUT_MODE (condition_rtx, DImode);
11701 convert_move (result, condition_rtx, 0);
11703 else
11705 PUT_MODE (condition_rtx, SImode);
11706 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
11710 /* Emit a branch of kind CODE to location LOC. */
11712 void
11713 rs6000_emit_cbranch (enum rtx_code code, rtx loc)
11715 rtx condition_rtx, loc_ref;
11717 condition_rtx = rs6000_generate_compare (code);
11718 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
11719 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
11720 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
11721 loc_ref, pc_rtx)));
11724 /* Return the string to output a conditional branch to LABEL, which is
11725 the operand number of the label, or -1 if the branch is really a
11726 conditional return.
11728 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11729 condition code register and its mode specifies what kind of
11730 comparison we made.
11732 REVERSED is nonzero if we should reverse the sense of the comparison.
11734 INSN is the insn. */
11736 char *
11737 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
11739 static char string[64];
11740 enum rtx_code code = GET_CODE (op);
11741 rtx cc_reg = XEXP (op, 0);
11742 enum machine_mode mode = GET_MODE (cc_reg);
11743 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
11744 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
11745 int really_reversed = reversed ^ need_longbranch;
11746 char *s = string;
11747 const char *ccode;
11748 const char *pred;
11749 rtx note;
11751 validate_condition_mode (code, mode);
11753 /* Work out which way this really branches. We could use
11754 reverse_condition_maybe_unordered here always but this
11755 makes the resulting assembler clearer. */
11756 if (really_reversed)
11758 /* Reversal of FP compares takes care -- an ordered compare
11759 becomes an unordered compare and vice versa. */
11760 if (mode == CCFPmode)
11761 code = reverse_condition_maybe_unordered (code);
11762 else
11763 code = reverse_condition (code);
11766 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
11768 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11769 to the GT bit. */
11770 switch (code)
11772 case EQ:
11773 /* Opposite of GT. */
11774 code = GT;
11775 break;
11777 case NE:
11778 code = UNLE;
11779 break;
11781 default:
11782 gcc_unreachable ();
11786 switch (code)
11788 /* Not all of these are actually distinct opcodes, but
11789 we distinguish them for clarity of the resulting assembler. */
11790 case NE: case LTGT:
11791 ccode = "ne"; break;
11792 case EQ: case UNEQ:
11793 ccode = "eq"; break;
11794 case GE: case GEU:
11795 ccode = "ge"; break;
11796 case GT: case GTU: case UNGT:
11797 ccode = "gt"; break;
11798 case LE: case LEU:
11799 ccode = "le"; break;
11800 case LT: case LTU: case UNLT:
11801 ccode = "lt"; break;
11802 case UNORDERED: ccode = "un"; break;
11803 case ORDERED: ccode = "nu"; break;
11804 case UNGE: ccode = "nl"; break;
11805 case UNLE: ccode = "ng"; break;
11806 default:
11807 gcc_unreachable ();
11810 /* Maybe we have a guess as to how likely the branch is.
11811 The old mnemonics don't have a way to specify this information. */
11812 pred = "";
11813 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
11814 if (note != NULL_RTX)
11816 /* PROB is the difference from 50%. */
11817 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
11819 /* Only hint for highly probable/improbable branches on newer
11820 cpus as static prediction overrides processor dynamic
11821 prediction. For older cpus we may as well always hint, but
11822 assume not taken for branches that are very close to 50% as a
11823 mispredicted taken branch is more expensive than a
11824 mispredicted not-taken branch. */
11825 if (rs6000_always_hint
11826 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
11827 && br_prob_note_reliable_p (note)))
11829 if (abs (prob) > REG_BR_PROB_BASE / 20
11830 && ((prob > 0) ^ need_longbranch))
11831 pred = "+";
11832 else
11833 pred = "-";
11837 if (label == NULL)
11838 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
11839 else
11840 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
11842 /* We need to escape any '%' characters in the reg_names string.
11843 Assume they'd only be the first character.... */
11844 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
11845 *s++ = '%';
11846 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
11848 if (label != NULL)
11850 /* If the branch distance was too far, we may have to use an
11851 unconditional branch to go the distance. */
11852 if (need_longbranch)
11853 s += sprintf (s, ",$+8\n\tb %s", label);
11854 else
11855 s += sprintf (s, ",%s", label);
11858 return string;
11861 /* Return the string to flip the GT bit on a CR. */
11862 char *
11863 output_e500_flip_gt_bit (rtx dst, rtx src)
11865 static char string[64];
11866 int a, b;
11868 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
11869 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
11871 /* GT bit. */
11872 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
11873 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
11875 sprintf (string, "crnot %d,%d", a, b);
11876 return string;
11879 /* Return insn index for the vector compare instruction for given CODE,
11880 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11881 not available. */
11883 static int
11884 get_vec_cmp_insn (enum rtx_code code,
11885 enum machine_mode dest_mode,
11886 enum machine_mode op_mode)
11888 if (!TARGET_ALTIVEC)
11889 return INSN_NOT_AVAILABLE;
11891 switch (code)
11893 case EQ:
11894 if (dest_mode == V16QImode && op_mode == V16QImode)
11895 return UNSPEC_VCMPEQUB;
11896 if (dest_mode == V8HImode && op_mode == V8HImode)
11897 return UNSPEC_VCMPEQUH;
11898 if (dest_mode == V4SImode && op_mode == V4SImode)
11899 return UNSPEC_VCMPEQUW;
11900 if (dest_mode == V4SImode && op_mode == V4SFmode)
11901 return UNSPEC_VCMPEQFP;
11902 break;
11903 case GE:
11904 if (dest_mode == V4SImode && op_mode == V4SFmode)
11905 return UNSPEC_VCMPGEFP;
11906 case GT:
11907 if (dest_mode == V16QImode && op_mode == V16QImode)
11908 return UNSPEC_VCMPGTSB;
11909 if (dest_mode == V8HImode && op_mode == V8HImode)
11910 return UNSPEC_VCMPGTSH;
11911 if (dest_mode == V4SImode && op_mode == V4SImode)
11912 return UNSPEC_VCMPGTSW;
11913 if (dest_mode == V4SImode && op_mode == V4SFmode)
11914 return UNSPEC_VCMPGTFP;
11915 break;
11916 case GTU:
11917 if (dest_mode == V16QImode && op_mode == V16QImode)
11918 return UNSPEC_VCMPGTUB;
11919 if (dest_mode == V8HImode && op_mode == V8HImode)
11920 return UNSPEC_VCMPGTUH;
11921 if (dest_mode == V4SImode && op_mode == V4SImode)
11922 return UNSPEC_VCMPGTUW;
11923 break;
11924 default:
11925 break;
11927 return INSN_NOT_AVAILABLE;
11930 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
11931 DMODE is expected destination mode. This is a recursive function. */
11933 static rtx
11934 rs6000_emit_vector_compare (enum rtx_code rcode,
11935 rtx op0, rtx op1,
11936 enum machine_mode dmode)
11938 int vec_cmp_insn;
11939 rtx mask;
11940 enum machine_mode dest_mode;
11941 enum machine_mode op_mode = GET_MODE (op1);
11943 gcc_assert (TARGET_ALTIVEC);
11944 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
11946 /* Floating point vector compare instructions uses destination V4SImode.
11947 Move destination to appropriate mode later. */
11948 if (dmode == V4SFmode)
11949 dest_mode = V4SImode;
11950 else
11951 dest_mode = dmode;
11953 mask = gen_reg_rtx (dest_mode);
11954 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11956 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
11958 bool swap_operands = false;
11959 bool try_again = false;
11960 switch (rcode)
11962 case LT:
11963 rcode = GT;
11964 swap_operands = true;
11965 try_again = true;
11966 break;
11967 case LTU:
11968 rcode = GTU;
11969 swap_operands = true;
11970 try_again = true;
11971 break;
11972 case NE:
11973 case UNLE:
11974 case UNLT:
11975 case UNGE:
11976 case UNGT:
11977 /* Invert condition and try again.
11978 e.g., A != B becomes ~(A==B). */
11980 enum rtx_code rev_code;
11981 enum insn_code nor_code;
11982 rtx eq_rtx;
11984 rev_code = reverse_condition_maybe_unordered (rcode);
11985 eq_rtx = rs6000_emit_vector_compare (rev_code, op0, op1,
11986 dest_mode);
11988 nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
11989 gcc_assert (nor_code != CODE_FOR_nothing);
11990 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
11992 if (dmode != dest_mode)
11994 rtx temp = gen_reg_rtx (dest_mode);
11995 convert_move (temp, mask, 0);
11996 return temp;
11998 return mask;
12000 break;
12001 case GE:
12002 case GEU:
12003 case LE:
12004 case LEU:
12005 /* Try GT/GTU/LT/LTU OR EQ */
12007 rtx c_rtx, eq_rtx;
12008 enum insn_code ior_code;
12009 enum rtx_code new_code;
12011 switch (rcode)
12013 case GE:
12014 new_code = GT;
12015 break;
12017 case GEU:
12018 new_code = GTU;
12019 break;
12021 case LE:
12022 new_code = LT;
12023 break;
12025 case LEU:
12026 new_code = LTU;
12027 break;
12029 default:
12030 gcc_unreachable ();
12033 c_rtx = rs6000_emit_vector_compare (new_code,
12034 op0, op1, dest_mode);
12035 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
12036 dest_mode);
12038 ior_code = ior_optab->handlers[(int)dest_mode].insn_code;
12039 gcc_assert (ior_code != CODE_FOR_nothing);
12040 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
12041 if (dmode != dest_mode)
12043 rtx temp = gen_reg_rtx (dest_mode);
12044 convert_move (temp, mask, 0);
12045 return temp;
12047 return mask;
12049 break;
12050 default:
12051 gcc_unreachable ();
12054 if (try_again)
12056 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
12057 /* You only get two chances. */
12058 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
12061 if (swap_operands)
12063 rtx tmp;
12064 tmp = op0;
12065 op0 = op1;
12066 op1 = tmp;
12070 emit_insn (gen_rtx_SET (VOIDmode, mask,
12071 gen_rtx_UNSPEC (dest_mode,
12072 gen_rtvec (2, op0, op1),
12073 vec_cmp_insn)));
12074 if (dmode != dest_mode)
12076 rtx temp = gen_reg_rtx (dest_mode);
12077 convert_move (temp, mask, 0);
12078 return temp;
12080 return mask;
12083 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
12084 valid insn doesn exist for given mode. */
12086 static int
12087 get_vsel_insn (enum machine_mode mode)
12089 switch (mode)
12091 case V4SImode:
12092 return UNSPEC_VSEL4SI;
12093 break;
12094 case V4SFmode:
12095 return UNSPEC_VSEL4SF;
12096 break;
12097 case V8HImode:
12098 return UNSPEC_VSEL8HI;
12099 break;
12100 case V16QImode:
12101 return UNSPEC_VSEL16QI;
12102 break;
12103 default:
12104 return INSN_NOT_AVAILABLE;
12105 break;
12107 return INSN_NOT_AVAILABLE;
12110 /* Emit vector select insn where DEST is destination using
12111 operands OP1, OP2 and MASK. */
12113 static void
12114 rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
12116 rtx t, temp;
12117 enum machine_mode dest_mode = GET_MODE (dest);
12118 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
12120 temp = gen_reg_rtx (dest_mode);
12122 /* For each vector element, select op1 when mask is 1 otherwise
12123 select op2. */
12124 t = gen_rtx_SET (VOIDmode, temp,
12125 gen_rtx_UNSPEC (dest_mode,
12126 gen_rtvec (3, op2, op1, mask),
12127 vsel_insn_index));
12128 emit_insn (t);
12129 emit_move_insn (dest, temp);
12130 return;
12133 /* Emit vector conditional expression.
12134 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
12135 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
12138 rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
12139 rtx cond, rtx cc_op0, rtx cc_op1)
12141 enum machine_mode dest_mode = GET_MODE (dest);
12142 enum rtx_code rcode = GET_CODE (cond);
12143 rtx mask;
12145 if (!TARGET_ALTIVEC)
12146 return 0;
12148 /* Get the vector mask for the given relational operations. */
12149 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
12151 rs6000_emit_vector_select (dest, op1, op2, mask);
12153 return 1;
12156 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
12157 operands of the last comparison is nonzero/true, FALSE_COND if it
12158 is zero/false. Return 0 if the hardware has no such operation. */
12161 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
12163 enum rtx_code code = GET_CODE (op);
12164 rtx op0 = rs6000_compare_op0;
12165 rtx op1 = rs6000_compare_op1;
12166 REAL_VALUE_TYPE c1;
12167 enum machine_mode compare_mode = GET_MODE (op0);
12168 enum machine_mode result_mode = GET_MODE (dest);
12169 rtx temp;
12170 bool is_against_zero;
12172 /* These modes should always match. */
12173 if (GET_MODE (op1) != compare_mode
12174 /* In the isel case however, we can use a compare immediate, so
12175 op1 may be a small constant. */
12176 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
12177 return 0;
12178 if (GET_MODE (true_cond) != result_mode)
12179 return 0;
12180 if (GET_MODE (false_cond) != result_mode)
12181 return 0;
12183 /* First, work out if the hardware can do this at all, or
12184 if it's too slow.... */
12185 if (! rs6000_compare_fp_p)
12187 if (TARGET_ISEL)
12188 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
12189 return 0;
12191 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
12192 && SCALAR_FLOAT_MODE_P (compare_mode))
12193 return 0;
12195 is_against_zero = op1 == CONST0_RTX (compare_mode);
12197 /* A floating-point subtract might overflow, underflow, or produce
12198 an inexact result, thus changing the floating-point flags, so it
12199 can't be generated if we care about that. It's safe if one side
12200 of the construct is zero, since then no subtract will be
12201 generated. */
12202 if (SCALAR_FLOAT_MODE_P (compare_mode)
12203 && flag_trapping_math && ! is_against_zero)
12204 return 0;
12206 /* Eliminate half of the comparisons by switching operands, this
12207 makes the remaining code simpler. */
12208 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
12209 || code == LTGT || code == LT || code == UNLE)
12211 code = reverse_condition_maybe_unordered (code);
12212 temp = true_cond;
12213 true_cond = false_cond;
12214 false_cond = temp;
12217 /* UNEQ and LTGT take four instructions for a comparison with zero,
12218 it'll probably be faster to use a branch here too. */
12219 if (code == UNEQ && HONOR_NANS (compare_mode))
12220 return 0;
12222 if (GET_CODE (op1) == CONST_DOUBLE)
12223 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
12225 /* We're going to try to implement comparisons by performing
12226 a subtract, then comparing against zero. Unfortunately,
12227 Inf - Inf is NaN which is not zero, and so if we don't
12228 know that the operand is finite and the comparison
12229 would treat EQ different to UNORDERED, we can't do it. */
12230 if (HONOR_INFINITIES (compare_mode)
12231 && code != GT && code != UNGE
12232 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
12233 /* Constructs of the form (a OP b ? a : b) are safe. */
12234 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
12235 || (! rtx_equal_p (op0, true_cond)
12236 && ! rtx_equal_p (op1, true_cond))))
12237 return 0;
12239 /* At this point we know we can use fsel. */
12241 /* Reduce the comparison to a comparison against zero. */
12242 if (! is_against_zero)
12244 temp = gen_reg_rtx (compare_mode);
12245 emit_insn (gen_rtx_SET (VOIDmode, temp,
12246 gen_rtx_MINUS (compare_mode, op0, op1)));
12247 op0 = temp;
12248 op1 = CONST0_RTX (compare_mode);
12251 /* If we don't care about NaNs we can reduce some of the comparisons
12252 down to faster ones. */
12253 if (! HONOR_NANS (compare_mode))
12254 switch (code)
12256 case GT:
12257 code = LE;
12258 temp = true_cond;
12259 true_cond = false_cond;
12260 false_cond = temp;
12261 break;
12262 case UNGE:
12263 code = GE;
12264 break;
12265 case UNEQ:
12266 code = EQ;
12267 break;
12268 default:
12269 break;
12272 /* Now, reduce everything down to a GE. */
12273 switch (code)
12275 case GE:
12276 break;
12278 case LE:
12279 temp = gen_reg_rtx (compare_mode);
12280 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12281 op0 = temp;
12282 break;
12284 case ORDERED:
12285 temp = gen_reg_rtx (compare_mode);
12286 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
12287 op0 = temp;
12288 break;
12290 case EQ:
12291 temp = gen_reg_rtx (compare_mode);
12292 emit_insn (gen_rtx_SET (VOIDmode, temp,
12293 gen_rtx_NEG (compare_mode,
12294 gen_rtx_ABS (compare_mode, op0))));
12295 op0 = temp;
12296 break;
12298 case UNGE:
12299 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
12300 temp = gen_reg_rtx (result_mode);
12301 emit_insn (gen_rtx_SET (VOIDmode, temp,
12302 gen_rtx_IF_THEN_ELSE (result_mode,
12303 gen_rtx_GE (VOIDmode,
12304 op0, op1),
12305 true_cond, false_cond)));
12306 false_cond = true_cond;
12307 true_cond = temp;
12309 temp = gen_reg_rtx (compare_mode);
12310 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12311 op0 = temp;
12312 break;
12314 case GT:
12315 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
12316 temp = gen_reg_rtx (result_mode);
12317 emit_insn (gen_rtx_SET (VOIDmode, temp,
12318 gen_rtx_IF_THEN_ELSE (result_mode,
12319 gen_rtx_GE (VOIDmode,
12320 op0, op1),
12321 true_cond, false_cond)));
12322 true_cond = false_cond;
12323 false_cond = temp;
12325 temp = gen_reg_rtx (compare_mode);
12326 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
12327 op0 = temp;
12328 break;
12330 default:
12331 gcc_unreachable ();
12334 emit_insn (gen_rtx_SET (VOIDmode, dest,
12335 gen_rtx_IF_THEN_ELSE (result_mode,
12336 gen_rtx_GE (VOIDmode,
12337 op0, op1),
12338 true_cond, false_cond)));
12339 return 1;
12342 /* Same as above, but for ints (isel). */
12344 static int
12345 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
12347 rtx condition_rtx, cr;
12349 /* All isel implementations thus far are 32-bits. */
12350 if (GET_MODE (rs6000_compare_op0) != SImode)
12351 return 0;
12353 /* We still have to do the compare, because isel doesn't do a
12354 compare, it just looks at the CRx bits set by a previous compare
12355 instruction. */
12356 condition_rtx = rs6000_generate_compare (GET_CODE (op));
12357 cr = XEXP (condition_rtx, 0);
12359 if (GET_MODE (cr) == CCmode)
12360 emit_insn (gen_isel_signed (dest, condition_rtx,
12361 true_cond, false_cond, cr));
12362 else
12363 emit_insn (gen_isel_unsigned (dest, condition_rtx,
12364 true_cond, false_cond, cr));
12366 return 1;
12369 const char *
12370 output_isel (rtx *operands)
12372 enum rtx_code code;
12374 code = GET_CODE (operands[1]);
12375 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
12377 PUT_CODE (operands[1], reverse_condition (code));
12378 return "isel %0,%3,%2,%j1";
12380 else
12381 return "isel %0,%2,%3,%j1";
12384 void
12385 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
12387 enum machine_mode mode = GET_MODE (op0);
12388 enum rtx_code c;
12389 rtx target;
12391 if (code == SMAX || code == SMIN)
12392 c = GE;
12393 else
12394 c = GEU;
12396 if (code == SMAX || code == UMAX)
12397 target = emit_conditional_move (dest, c, op0, op1, mode,
12398 op0, op1, mode, 0);
12399 else
12400 target = emit_conditional_move (dest, c, op0, op1, mode,
12401 op1, op0, mode, 0);
12402 gcc_assert (target);
12403 if (target != dest)
12404 emit_move_insn (dest, target);
12407 /* Emit instructions to perform a load-reserved/store-conditional operation.
12408 The operation performed is an atomic
12409 (set M (CODE:MODE M OP))
12410 If not NULL, BEFORE is atomically set to M before the operation, and
12411 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
12412 If SYNC_P then a memory barrier is emitted before the operation.
12413 Either OP or M may be wrapped in a NOT operation. */
12415 void
12416 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
12417 rtx m, rtx op, rtx before_param, rtx after_param,
12418 bool sync_p)
12420 enum machine_mode used_mode;
12421 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
12422 rtx used_m;
12423 rtvec vec;
12424 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12425 rtx shift = NULL_RTX;
12427 if (sync_p)
12428 emit_insn (gen_memory_barrier ());
12430 if (GET_CODE (m) == NOT)
12431 used_m = XEXP (m, 0);
12432 else
12433 used_m = m;
12435 /* If this is smaller than SImode, we'll have to use SImode with
12436 adjustments. */
12437 if (mode == QImode || mode == HImode)
12439 rtx newop, oldop;
12441 if (MEM_ALIGN (used_m) >= 32)
12443 int ishift = 0;
12444 if (BYTES_BIG_ENDIAN)
12445 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
12447 shift = GEN_INT (ishift);
12449 else
12451 rtx addrSI, aligned_addr;
12452 int shift_mask = mode == QImode ? 0x18 : 0x10;
12454 addrSI = force_reg (SImode, gen_lowpart_common (SImode,
12455 XEXP (used_m, 0)));
12456 shift = gen_reg_rtx (SImode);
12458 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
12459 GEN_INT (shift_mask)));
12460 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
12462 aligned_addr = expand_binop (Pmode, and_optab,
12463 XEXP (used_m, 0),
12464 GEN_INT (-4), NULL_RTX,
12465 1, OPTAB_LIB_WIDEN);
12466 used_m = change_address (used_m, SImode, aligned_addr);
12467 set_mem_align (used_m, 32);
12468 /* It's safe to keep the old alias set of USED_M, because
12469 the operation is atomic and only affects the original
12470 USED_M. */
12471 if (GET_CODE (m) == NOT)
12472 m = gen_rtx_NOT (SImode, used_m);
12473 else
12474 m = used_m;
12477 if (GET_CODE (op) == NOT)
12479 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
12480 oldop = gen_rtx_NOT (SImode, oldop);
12482 else
12483 oldop = lowpart_subreg (SImode, op, mode);
12485 switch (code)
12487 case IOR:
12488 case XOR:
12489 newop = expand_binop (SImode, and_optab,
12490 oldop, GEN_INT (imask), NULL_RTX,
12491 1, OPTAB_LIB_WIDEN);
12492 emit_insn (gen_ashlsi3 (newop, newop, shift));
12493 break;
12495 case AND:
12496 newop = expand_binop (SImode, ior_optab,
12497 oldop, GEN_INT (~imask), NULL_RTX,
12498 1, OPTAB_LIB_WIDEN);
12499 emit_insn (gen_rotlsi3 (newop, newop, shift));
12500 break;
12502 case PLUS:
12503 case MINUS:
12505 rtx mask;
12507 newop = expand_binop (SImode, and_optab,
12508 oldop, GEN_INT (imask), NULL_RTX,
12509 1, OPTAB_LIB_WIDEN);
12510 emit_insn (gen_ashlsi3 (newop, newop, shift));
12512 mask = gen_reg_rtx (SImode);
12513 emit_move_insn (mask, GEN_INT (imask));
12514 emit_insn (gen_ashlsi3 (mask, mask, shift));
12516 if (code == PLUS)
12517 newop = gen_rtx_PLUS (SImode, m, newop);
12518 else
12519 newop = gen_rtx_MINUS (SImode, m, newop);
12520 newop = gen_rtx_AND (SImode, newop, mask);
12521 newop = gen_rtx_IOR (SImode, newop,
12522 gen_rtx_AND (SImode,
12523 gen_rtx_NOT (SImode, mask),
12524 m));
12525 break;
12528 default:
12529 gcc_unreachable ();
12532 if (GET_CODE (m) == NOT)
12534 rtx mask, xorm;
12536 mask = gen_reg_rtx (SImode);
12537 emit_move_insn (mask, GEN_INT (imask));
12538 emit_insn (gen_ashlsi3 (mask, mask, shift));
12540 xorm = gen_rtx_XOR (SImode, used_m, mask);
12541 /* Depending on the value of 'op', the XOR or the operation might
12542 be able to be simplified away. */
12543 newop = simplify_gen_binary (code, SImode, xorm, newop);
12545 op = newop;
12546 used_mode = SImode;
12547 before = gen_reg_rtx (used_mode);
12548 after = gen_reg_rtx (used_mode);
12550 else
12552 used_mode = mode;
12553 before = before_param;
12554 after = after_param;
12556 if (before == NULL_RTX)
12557 before = gen_reg_rtx (used_mode);
12558 if (after == NULL_RTX)
12559 after = gen_reg_rtx (used_mode);
12562 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
12563 && used_mode != mode)
12564 the_op = op; /* Computed above. */
12565 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
12566 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
12567 else
12568 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
12570 set_after = gen_rtx_SET (VOIDmode, after, the_op);
12571 set_before = gen_rtx_SET (VOIDmode, before, used_m);
12572 set_atomic = gen_rtx_SET (VOIDmode, used_m,
12573 gen_rtx_UNSPEC (used_mode,
12574 gen_rtvec (1, the_op),
12575 UNSPEC_SYNC_OP));
12576 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
12578 if ((code == PLUS || code == MINUS) && used_mode != mode)
12579 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
12580 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
12581 else
12582 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
12583 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
12585 /* Shift and mask the return values properly. */
12586 if (used_mode != mode && before_param)
12588 emit_insn (gen_lshrsi3 (before, before, shift));
12589 convert_move (before_param, before, 1);
12592 if (used_mode != mode && after_param)
12594 emit_insn (gen_lshrsi3 (after, after, shift));
12595 convert_move (after_param, after, 1);
12598 /* The previous sequence will end with a branch that's dependent on
12599 the conditional store, so placing an isync will ensure that no
12600 other instructions (especially, no load or store instructions)
12601 can start before the atomic operation completes. */
12602 if (sync_p)
12603 emit_insn (gen_isync ());
12606 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12607 COND is true. Mark the jump as unlikely to be taken. */
12609 static void
12610 emit_unlikely_jump (rtx cond, rtx label)
12612 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
12613 rtx x;
12615 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
12616 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
12617 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
12620 /* A subroutine of the atomic operation splitters. Emit a load-locked
12621 instruction in MODE. */
12623 static void
12624 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
12626 rtx (*fn) (rtx, rtx) = NULL;
12627 if (mode == SImode)
12628 fn = gen_load_locked_si;
12629 else if (mode == DImode)
12630 fn = gen_load_locked_di;
12631 emit_insn (fn (reg, mem));
12634 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12635 instruction in MODE. */
12637 static void
12638 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
12640 rtx (*fn) (rtx, rtx, rtx) = NULL;
12641 if (mode == SImode)
12642 fn = gen_store_conditional_si;
12643 else if (mode == DImode)
12644 fn = gen_store_conditional_di;
12646 /* Emit sync before stwcx. to address PPC405 Erratum. */
12647 if (PPC405_ERRATUM77)
12648 emit_insn (gen_memory_barrier ());
12650 emit_insn (fn (res, mem, val));
12653 /* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
12654 to perform. MEM is the memory on which to operate. VAL is the second
12655 operand of the binary operator. BEFORE and AFTER are optional locations to
12656 return the value of MEM either before of after the operation. SCRATCH is
12657 a scratch register. */
12659 void
12660 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
12661 rtx before, rtx after, rtx scratch)
12663 enum machine_mode mode = GET_MODE (mem);
12664 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12666 emit_insn (gen_memory_barrier ());
12668 label = gen_label_rtx ();
12669 emit_label (label);
12670 label = gen_rtx_LABEL_REF (VOIDmode, label);
12672 if (before == NULL_RTX)
12673 before = scratch;
12674 emit_load_locked (mode, before, mem);
12676 if (code == NOT)
12677 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
12678 else if (code == AND)
12679 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
12680 else
12681 x = gen_rtx_fmt_ee (code, mode, before, val);
12683 if (after != NULL_RTX)
12684 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
12685 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
12687 emit_store_conditional (mode, cond, mem, scratch);
12689 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12690 emit_unlikely_jump (x, label);
12692 emit_insn (gen_isync ());
12695 /* Expand an atomic compare and swap operation. MEM is the memory on which
12696 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12697 value to be stored. SCRATCH is a scratch GPR. */
12699 void
12700 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
12701 rtx scratch)
12703 enum machine_mode mode = GET_MODE (mem);
12704 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12706 emit_insn (gen_memory_barrier ());
12708 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12709 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12710 emit_label (XEXP (label1, 0));
12712 emit_load_locked (mode, retval, mem);
12714 x = gen_rtx_COMPARE (CCmode, retval, oldval);
12715 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12717 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12718 emit_unlikely_jump (x, label2);
12720 emit_move_insn (scratch, newval);
12721 emit_store_conditional (mode, cond, mem, scratch);
12723 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12724 emit_unlikely_jump (x, label1);
12726 emit_insn (gen_isync ());
12727 emit_label (XEXP (label2, 0));
12730 /* Expand an atomic test and set operation. MEM is the memory on which
12731 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12733 void
12734 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
12736 enum machine_mode mode = GET_MODE (mem);
12737 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12739 emit_insn (gen_memory_barrier ());
12741 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12742 emit_label (XEXP (label, 0));
12744 emit_load_locked (mode, retval, mem);
12745 emit_move_insn (scratch, val);
12746 emit_store_conditional (mode, cond, mem, scratch);
12748 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12749 emit_unlikely_jump (x, label);
12751 emit_insn (gen_isync ());
12754 void
12755 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
12757 enum machine_mode mode = GET_MODE (mem);
12758 rtx addrSI, align, wdst, shift, mask;
12759 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
12760 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12762 /* Shift amount for subword relative to aligned word. */
12763 addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0)));
12764 shift = gen_reg_rtx (SImode);
12765 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
12766 GEN_INT (shift_mask)));
12767 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
12769 /* Shift and mask old value into position within word. */
12770 oldval = convert_modes (SImode, mode, oldval, 1);
12771 oldval = expand_binop (SImode, and_optab,
12772 oldval, GEN_INT (imask), NULL_RTX,
12773 1, OPTAB_LIB_WIDEN);
12774 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
12776 /* Shift and mask new value into position within word. */
12777 newval = convert_modes (SImode, mode, newval, 1);
12778 newval = expand_binop (SImode, and_optab,
12779 newval, GEN_INT (imask), NULL_RTX,
12780 1, OPTAB_LIB_WIDEN);
12781 emit_insn (gen_ashlsi3 (newval, newval, shift));
12783 /* Mask for insertion. */
12784 mask = gen_reg_rtx (SImode);
12785 emit_move_insn (mask, GEN_INT (imask));
12786 emit_insn (gen_ashlsi3 (mask, mask, shift));
12788 /* Address of aligned word containing subword. */
12789 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
12790 NULL_RTX, 1, OPTAB_LIB_WIDEN);
12791 mem = change_address (mem, SImode, align);
12792 set_mem_align (mem, 32);
12793 MEM_VOLATILE_P (mem) = 1;
12795 wdst = gen_reg_rtx (SImode);
12796 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
12797 oldval, newval, mem));
12799 emit_move_insn (dst, gen_lowpart (mode, wdst));
12802 void
12803 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
12804 rtx oldval, rtx newval, rtx mem,
12805 rtx scratch)
12807 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12809 emit_insn (gen_memory_barrier ());
12810 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12811 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12812 emit_label (XEXP (label1, 0));
12814 emit_load_locked (SImode, scratch, mem);
12816 /* Mask subword within loaded value for comparison with oldval.
12817 Use UNSPEC_AND to avoid clobber.*/
12818 emit_insn (gen_rtx_SET (SImode, dest,
12819 gen_rtx_UNSPEC (SImode,
12820 gen_rtvec (2, scratch, mask),
12821 UNSPEC_AND)));
12823 x = gen_rtx_COMPARE (CCmode, dest, oldval);
12824 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12826 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12827 emit_unlikely_jump (x, label2);
12829 /* Clear subword within loaded value for insertion of new value. */
12830 emit_insn (gen_rtx_SET (SImode, scratch,
12831 gen_rtx_AND (SImode,
12832 gen_rtx_NOT (SImode, mask), scratch)));
12833 emit_insn (gen_iorsi3 (scratch, scratch, newval));
12834 emit_store_conditional (SImode, cond, mem, scratch);
12836 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12837 emit_unlikely_jump (x, label1);
12839 emit_insn (gen_isync ());
12840 emit_label (XEXP (label2, 0));
12844 /* Emit instructions to move SRC to DST. Called by splitters for
12845 multi-register moves. It will emit at most one instruction for
12846 each register that is accessed; that is, it won't emit li/lis pairs
12847 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12848 register. */
12850 void
12851 rs6000_split_multireg_move (rtx dst, rtx src)
12853 /* The register number of the first register being moved. */
12854 int reg;
12855 /* The mode that is to be moved. */
12856 enum machine_mode mode;
12857 /* The mode that the move is being done in, and its size. */
12858 enum machine_mode reg_mode;
12859 int reg_mode_size;
12860 /* The number of registers that will be moved. */
12861 int nregs;
12863 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
12864 mode = GET_MODE (dst);
12865 nregs = hard_regno_nregs[reg][mode];
12866 if (FP_REGNO_P (reg))
12867 reg_mode = DFmode;
12868 else if (ALTIVEC_REGNO_P (reg))
12869 reg_mode = V16QImode;
12870 else if (TARGET_E500_DOUBLE && mode == TFmode)
12871 reg_mode = DFmode;
12872 else
12873 reg_mode = word_mode;
12874 reg_mode_size = GET_MODE_SIZE (reg_mode);
12876 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
12878 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
12880 /* Move register range backwards, if we might have destructive
12881 overlap. */
12882 int i;
12883 for (i = nregs - 1; i >= 0; i--)
12884 emit_insn (gen_rtx_SET (VOIDmode,
12885 simplify_gen_subreg (reg_mode, dst, mode,
12886 i * reg_mode_size),
12887 simplify_gen_subreg (reg_mode, src, mode,
12888 i * reg_mode_size)));
12890 else
12892 int i;
12893 int j = -1;
12894 bool used_update = false;
12896 if (MEM_P (src) && INT_REGNO_P (reg))
12898 rtx breg;
12900 if (GET_CODE (XEXP (src, 0)) == PRE_INC
12901 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
12903 rtx delta_rtx;
12904 breg = XEXP (XEXP (src, 0), 0);
12905 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
12906 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
12907 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
12908 emit_insn (TARGET_32BIT
12909 ? gen_addsi3 (breg, breg, delta_rtx)
12910 : gen_adddi3 (breg, breg, delta_rtx));
12911 src = replace_equiv_address (src, breg);
12913 else if (! rs6000_offsettable_memref_p (src))
12915 rtx basereg;
12916 basereg = gen_rtx_REG (Pmode, reg);
12917 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
12918 src = replace_equiv_address (src, basereg);
12921 breg = XEXP (src, 0);
12922 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
12923 breg = XEXP (breg, 0);
12925 /* If the base register we are using to address memory is
12926 also a destination reg, then change that register last. */
12927 if (REG_P (breg)
12928 && REGNO (breg) >= REGNO (dst)
12929 && REGNO (breg) < REGNO (dst) + nregs)
12930 j = REGNO (breg) - REGNO (dst);
12933 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
12935 rtx breg;
12937 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
12938 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
12940 rtx delta_rtx;
12941 breg = XEXP (XEXP (dst, 0), 0);
12942 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
12943 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
12944 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
12946 /* We have to update the breg before doing the store.
12947 Use store with update, if available. */
12949 if (TARGET_UPDATE)
12951 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
12952 emit_insn (TARGET_32BIT
12953 ? (TARGET_POWERPC64
12954 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
12955 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
12956 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
12957 used_update = true;
12959 else
12960 emit_insn (TARGET_32BIT
12961 ? gen_addsi3 (breg, breg, delta_rtx)
12962 : gen_adddi3 (breg, breg, delta_rtx));
12963 dst = replace_equiv_address (dst, breg);
12965 else
12966 gcc_assert (rs6000_offsettable_memref_p (dst));
12969 for (i = 0; i < nregs; i++)
12971 /* Calculate index to next subword. */
12972 ++j;
12973 if (j == nregs)
12974 j = 0;
12976 /* If compiler already emitted move of first word by
12977 store with update, no need to do anything. */
12978 if (j == 0 && used_update)
12979 continue;
12981 emit_insn (gen_rtx_SET (VOIDmode,
12982 simplify_gen_subreg (reg_mode, dst, mode,
12983 j * reg_mode_size),
12984 simplify_gen_subreg (reg_mode, src, mode,
12985 j * reg_mode_size)));
12991 /* This page contains routines that are used to determine what the
12992 function prologue and epilogue code will do and write them out. */
12994 /* Return the first fixed-point register that is required to be
12995 saved. 32 if none. */
12998 first_reg_to_save (void)
13000 int first_reg;
13002 /* Find lowest numbered live register. */
13003 for (first_reg = 13; first_reg <= 31; first_reg++)
13004 if (regs_ever_live[first_reg]
13005 && (! call_used_regs[first_reg]
13006 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
13007 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
13008 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
13009 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
13010 break;
13012 #if TARGET_MACHO
13013 if (flag_pic
13014 && current_function_uses_pic_offset_table
13015 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
13016 return RS6000_PIC_OFFSET_TABLE_REGNUM;
13017 #endif
13019 return first_reg;
13022 /* Similar, for FP regs. */
13025 first_fp_reg_to_save (void)
13027 int first_reg;
13029 /* Find lowest numbered live register. */
13030 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
13031 if (regs_ever_live[first_reg])
13032 break;
13034 return first_reg;
13037 /* Similar, for AltiVec regs. */
13039 static int
13040 first_altivec_reg_to_save (void)
13042 int i;
13044 /* Stack frame remains as is unless we are in AltiVec ABI. */
13045 if (! TARGET_ALTIVEC_ABI)
13046 return LAST_ALTIVEC_REGNO + 1;
13048 /* On Darwin, the unwind routines are compiled without
13049 TARGET_ALTIVEC, and use save_world to save/restore the
13050 altivec registers when necessary. */
13051 if (DEFAULT_ABI == ABI_DARWIN && current_function_calls_eh_return
13052 && ! TARGET_ALTIVEC)
13053 return FIRST_ALTIVEC_REGNO + 20;
13055 /* Find lowest numbered live register. */
13056 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
13057 if (regs_ever_live[i])
13058 break;
13060 return i;
13063 /* Return a 32-bit mask of the AltiVec registers we need to set in
13064 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
13065 the 32-bit word is 0. */
13067 static unsigned int
13068 compute_vrsave_mask (void)
13070 unsigned int i, mask = 0;
13072 /* On Darwin, the unwind routines are compiled without
13073 TARGET_ALTIVEC, and use save_world to save/restore the
13074 call-saved altivec registers when necessary. */
13075 if (DEFAULT_ABI == ABI_DARWIN && current_function_calls_eh_return
13076 && ! TARGET_ALTIVEC)
13077 mask |= 0xFFF;
13079 /* First, find out if we use _any_ altivec registers. */
13080 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
13081 if (regs_ever_live[i])
13082 mask |= ALTIVEC_REG_BIT (i);
13084 if (mask == 0)
13085 return mask;
13087 /* Next, remove the argument registers from the set. These must
13088 be in the VRSAVE mask set by the caller, so we don't need to add
13089 them in again. More importantly, the mask we compute here is
13090 used to generate CLOBBERs in the set_vrsave insn, and we do not
13091 wish the argument registers to die. */
13092 for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
13093 mask &= ~ALTIVEC_REG_BIT (i);
13095 /* Similarly, remove the return value from the set. */
13097 bool yes = false;
13098 diddle_return_value (is_altivec_return_reg, &yes);
13099 if (yes)
13100 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
13103 return mask;
13106 /* For a very restricted set of circumstances, we can cut down the
13107 size of prologues/epilogues by calling our own save/restore-the-world
13108 routines. */
13110 static void
13111 compute_save_world_info (rs6000_stack_t *info_ptr)
13113 info_ptr->world_save_p = 1;
13114 info_ptr->world_save_p
13115 = (WORLD_SAVE_P (info_ptr)
13116 && DEFAULT_ABI == ABI_DARWIN
13117 && ! (current_function_calls_setjmp && flag_exceptions)
13118 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
13119 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
13120 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
13121 && info_ptr->cr_save_p);
13123 /* This will not work in conjunction with sibcalls. Make sure there
13124 are none. (This check is expensive, but seldom executed.) */
13125 if (WORLD_SAVE_P (info_ptr))
13127 rtx insn;
13128 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
13129 if ( GET_CODE (insn) == CALL_INSN
13130 && SIBLING_CALL_P (insn))
13132 info_ptr->world_save_p = 0;
13133 break;
13137 if (WORLD_SAVE_P (info_ptr))
13139 /* Even if we're not touching VRsave, make sure there's room on the
13140 stack for it, if it looks like we're calling SAVE_WORLD, which
13141 will attempt to save it. */
13142 info_ptr->vrsave_size = 4;
13144 /* "Save" the VRsave register too if we're saving the world. */
13145 if (info_ptr->vrsave_mask == 0)
13146 info_ptr->vrsave_mask = compute_vrsave_mask ();
13148 /* Because the Darwin register save/restore routines only handle
13149 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
13150 check. */
13151 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
13152 && (info_ptr->first_altivec_reg_save
13153 >= FIRST_SAVED_ALTIVEC_REGNO));
13155 return;
13159 static void
13160 is_altivec_return_reg (rtx reg, void *xyes)
13162 bool *yes = (bool *) xyes;
13163 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
13164 *yes = true;
13168 /* Calculate the stack information for the current function. This is
13169 complicated by having two separate calling sequences, the AIX calling
13170 sequence and the V.4 calling sequence.
13172 AIX (and Darwin/Mac OS X) stack frames look like:
13173 32-bit 64-bit
13174 SP----> +---------------------------------------+
13175 | back chain to caller | 0 0
13176 +---------------------------------------+
13177 | saved CR | 4 8 (8-11)
13178 +---------------------------------------+
13179 | saved LR | 8 16
13180 +---------------------------------------+
13181 | reserved for compilers | 12 24
13182 +---------------------------------------+
13183 | reserved for binders | 16 32
13184 +---------------------------------------+
13185 | saved TOC pointer | 20 40
13186 +---------------------------------------+
13187 | Parameter save area (P) | 24 48
13188 +---------------------------------------+
13189 | Alloca space (A) | 24+P etc.
13190 +---------------------------------------+
13191 | Local variable space (L) | 24+P+A
13192 +---------------------------------------+
13193 | Float/int conversion temporary (X) | 24+P+A+L
13194 +---------------------------------------+
13195 | Save area for AltiVec registers (W) | 24+P+A+L+X
13196 +---------------------------------------+
13197 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
13198 +---------------------------------------+
13199 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
13200 +---------------------------------------+
13201 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
13202 +---------------------------------------+
13203 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
13204 +---------------------------------------+
13205 old SP->| back chain to caller's caller |
13206 +---------------------------------------+
13208 The required alignment for AIX configurations is two words (i.e., 8
13209 or 16 bytes).
13212 V.4 stack frames look like:
13214 SP----> +---------------------------------------+
13215 | back chain to caller | 0
13216 +---------------------------------------+
13217 | caller's saved LR | 4
13218 +---------------------------------------+
13219 | Parameter save area (P) | 8
13220 +---------------------------------------+
13221 | Alloca space (A) | 8+P
13222 +---------------------------------------+
13223 | Varargs save area (V) | 8+P+A
13224 +---------------------------------------+
13225 | Local variable space (L) | 8+P+A+V
13226 +---------------------------------------+
13227 | Float/int conversion temporary (X) | 8+P+A+V+L
13228 +---------------------------------------+
13229 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
13230 +---------------------------------------+
13231 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
13232 +---------------------------------------+
13233 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
13234 +---------------------------------------+
13235 | SPE: area for 64-bit GP registers |
13236 +---------------------------------------+
13237 | SPE alignment padding |
13238 +---------------------------------------+
13239 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
13240 +---------------------------------------+
13241 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
13242 +---------------------------------------+
13243 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
13244 +---------------------------------------+
13245 old SP->| back chain to caller's caller |
13246 +---------------------------------------+
13248 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
13249 given. (But note below and in sysv4.h that we require only 8 and
13250 may round up the size of our stack frame anyways. The historical
13251 reason is early versions of powerpc-linux which didn't properly
13252 align the stack at program startup. A happy side-effect is that
13253 -mno-eabi libraries can be used with -meabi programs.)
13255 The EABI configuration defaults to the V.4 layout. However,
13256 the stack alignment requirements may differ. If -mno-eabi is not
13257 given, the required stack alignment is 8 bytes; if -mno-eabi is
13258 given, the required alignment is 16 bytes. (But see V.4 comment
13259 above.) */
13261 #ifndef ABI_STACK_BOUNDARY
13262 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
13263 #endif
13265 static rs6000_stack_t *
13266 rs6000_stack_info (void)
13268 static rs6000_stack_t info;
13269 rs6000_stack_t *info_ptr = &info;
13270 int reg_size = TARGET_32BIT ? 4 : 8;
13271 int ehrd_size;
13272 int save_align;
13273 HOST_WIDE_INT non_fixed_size;
13275 memset (&info, 0, sizeof (info));
13277 if (TARGET_SPE)
13279 /* Cache value so we don't rescan instruction chain over and over. */
13280 if (cfun->machine->insn_chain_scanned_p == 0)
13281 cfun->machine->insn_chain_scanned_p
13282 = spe_func_has_64bit_regs_p () + 1;
13283 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
13286 /* Select which calling sequence. */
13287 info_ptr->abi = DEFAULT_ABI;
13289 /* Calculate which registers need to be saved & save area size. */
13290 info_ptr->first_gp_reg_save = first_reg_to_save ();
13291 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
13292 even if it currently looks like we won't. */
13293 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
13294 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
13295 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
13296 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
13297 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
13298 else
13299 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
13301 /* For the SPE, we have an additional upper 32-bits on each GPR.
13302 Ideally we should save the entire 64-bits only when the upper
13303 half is used in SIMD instructions. Since we only record
13304 registers live (not the size they are used in), this proves
13305 difficult because we'd have to traverse the instruction chain at
13306 the right time, taking reload into account. This is a real pain,
13307 so we opt to save the GPRs in 64-bits always if but one register
13308 gets used in 64-bits. Otherwise, all the registers in the frame
13309 get saved in 32-bits.
13311 So... since when we save all GPRs (except the SP) in 64-bits, the
13312 traditional GP save area will be empty. */
13313 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13314 info_ptr->gp_size = 0;
13316 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
13317 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
13319 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
13320 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
13321 - info_ptr->first_altivec_reg_save);
13323 /* Does this function call anything? */
13324 info_ptr->calls_p = (! current_function_is_leaf
13325 || cfun->machine->ra_needs_full_frame);
13327 /* Determine if we need to save the link register. */
13328 if ((DEFAULT_ABI == ABI_AIX
13329 && current_function_profile
13330 && !TARGET_PROFILE_KERNEL)
13331 #ifdef TARGET_RELOCATABLE
13332 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
13333 #endif
13334 || (info_ptr->first_fp_reg_save != 64
13335 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
13336 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
13337 || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
13338 || info_ptr->calls_p
13339 || rs6000_ra_ever_killed ())
13341 info_ptr->lr_save_p = 1;
13342 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
13345 /* Determine if we need to save the condition code registers. */
13346 if (regs_ever_live[CR2_REGNO]
13347 || regs_ever_live[CR3_REGNO]
13348 || regs_ever_live[CR4_REGNO])
13350 info_ptr->cr_save_p = 1;
13351 if (DEFAULT_ABI == ABI_V4)
13352 info_ptr->cr_size = reg_size;
13355 /* If the current function calls __builtin_eh_return, then we need
13356 to allocate stack space for registers that will hold data for
13357 the exception handler. */
13358 if (current_function_calls_eh_return)
13360 unsigned int i;
13361 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
13362 continue;
13364 /* SPE saves EH registers in 64-bits. */
13365 ehrd_size = i * (TARGET_SPE_ABI
13366 && info_ptr->spe_64bit_regs_used != 0
13367 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
13369 else
13370 ehrd_size = 0;
13372 /* Determine various sizes. */
13373 info_ptr->reg_size = reg_size;
13374 info_ptr->fixed_size = RS6000_SAVE_AREA;
13375 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
13376 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
13377 TARGET_ALTIVEC ? 16 : 8);
13378 if (FRAME_GROWS_DOWNWARD)
13379 info_ptr->vars_size
13380 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
13381 + info_ptr->parm_size,
13382 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
13383 - (info_ptr->fixed_size + info_ptr->vars_size
13384 + info_ptr->parm_size);
13386 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13387 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
13388 else
13389 info_ptr->spe_gp_size = 0;
13391 if (TARGET_ALTIVEC_ABI)
13392 info_ptr->vrsave_mask = compute_vrsave_mask ();
13393 else
13394 info_ptr->vrsave_mask = 0;
13396 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
13397 info_ptr->vrsave_size = 4;
13398 else
13399 info_ptr->vrsave_size = 0;
13401 compute_save_world_info (info_ptr);
13403 /* Calculate the offsets. */
13404 switch (DEFAULT_ABI)
13406 case ABI_NONE:
13407 default:
13408 gcc_unreachable ();
13410 case ABI_AIX:
13411 case ABI_DARWIN:
13412 info_ptr->fp_save_offset = - info_ptr->fp_size;
13413 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
13415 if (TARGET_ALTIVEC_ABI)
13417 info_ptr->vrsave_save_offset
13418 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
13420 /* Align stack so vector save area is on a quadword boundary.
13421 The padding goes above the vectors. */
13422 if (info_ptr->altivec_size != 0)
13423 info_ptr->altivec_padding_size
13424 = info_ptr->vrsave_save_offset & 0xF;
13425 else
13426 info_ptr->altivec_padding_size = 0;
13428 info_ptr->altivec_save_offset
13429 = info_ptr->vrsave_save_offset
13430 - info_ptr->altivec_padding_size
13431 - info_ptr->altivec_size;
13432 gcc_assert (info_ptr->altivec_size == 0
13433 || info_ptr->altivec_save_offset % 16 == 0);
13435 /* Adjust for AltiVec case. */
13436 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
13438 else
13439 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
13440 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
13441 info_ptr->lr_save_offset = 2*reg_size;
13442 break;
13444 case ABI_V4:
13445 info_ptr->fp_save_offset = - info_ptr->fp_size;
13446 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
13447 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
13449 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
13451 /* Align stack so SPE GPR save area is aligned on a
13452 double-word boundary. */
13453 if (info_ptr->spe_gp_size != 0)
13454 info_ptr->spe_padding_size
13455 = 8 - (-info_ptr->cr_save_offset % 8);
13456 else
13457 info_ptr->spe_padding_size = 0;
13459 info_ptr->spe_gp_save_offset
13460 = info_ptr->cr_save_offset
13461 - info_ptr->spe_padding_size
13462 - info_ptr->spe_gp_size;
13464 /* Adjust for SPE case. */
13465 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
13467 else if (TARGET_ALTIVEC_ABI)
13469 info_ptr->vrsave_save_offset
13470 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
13472 /* Align stack so vector save area is on a quadword boundary. */
13473 if (info_ptr->altivec_size != 0)
13474 info_ptr->altivec_padding_size
13475 = 16 - (-info_ptr->vrsave_save_offset % 16);
13476 else
13477 info_ptr->altivec_padding_size = 0;
13479 info_ptr->altivec_save_offset
13480 = info_ptr->vrsave_save_offset
13481 - info_ptr->altivec_padding_size
13482 - info_ptr->altivec_size;
13484 /* Adjust for AltiVec case. */
13485 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
13487 else
13488 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
13489 info_ptr->ehrd_offset -= ehrd_size;
13490 info_ptr->lr_save_offset = reg_size;
13491 break;
13494 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
13495 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
13496 + info_ptr->gp_size
13497 + info_ptr->altivec_size
13498 + info_ptr->altivec_padding_size
13499 + info_ptr->spe_gp_size
13500 + info_ptr->spe_padding_size
13501 + ehrd_size
13502 + info_ptr->cr_size
13503 + info_ptr->vrsave_size,
13504 save_align);
13506 non_fixed_size = (info_ptr->vars_size
13507 + info_ptr->parm_size
13508 + info_ptr->save_size);
13510 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
13511 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
13513 /* Determine if we need to allocate any stack frame:
13515 For AIX we need to push the stack if a frame pointer is needed
13516 (because the stack might be dynamically adjusted), if we are
13517 debugging, if we make calls, or if the sum of fp_save, gp_save,
13518 and local variables are more than the space needed to save all
13519 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
13520 + 18*8 = 288 (GPR13 reserved).
13522 For V.4 we don't have the stack cushion that AIX uses, but assume
13523 that the debugger can handle stackless frames. */
13525 if (info_ptr->calls_p)
13526 info_ptr->push_p = 1;
13528 else if (DEFAULT_ABI == ABI_V4)
13529 info_ptr->push_p = non_fixed_size != 0;
13531 else if (frame_pointer_needed)
13532 info_ptr->push_p = 1;
13534 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
13535 info_ptr->push_p = 1;
13537 else
13538 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
13540 /* Zero offsets if we're not saving those registers. */
13541 if (info_ptr->fp_size == 0)
13542 info_ptr->fp_save_offset = 0;
13544 if (info_ptr->gp_size == 0)
13545 info_ptr->gp_save_offset = 0;
13547 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
13548 info_ptr->altivec_save_offset = 0;
13550 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
13551 info_ptr->vrsave_save_offset = 0;
13553 if (! TARGET_SPE_ABI
13554 || info_ptr->spe_64bit_regs_used == 0
13555 || info_ptr->spe_gp_size == 0)
13556 info_ptr->spe_gp_save_offset = 0;
13558 if (! info_ptr->lr_save_p)
13559 info_ptr->lr_save_offset = 0;
13561 if (! info_ptr->cr_save_p)
13562 info_ptr->cr_save_offset = 0;
13564 return info_ptr;
13567 /* Return true if the current function uses any GPRs in 64-bit SIMD
13568 mode. */
13570 static bool
13571 spe_func_has_64bit_regs_p (void)
13573 rtx insns, insn;
13575 /* Functions that save and restore all the call-saved registers will
13576 need to save/restore the registers in 64-bits. */
13577 if (current_function_calls_eh_return
13578 || current_function_calls_setjmp
13579 || current_function_has_nonlocal_goto)
13580 return true;
13582 insns = get_insns ();
13584 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
13586 if (INSN_P (insn))
13588 rtx i;
13590 /* FIXME: This should be implemented with attributes...
13592 (set_attr "spe64" "true")....then,
13593 if (get_spe64(insn)) return true;
13595 It's the only reliable way to do the stuff below. */
13597 i = PATTERN (insn);
13598 if (GET_CODE (i) == SET)
13600 enum machine_mode mode = GET_MODE (SET_SRC (i));
13602 if (SPE_VECTOR_MODE (mode))
13603 return true;
13604 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
13605 return true;
13610 return false;
13613 static void
13614 debug_stack_info (rs6000_stack_t *info)
13616 const char *abi_string;
13618 if (! info)
13619 info = rs6000_stack_info ();
13621 fprintf (stderr, "\nStack information for function %s:\n",
13622 ((current_function_decl && DECL_NAME (current_function_decl))
13623 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
13624 : "<unknown>"));
13626 switch (info->abi)
13628 default: abi_string = "Unknown"; break;
13629 case ABI_NONE: abi_string = "NONE"; break;
13630 case ABI_AIX: abi_string = "AIX"; break;
13631 case ABI_DARWIN: abi_string = "Darwin"; break;
13632 case ABI_V4: abi_string = "V.4"; break;
13635 fprintf (stderr, "\tABI = %5s\n", abi_string);
13637 if (TARGET_ALTIVEC_ABI)
13638 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
13640 if (TARGET_SPE_ABI)
13641 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
13643 if (info->first_gp_reg_save != 32)
13644 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
13646 if (info->first_fp_reg_save != 64)
13647 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
13649 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
13650 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
13651 info->first_altivec_reg_save);
13653 if (info->lr_save_p)
13654 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
13656 if (info->cr_save_p)
13657 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
13659 if (info->vrsave_mask)
13660 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
13662 if (info->push_p)
13663 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
13665 if (info->calls_p)
13666 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
13668 if (info->gp_save_offset)
13669 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
13671 if (info->fp_save_offset)
13672 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
13674 if (info->altivec_save_offset)
13675 fprintf (stderr, "\taltivec_save_offset = %5d\n",
13676 info->altivec_save_offset);
13678 if (info->spe_gp_save_offset)
13679 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
13680 info->spe_gp_save_offset);
13682 if (info->vrsave_save_offset)
13683 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
13684 info->vrsave_save_offset);
13686 if (info->lr_save_offset)
13687 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
13689 if (info->cr_save_offset)
13690 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
13692 if (info->varargs_save_offset)
13693 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
13695 if (info->total_size)
13696 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13697 info->total_size);
13699 if (info->vars_size)
13700 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13701 info->vars_size);
13703 if (info->parm_size)
13704 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
13706 if (info->fixed_size)
13707 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
13709 if (info->gp_size)
13710 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
13712 if (info->spe_gp_size)
13713 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
13715 if (info->fp_size)
13716 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
13718 if (info->altivec_size)
13719 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
13721 if (info->vrsave_size)
13722 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
13724 if (info->altivec_padding_size)
13725 fprintf (stderr, "\taltivec_padding_size= %5d\n",
13726 info->altivec_padding_size);
13728 if (info->spe_padding_size)
13729 fprintf (stderr, "\tspe_padding_size = %5d\n",
13730 info->spe_padding_size);
13732 if (info->cr_size)
13733 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
13735 if (info->save_size)
13736 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
13738 if (info->reg_size != 4)
13739 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
13741 fprintf (stderr, "\n");
13745 rs6000_return_addr (int count, rtx frame)
13747 /* Currently we don't optimize very well between prolog and body
13748 code and for PIC code the code can be actually quite bad, so
13749 don't try to be too clever here. */
13750 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
13752 cfun->machine->ra_needs_full_frame = 1;
13754 return
13755 gen_rtx_MEM
13756 (Pmode,
13757 memory_address
13758 (Pmode,
13759 plus_constant (copy_to_reg
13760 (gen_rtx_MEM (Pmode,
13761 memory_address (Pmode, frame))),
13762 RETURN_ADDRESS_OFFSET)));
13765 cfun->machine->ra_need_lr = 1;
13766 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
13769 /* Say whether a function is a candidate for sibcall handling or not.
13770 We do not allow indirect calls to be optimized into sibling calls.
13771 Also, we can't do it if there are any vector parameters; there's
13772 nowhere to put the VRsave code so it works; note that functions with
13773 vector parameters are required to have a prototype, so the argument
13774 type info must be available here. (The tail recursion case can work
13775 with vector parameters, but there's no way to distinguish here.) */
13776 static bool
13777 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
13779 tree type;
13780 if (decl)
13782 if (TARGET_ALTIVEC_VRSAVE)
13784 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
13785 type; type = TREE_CHAIN (type))
13787 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
13788 return false;
13791 if (DEFAULT_ABI == ABI_DARWIN
13792 || (*targetm.binds_local_p) (decl))
13794 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
13796 if (!lookup_attribute ("longcall", attr_list)
13797 || lookup_attribute ("shortcall", attr_list))
13798 return true;
13801 return false;
13804 /* NULL if INSN insn is valid within a low-overhead loop.
13805 Otherwise return why doloop cannot be applied.
13806 PowerPC uses the COUNT register for branch on table instructions. */
13808 static const char *
13809 rs6000_invalid_within_doloop (rtx insn)
13811 if (CALL_P (insn))
13812 return "Function call in the loop.";
13814 if (JUMP_P (insn)
13815 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
13816 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
13817 return "Computed branch in the loop.";
13819 return NULL;
13822 static int
13823 rs6000_ra_ever_killed (void)
13825 rtx top;
13826 rtx reg;
13827 rtx insn;
13829 if (current_function_is_thunk)
13830 return 0;
13832 /* regs_ever_live has LR marked as used if any sibcalls are present,
13833 but this should not force saving and restoring in the
13834 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13835 clobbers LR, so that is inappropriate. */
13837 /* Also, the prologue can generate a store into LR that
13838 doesn't really count, like this:
13840 move LR->R0
13841 bcl to set PIC register
13842 move LR->R31
13843 move R0->LR
13845 When we're called from the epilogue, we need to avoid counting
13846 this as a store. */
13848 push_topmost_sequence ();
13849 top = get_insns ();
13850 pop_topmost_sequence ();
13851 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
13853 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
13855 if (INSN_P (insn))
13857 if (CALL_P (insn))
13859 if (!SIBLING_CALL_P (insn))
13860 return 1;
13862 else if (find_regno_note (insn, REG_INC, LINK_REGISTER_REGNUM))
13863 return 1;
13864 else if (set_of (reg, insn) != NULL_RTX
13865 && !prologue_epilogue_contains (insn))
13866 return 1;
13869 return 0;
13872 /* Add a REG_MAYBE_DEAD note to the insn. */
13873 static void
13874 rs6000_maybe_dead (rtx insn)
13876 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
13877 const0_rtx,
13878 REG_NOTES (insn));
13881 /* Emit instructions needed to load the TOC register.
13882 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13883 a constant pool; or for SVR4 -fpic. */
13885 void
13886 rs6000_emit_load_toc_table (int fromprolog)
13888 rtx dest, insn;
13889 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
13891 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
13893 char buf[30];
13894 rtx lab, tmp1, tmp2, got, tempLR;
13896 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13897 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13898 if (flag_pic == 2)
13899 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13900 else
13901 got = rs6000_got_sym ();
13902 tmp1 = tmp2 = dest;
13903 if (!fromprolog)
13905 tmp1 = gen_reg_rtx (Pmode);
13906 tmp2 = gen_reg_rtx (Pmode);
13908 tempLR = (fromprolog
13909 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13910 : gen_reg_rtx (Pmode));
13911 insn = emit_insn (gen_load_toc_v4_PIC_1 (tempLR, lab));
13912 if (fromprolog)
13913 rs6000_maybe_dead (insn);
13914 insn = emit_move_insn (tmp1, tempLR);
13915 if (fromprolog)
13916 rs6000_maybe_dead (insn);
13917 insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
13918 if (fromprolog)
13919 rs6000_maybe_dead (insn);
13920 insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
13921 if (fromprolog)
13922 rs6000_maybe_dead (insn);
13924 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
13926 rtx tempLR = (fromprolog
13927 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13928 : gen_reg_rtx (Pmode));
13930 insn = emit_insn (gen_load_toc_v4_pic_si (tempLR));
13931 if (fromprolog)
13932 rs6000_maybe_dead (insn);
13933 insn = emit_move_insn (dest, tempLR);
13934 if (fromprolog)
13935 rs6000_maybe_dead (insn);
13937 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
13939 char buf[30];
13940 rtx tempLR = (fromprolog
13941 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13942 : gen_reg_rtx (Pmode));
13943 rtx temp0 = (fromprolog
13944 ? gen_rtx_REG (Pmode, 0)
13945 : gen_reg_rtx (Pmode));
13947 if (fromprolog)
13949 rtx symF, symL;
13951 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13952 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13954 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
13955 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13957 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
13958 symF)));
13959 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
13960 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
13961 symL,
13962 symF)));
13964 else
13966 rtx tocsym;
13968 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13969 emit_insn (gen_load_toc_v4_PIC_1b (tempLR, tocsym));
13970 emit_move_insn (dest, tempLR);
13971 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
13973 insn = emit_insn (gen_addsi3 (dest, temp0, dest));
13974 if (fromprolog)
13975 rs6000_maybe_dead (insn);
13977 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
13979 /* This is for AIX code running in non-PIC ELF32. */
13980 char buf[30];
13981 rtx realsym;
13982 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
13983 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13985 insn = emit_insn (gen_elf_high (dest, realsym));
13986 if (fromprolog)
13987 rs6000_maybe_dead (insn);
13988 insn = emit_insn (gen_elf_low (dest, dest, realsym));
13989 if (fromprolog)
13990 rs6000_maybe_dead (insn);
13992 else
13994 gcc_assert (DEFAULT_ABI == ABI_AIX);
13996 if (TARGET_32BIT)
13997 insn = emit_insn (gen_load_toc_aix_si (dest));
13998 else
13999 insn = emit_insn (gen_load_toc_aix_di (dest));
14000 if (fromprolog)
14001 rs6000_maybe_dead (insn);
14005 /* Emit instructions to restore the link register after determining where
14006 its value has been stored. */
14008 void
14009 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
14011 rs6000_stack_t *info = rs6000_stack_info ();
14012 rtx operands[2];
14014 operands[0] = source;
14015 operands[1] = scratch;
14017 if (info->lr_save_p)
14019 rtx frame_rtx = stack_pointer_rtx;
14020 HOST_WIDE_INT sp_offset = 0;
14021 rtx tmp;
14023 if (frame_pointer_needed
14024 || current_function_calls_alloca
14025 || info->total_size > 32767)
14027 tmp = gen_frame_mem (Pmode, frame_rtx);
14028 emit_move_insn (operands[1], tmp);
14029 frame_rtx = operands[1];
14031 else if (info->push_p)
14032 sp_offset = info->total_size;
14034 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
14035 tmp = gen_frame_mem (Pmode, tmp);
14036 emit_move_insn (tmp, operands[0]);
14038 else
14039 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
14042 static GTY(()) int set = -1;
14045 get_TOC_alias_set (void)
14047 if (set == -1)
14048 set = new_alias_set ();
14049 return set;
14052 /* This returns nonzero if the current function uses the TOC. This is
14053 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
14054 is generated by the ABI_V4 load_toc_* patterns. */
14055 #if TARGET_ELF
14056 static int
14057 uses_TOC (void)
14059 rtx insn;
14061 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
14062 if (INSN_P (insn))
14064 rtx pat = PATTERN (insn);
14065 int i;
14067 if (GET_CODE (pat) == PARALLEL)
14068 for (i = 0; i < XVECLEN (pat, 0); i++)
14070 rtx sub = XVECEXP (pat, 0, i);
14071 if (GET_CODE (sub) == USE)
14073 sub = XEXP (sub, 0);
14074 if (GET_CODE (sub) == UNSPEC
14075 && XINT (sub, 1) == UNSPEC_TOC)
14076 return 1;
14080 return 0;
14082 #endif
14085 create_TOC_reference (rtx symbol)
14087 if (no_new_pseudos)
14088 regs_ever_live[TOC_REGISTER] = 1;
14089 return gen_rtx_PLUS (Pmode,
14090 gen_rtx_REG (Pmode, TOC_REGISTER),
14091 gen_rtx_CONST (Pmode,
14092 gen_rtx_MINUS (Pmode, symbol,
14093 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
14096 /* If _Unwind_* has been called from within the same module,
14097 toc register is not guaranteed to be saved to 40(1) on function
14098 entry. Save it there in that case. */
14100 void
14101 rs6000_aix_emit_builtin_unwind_init (void)
14103 rtx mem;
14104 rtx stack_top = gen_reg_rtx (Pmode);
14105 rtx opcode_addr = gen_reg_rtx (Pmode);
14106 rtx opcode = gen_reg_rtx (SImode);
14107 rtx tocompare = gen_reg_rtx (SImode);
14108 rtx no_toc_save_needed = gen_label_rtx ();
14110 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
14111 emit_move_insn (stack_top, mem);
14113 mem = gen_frame_mem (Pmode,
14114 gen_rtx_PLUS (Pmode, stack_top,
14115 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
14116 emit_move_insn (opcode_addr, mem);
14117 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
14118 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
14119 : 0xE8410028, SImode));
14121 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
14122 SImode, NULL_RTX, NULL_RTX,
14123 no_toc_save_needed);
14125 mem = gen_frame_mem (Pmode,
14126 gen_rtx_PLUS (Pmode, stack_top,
14127 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
14128 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
14129 emit_label (no_toc_save_needed);
14132 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
14133 and the change to the stack pointer. */
14135 static void
14136 rs6000_emit_stack_tie (void)
14138 rtx mem = gen_frame_mem (BLKmode,
14139 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
14141 emit_insn (gen_stack_tie (mem));
14144 /* Emit the correct code for allocating stack space, as insns.
14145 If COPY_R12, make sure a copy of the old frame is left in r12.
14146 The generated code may use hard register 0 as a temporary. */
14148 static void
14149 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
14151 rtx insn;
14152 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14153 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
14154 rtx todec = gen_int_mode (-size, Pmode);
14156 if (INTVAL (todec) != -size)
14158 warning (0, "stack frame too large");
14159 emit_insn (gen_trap ());
14160 return;
14163 if (current_function_limit_stack)
14165 if (REG_P (stack_limit_rtx)
14166 && REGNO (stack_limit_rtx) > 1
14167 && REGNO (stack_limit_rtx) <= 31)
14169 emit_insn (TARGET_32BIT
14170 ? gen_addsi3 (tmp_reg,
14171 stack_limit_rtx,
14172 GEN_INT (size))
14173 : gen_adddi3 (tmp_reg,
14174 stack_limit_rtx,
14175 GEN_INT (size)));
14177 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
14178 const0_rtx));
14180 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
14181 && TARGET_32BIT
14182 && DEFAULT_ABI == ABI_V4)
14184 rtx toload = gen_rtx_CONST (VOIDmode,
14185 gen_rtx_PLUS (Pmode,
14186 stack_limit_rtx,
14187 GEN_INT (size)));
14189 emit_insn (gen_elf_high (tmp_reg, toload));
14190 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
14191 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
14192 const0_rtx));
14194 else
14195 warning (0, "stack limit expression is not supported");
14198 if (copy_r12 || ! TARGET_UPDATE)
14199 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
14201 if (TARGET_UPDATE)
14203 if (size > 32767)
14205 /* Need a note here so that try_split doesn't get confused. */
14206 if (get_last_insn () == NULL_RTX)
14207 emit_note (NOTE_INSN_DELETED);
14208 insn = emit_move_insn (tmp_reg, todec);
14209 try_split (PATTERN (insn), insn, 0);
14210 todec = tmp_reg;
14213 insn = emit_insn (TARGET_32BIT
14214 ? gen_movsi_update (stack_reg, stack_reg,
14215 todec, stack_reg)
14216 : gen_movdi_di_update (stack_reg, stack_reg,
14217 todec, stack_reg));
14219 else
14221 insn = emit_insn (TARGET_32BIT
14222 ? gen_addsi3 (stack_reg, stack_reg, todec)
14223 : gen_adddi3 (stack_reg, stack_reg, todec));
14224 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
14225 gen_rtx_REG (Pmode, 12));
14228 RTX_FRAME_RELATED_P (insn) = 1;
14229 REG_NOTES (insn) =
14230 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14231 gen_rtx_SET (VOIDmode, stack_reg,
14232 gen_rtx_PLUS (Pmode, stack_reg,
14233 GEN_INT (-size))),
14234 REG_NOTES (insn));
14237 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
14238 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
14239 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
14240 deduce these equivalences by itself so it wasn't necessary to hold
14241 its hand so much. */
14243 static void
14244 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
14245 rtx reg2, rtx rreg)
14247 rtx real, temp;
14249 /* copy_rtx will not make unique copies of registers, so we need to
14250 ensure we don't have unwanted sharing here. */
14251 if (reg == reg2)
14252 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
14254 if (reg == rreg)
14255 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
14257 real = copy_rtx (PATTERN (insn));
14259 if (reg2 != NULL_RTX)
14260 real = replace_rtx (real, reg2, rreg);
14262 real = replace_rtx (real, reg,
14263 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
14264 STACK_POINTER_REGNUM),
14265 GEN_INT (val)));
14267 /* We expect that 'real' is either a SET or a PARALLEL containing
14268 SETs (and possibly other stuff). In a PARALLEL, all the SETs
14269 are important so they all have to be marked RTX_FRAME_RELATED_P. */
14271 if (GET_CODE (real) == SET)
14273 rtx set = real;
14275 temp = simplify_rtx (SET_SRC (set));
14276 if (temp)
14277 SET_SRC (set) = temp;
14278 temp = simplify_rtx (SET_DEST (set));
14279 if (temp)
14280 SET_DEST (set) = temp;
14281 if (GET_CODE (SET_DEST (set)) == MEM)
14283 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
14284 if (temp)
14285 XEXP (SET_DEST (set), 0) = temp;
14288 else
14290 int i;
14292 gcc_assert (GET_CODE (real) == PARALLEL);
14293 for (i = 0; i < XVECLEN (real, 0); i++)
14294 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
14296 rtx set = XVECEXP (real, 0, i);
14298 temp = simplify_rtx (SET_SRC (set));
14299 if (temp)
14300 SET_SRC (set) = temp;
14301 temp = simplify_rtx (SET_DEST (set));
14302 if (temp)
14303 SET_DEST (set) = temp;
14304 if (GET_CODE (SET_DEST (set)) == MEM)
14306 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
14307 if (temp)
14308 XEXP (SET_DEST (set), 0) = temp;
14310 RTX_FRAME_RELATED_P (set) = 1;
14314 if (TARGET_SPE)
14315 real = spe_synthesize_frame_save (real);
14317 RTX_FRAME_RELATED_P (insn) = 1;
14318 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14319 real,
14320 REG_NOTES (insn));
14323 /* Given an SPE frame note, return a PARALLEL of SETs with the
14324 original note, plus a synthetic register save. */
14326 static rtx
14327 spe_synthesize_frame_save (rtx real)
14329 rtx synth, offset, reg, real2;
14331 if (GET_CODE (real) != SET
14332 || GET_MODE (SET_SRC (real)) != V2SImode)
14333 return real;
14335 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
14336 frame related note. The parallel contains a set of the register
14337 being saved, and another set to a synthetic register (n+1200).
14338 This is so we can differentiate between 64-bit and 32-bit saves.
14339 Words cannot describe this nastiness. */
14341 gcc_assert (GET_CODE (SET_DEST (real)) == MEM
14342 && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS
14343 && GET_CODE (SET_SRC (real)) == REG);
14345 /* Transform:
14346 (set (mem (plus (reg x) (const y)))
14347 (reg z))
14348 into:
14349 (set (mem (plus (reg x) (const y+4)))
14350 (reg z+1200))
14353 real2 = copy_rtx (real);
14354 PUT_MODE (SET_DEST (real2), SImode);
14355 reg = SET_SRC (real2);
14356 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
14357 synth = copy_rtx (real2);
14359 if (BYTES_BIG_ENDIAN)
14361 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
14362 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
14365 reg = SET_SRC (synth);
14367 synth = replace_rtx (synth, reg,
14368 gen_rtx_REG (SImode, REGNO (reg) + 1200));
14370 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
14371 synth = replace_rtx (synth, offset,
14372 GEN_INT (INTVAL (offset)
14373 + (BYTES_BIG_ENDIAN ? 0 : 4)));
14375 RTX_FRAME_RELATED_P (synth) = 1;
14376 RTX_FRAME_RELATED_P (real2) = 1;
14377 if (BYTES_BIG_ENDIAN)
14378 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
14379 else
14380 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
14382 return real;
14385 /* Returns an insn that has a vrsave set operation with the
14386 appropriate CLOBBERs. */
14388 static rtx
14389 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
14391 int nclobs, i;
14392 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
14393 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14395 clobs[0]
14396 = gen_rtx_SET (VOIDmode,
14397 vrsave,
14398 gen_rtx_UNSPEC_VOLATILE (SImode,
14399 gen_rtvec (2, reg, vrsave),
14400 UNSPECV_SET_VRSAVE));
14402 nclobs = 1;
14404 /* We need to clobber the registers in the mask so the scheduler
14405 does not move sets to VRSAVE before sets of AltiVec registers.
14407 However, if the function receives nonlocal gotos, reload will set
14408 all call saved registers live. We will end up with:
14410 (set (reg 999) (mem))
14411 (parallel [ (set (reg vrsave) (unspec blah))
14412 (clobber (reg 999))])
14414 The clobber will cause the store into reg 999 to be dead, and
14415 flow will attempt to delete an epilogue insn. In this case, we
14416 need an unspec use/set of the register. */
14418 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
14419 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14421 if (!epiloguep || call_used_regs [i])
14422 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
14423 gen_rtx_REG (V4SImode, i));
14424 else
14426 rtx reg = gen_rtx_REG (V4SImode, i);
14428 clobs[nclobs++]
14429 = gen_rtx_SET (VOIDmode,
14430 reg,
14431 gen_rtx_UNSPEC (V4SImode,
14432 gen_rtvec (1, reg), 27));
14436 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
14438 for (i = 0; i < nclobs; ++i)
14439 XVECEXP (insn, 0, i) = clobs[i];
14441 return insn;
14444 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
14445 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
14447 static void
14448 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
14449 unsigned int regno, int offset, HOST_WIDE_INT total_size)
14451 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
14452 rtx replacea, replaceb;
14454 int_rtx = GEN_INT (offset);
14456 /* Some cases that need register indexed addressing. */
14457 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
14458 || (TARGET_E500_DOUBLE && mode == DFmode)
14459 || (TARGET_SPE_ABI
14460 && SPE_VECTOR_MODE (mode)
14461 && !SPE_CONST_OFFSET_OK (offset)))
14463 /* Whomever calls us must make sure r11 is available in the
14464 flow path of instructions in the prologue. */
14465 offset_rtx = gen_rtx_REG (Pmode, 11);
14466 emit_move_insn (offset_rtx, int_rtx);
14468 replacea = offset_rtx;
14469 replaceb = int_rtx;
14471 else
14473 offset_rtx = int_rtx;
14474 replacea = NULL_RTX;
14475 replaceb = NULL_RTX;
14478 reg = gen_rtx_REG (mode, regno);
14479 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
14480 mem = gen_frame_mem (mode, addr);
14482 insn = emit_move_insn (mem, reg);
14484 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
14487 /* Emit an offset memory reference suitable for a frame store, while
14488 converting to a valid addressing mode. */
14490 static rtx
14491 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
14493 rtx int_rtx, offset_rtx;
14495 int_rtx = GEN_INT (offset);
14497 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
14498 || (TARGET_E500_DOUBLE && mode == DFmode))
14500 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14501 emit_move_insn (offset_rtx, int_rtx);
14503 else
14504 offset_rtx = int_rtx;
14506 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
14509 /* Look for user-defined global regs. We should not save and restore these,
14510 and cannot use stmw/lmw if there are any in its range. */
14512 static bool
14513 no_global_regs_above (int first_greg)
14515 int i;
14516 for (i = 0; i < 32 - first_greg; i++)
14517 if (global_regs[first_greg + i])
14518 return false;
14519 return true;
14522 #ifndef TARGET_FIX_AND_CONTINUE
14523 #define TARGET_FIX_AND_CONTINUE 0
14524 #endif
14526 /* Emit function prologue as insns. */
14528 void
14529 rs6000_emit_prologue (void)
14531 rs6000_stack_t *info = rs6000_stack_info ();
14532 enum machine_mode reg_mode = Pmode;
14533 int reg_size = TARGET_32BIT ? 4 : 8;
14534 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14535 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
14536 rtx frame_reg_rtx = sp_reg_rtx;
14537 rtx cr_save_rtx = NULL_RTX;
14538 rtx insn;
14539 int saving_FPRs_inline;
14540 int using_store_multiple;
14541 HOST_WIDE_INT sp_offset = 0;
14543 if (TARGET_FIX_AND_CONTINUE)
14545 /* gdb on darwin arranges to forward a function from the old
14546 address by modifying the first 5 instructions of the function
14547 to branch to the overriding function. This is necessary to
14548 permit function pointers that point to the old function to
14549 actually forward to the new function. */
14550 emit_insn (gen_nop ());
14551 emit_insn (gen_nop ());
14552 emit_insn (gen_nop ());
14553 emit_insn (gen_nop ());
14554 emit_insn (gen_nop ());
14557 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14559 reg_mode = V2SImode;
14560 reg_size = 8;
14563 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
14564 && (!TARGET_SPE_ABI
14565 || info->spe_64bit_regs_used == 0)
14566 && info->first_gp_reg_save < 31
14567 && no_global_regs_above (info->first_gp_reg_save));
14568 saving_FPRs_inline = (info->first_fp_reg_save == 64
14569 || FP_SAVE_INLINE (info->first_fp_reg_save)
14570 || current_function_calls_eh_return
14571 || cfun->machine->ra_need_lr);
14573 /* For V.4, update stack before we do any saving and set back pointer. */
14574 if (! WORLD_SAVE_P (info)
14575 && info->push_p
14576 && (DEFAULT_ABI == ABI_V4
14577 || current_function_calls_eh_return))
14579 if (info->total_size < 32767)
14580 sp_offset = info->total_size;
14581 else
14582 frame_reg_rtx = frame_ptr_rtx;
14583 rs6000_emit_allocate_stack (info->total_size,
14584 (frame_reg_rtx != sp_reg_rtx
14585 && (info->cr_save_p
14586 || info->lr_save_p
14587 || info->first_fp_reg_save < 64
14588 || info->first_gp_reg_save < 32
14589 )));
14590 if (frame_reg_rtx != sp_reg_rtx)
14591 rs6000_emit_stack_tie ();
14594 /* Handle world saves specially here. */
14595 if (WORLD_SAVE_P (info))
14597 int i, j, sz;
14598 rtx treg;
14599 rtvec p;
14600 rtx reg0;
14602 /* save_world expects lr in r0. */
14603 reg0 = gen_rtx_REG (Pmode, 0);
14604 if (info->lr_save_p)
14606 insn = emit_move_insn (reg0,
14607 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14608 RTX_FRAME_RELATED_P (insn) = 1;
14611 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
14612 assumptions about the offsets of various bits of the stack
14613 frame. */
14614 gcc_assert (info->gp_save_offset == -220
14615 && info->fp_save_offset == -144
14616 && info->lr_save_offset == 8
14617 && info->cr_save_offset == 4
14618 && info->push_p
14619 && info->lr_save_p
14620 && (!current_function_calls_eh_return
14621 || info->ehrd_offset == -432)
14622 && info->vrsave_save_offset == -224
14623 && info->altivec_save_offset == -416);
14625 treg = gen_rtx_REG (SImode, 11);
14626 emit_move_insn (treg, GEN_INT (-info->total_size));
14628 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
14629 in R11. It also clobbers R12, so beware! */
14631 /* Preserve CR2 for save_world prologues */
14632 sz = 5;
14633 sz += 32 - info->first_gp_reg_save;
14634 sz += 64 - info->first_fp_reg_save;
14635 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
14636 p = rtvec_alloc (sz);
14637 j = 0;
14638 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
14639 gen_rtx_REG (Pmode,
14640 LINK_REGISTER_REGNUM));
14641 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
14642 gen_rtx_SYMBOL_REF (Pmode,
14643 "*save_world"));
14644 /* We do floats first so that the instruction pattern matches
14645 properly. */
14646 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14648 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14649 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14650 GEN_INT (info->fp_save_offset
14651 + sp_offset + 8 * i));
14652 rtx mem = gen_frame_mem (DFmode, addr);
14654 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14656 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
14658 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
14659 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14660 GEN_INT (info->altivec_save_offset
14661 + sp_offset + 16 * i));
14662 rtx mem = gen_frame_mem (V4SImode, addr);
14664 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14666 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14668 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14669 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14670 GEN_INT (info->gp_save_offset
14671 + sp_offset + reg_size * i));
14672 rtx mem = gen_frame_mem (reg_mode, addr);
14674 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14678 /* CR register traditionally saved as CR2. */
14679 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14680 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14681 GEN_INT (info->cr_save_offset
14682 + sp_offset));
14683 rtx mem = gen_frame_mem (reg_mode, addr);
14685 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14687 /* Explain about use of R0. */
14688 if (info->lr_save_p)
14690 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14691 GEN_INT (info->lr_save_offset
14692 + sp_offset));
14693 rtx mem = gen_frame_mem (reg_mode, addr);
14695 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
14697 /* Explain what happens to the stack pointer. */
14699 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
14700 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
14703 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14704 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14705 treg, GEN_INT (-info->total_size));
14706 sp_offset = info->total_size;
14709 /* Save AltiVec registers if needed. */
14710 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14712 int i;
14714 /* There should be a non inline version of this, for when we
14715 are saving lots of vector registers. */
14716 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14717 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14719 rtx areg, savereg, mem;
14720 int offset;
14722 offset = info->altivec_save_offset + sp_offset
14723 + 16 * (i - info->first_altivec_reg_save);
14725 savereg = gen_rtx_REG (V4SImode, i);
14727 areg = gen_rtx_REG (Pmode, 0);
14728 emit_move_insn (areg, GEN_INT (offset));
14730 /* AltiVec addressing mode is [reg+reg]. */
14731 mem = gen_frame_mem (V4SImode,
14732 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
14734 insn = emit_move_insn (mem, savereg);
14736 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14737 areg, GEN_INT (offset));
14741 /* VRSAVE is a bit vector representing which AltiVec registers
14742 are used. The OS uses this to determine which vector
14743 registers to save on a context switch. We need to save
14744 VRSAVE on the stack frame, add whatever AltiVec registers we
14745 used in this function, and do the corresponding magic in the
14746 epilogue. */
14748 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14749 && info->vrsave_mask != 0)
14751 rtx reg, mem, vrsave;
14752 int offset;
14754 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14755 as frame_reg_rtx and r11 as the static chain pointer for
14756 nested functions. */
14757 reg = gen_rtx_REG (SImode, 0);
14758 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14759 if (TARGET_MACHO)
14760 emit_insn (gen_get_vrsave_internal (reg));
14761 else
14762 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
14764 if (!WORLD_SAVE_P (info))
14766 /* Save VRSAVE. */
14767 offset = info->vrsave_save_offset + sp_offset;
14768 mem = gen_frame_mem (SImode,
14769 gen_rtx_PLUS (Pmode, frame_reg_rtx,
14770 GEN_INT (offset)));
14771 insn = emit_move_insn (mem, reg);
14774 /* Include the registers in the mask. */
14775 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
14777 insn = emit_insn (generate_set_vrsave (reg, info, 0));
14780 /* If we use the link register, get it into r0. */
14781 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14783 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14784 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14785 RTX_FRAME_RELATED_P (insn) = 1;
14788 /* If we need to save CR, put it into r12. */
14789 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
14791 rtx set;
14793 cr_save_rtx = gen_rtx_REG (SImode, 12);
14794 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14795 RTX_FRAME_RELATED_P (insn) = 1;
14796 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14797 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14798 But that's OK. All we have to do is specify that _one_ condition
14799 code register is saved in this stack slot. The thrower's epilogue
14800 will then restore all the call-saved registers.
14801 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14802 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
14803 gen_rtx_REG (SImode, CR2_REGNO));
14804 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14805 set,
14806 REG_NOTES (insn));
14809 /* Do any required saving of fpr's. If only one or two to save, do
14810 it ourselves. Otherwise, call function. */
14811 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
14813 int i;
14814 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14815 if ((regs_ever_live[info->first_fp_reg_save+i]
14816 && ! call_used_regs[info->first_fp_reg_save+i]))
14817 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
14818 info->first_fp_reg_save + i,
14819 info->fp_save_offset + sp_offset + 8 * i,
14820 info->total_size);
14822 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
14824 int i;
14825 char rname[30];
14826 const char *alloc_rname;
14827 rtvec p;
14828 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
14830 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
14831 gen_rtx_REG (Pmode,
14832 LINK_REGISTER_REGNUM));
14833 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
14834 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
14835 alloc_rname = ggc_strdup (rname);
14836 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
14837 gen_rtx_SYMBOL_REF (Pmode,
14838 alloc_rname));
14839 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14841 rtx addr, reg, mem;
14842 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14843 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14844 GEN_INT (info->fp_save_offset
14845 + sp_offset + 8*i));
14846 mem = gen_frame_mem (DFmode, addr);
14848 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
14850 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14851 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14852 NULL_RTX, NULL_RTX);
14855 /* Save GPRs. This is done as a PARALLEL if we are using
14856 the store-multiple instructions. */
14857 if (!WORLD_SAVE_P (info) && using_store_multiple)
14859 rtvec p;
14860 int i;
14861 p = rtvec_alloc (32 - info->first_gp_reg_save);
14862 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14864 rtx addr, reg, mem;
14865 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14866 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14867 GEN_INT (info->gp_save_offset
14868 + sp_offset
14869 + reg_size * i));
14870 mem = gen_frame_mem (reg_mode, addr);
14872 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
14874 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14875 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14876 NULL_RTX, NULL_RTX);
14878 else if (!WORLD_SAVE_P (info))
14880 int i;
14881 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14882 if ((regs_ever_live[info->first_gp_reg_save + i]
14883 && (!call_used_regs[info->first_gp_reg_save + i]
14884 || (i + info->first_gp_reg_save
14885 == RS6000_PIC_OFFSET_TABLE_REGNUM
14886 && TARGET_TOC && TARGET_MINIMAL_TOC)))
14887 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14888 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14889 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
14891 rtx addr, reg, mem;
14892 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14894 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14896 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
14897 rtx b;
14899 if (!SPE_CONST_OFFSET_OK (offset))
14901 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14902 emit_move_insn (b, GEN_INT (offset));
14904 else
14905 b = GEN_INT (offset);
14907 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
14908 mem = gen_frame_mem (V2SImode, addr);
14909 insn = emit_move_insn (mem, reg);
14911 if (GET_CODE (b) == CONST_INT)
14912 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14913 NULL_RTX, NULL_RTX);
14914 else
14915 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14916 b, GEN_INT (offset));
14918 else
14920 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14921 GEN_INT (info->gp_save_offset
14922 + sp_offset
14923 + reg_size * i));
14924 mem = gen_frame_mem (reg_mode, addr);
14926 insn = emit_move_insn (mem, reg);
14927 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14928 NULL_RTX, NULL_RTX);
14933 /* ??? There's no need to emit actual instructions here, but it's the
14934 easiest way to get the frame unwind information emitted. */
14935 if (current_function_calls_eh_return)
14937 unsigned int i, regno;
14939 /* In AIX ABI we need to pretend we save r2 here. */
14940 if (TARGET_AIX)
14942 rtx addr, reg, mem;
14944 reg = gen_rtx_REG (reg_mode, 2);
14945 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14946 GEN_INT (sp_offset + 5 * reg_size));
14947 mem = gen_frame_mem (reg_mode, addr);
14949 insn = emit_move_insn (mem, reg);
14950 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14951 NULL_RTX, NULL_RTX);
14952 PATTERN (insn) = gen_blockage ();
14955 for (i = 0; ; ++i)
14957 regno = EH_RETURN_DATA_REGNO (i);
14958 if (regno == INVALID_REGNUM)
14959 break;
14961 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14962 info->ehrd_offset + sp_offset
14963 + reg_size * (int) i,
14964 info->total_size);
14968 /* Save lr if we used it. */
14969 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14971 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14972 GEN_INT (info->lr_save_offset + sp_offset));
14973 rtx reg = gen_rtx_REG (Pmode, 0);
14974 rtx mem = gen_rtx_MEM (Pmode, addr);
14975 /* This should not be of frame_alias_set, because of
14976 __builtin_return_address. */
14978 insn = emit_move_insn (mem, reg);
14979 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14980 NULL_RTX, NULL_RTX);
14983 /* Save CR if we use any that must be preserved. */
14984 if (!WORLD_SAVE_P (info) && info->cr_save_p)
14986 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14987 GEN_INT (info->cr_save_offset + sp_offset));
14988 rtx mem = gen_frame_mem (SImode, addr);
14989 /* See the large comment above about why CR2_REGNO is used. */
14990 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
14992 /* If r12 was used to hold the original sp, copy cr into r0 now
14993 that it's free. */
14994 if (REGNO (frame_reg_rtx) == 12)
14996 rtx set;
14998 cr_save_rtx = gen_rtx_REG (SImode, 0);
14999 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
15000 RTX_FRAME_RELATED_P (insn) = 1;
15001 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
15002 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15003 set,
15004 REG_NOTES (insn));
15007 insn = emit_move_insn (mem, cr_save_rtx);
15009 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15010 NULL_RTX, NULL_RTX);
15013 /* Update stack and set back pointer unless this is V.4,
15014 for which it was done previously. */
15015 if (!WORLD_SAVE_P (info) && info->push_p
15016 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
15017 rs6000_emit_allocate_stack (info->total_size, FALSE);
15019 /* Set frame pointer, if needed. */
15020 if (frame_pointer_needed)
15022 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
15023 sp_reg_rtx);
15024 RTX_FRAME_RELATED_P (insn) = 1;
15027 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
15028 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
15029 || (DEFAULT_ABI == ABI_V4
15030 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
15031 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
15033 /* If emit_load_toc_table will use the link register, we need to save
15034 it. We use R12 for this purpose because emit_load_toc_table
15035 can use register 0. This allows us to use a plain 'blr' to return
15036 from the procedure more often. */
15037 int save_LR_around_toc_setup = (TARGET_ELF
15038 && DEFAULT_ABI != ABI_AIX
15039 && flag_pic
15040 && ! info->lr_save_p
15041 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
15042 if (save_LR_around_toc_setup)
15044 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
15046 insn = emit_move_insn (frame_ptr_rtx, lr);
15047 rs6000_maybe_dead (insn);
15048 RTX_FRAME_RELATED_P (insn) = 1;
15050 rs6000_emit_load_toc_table (TRUE);
15052 insn = emit_move_insn (lr, frame_ptr_rtx);
15053 rs6000_maybe_dead (insn);
15054 RTX_FRAME_RELATED_P (insn) = 1;
15056 else
15057 rs6000_emit_load_toc_table (TRUE);
15060 #if TARGET_MACHO
15061 if (DEFAULT_ABI == ABI_DARWIN
15062 && flag_pic && current_function_uses_pic_offset_table)
15064 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
15065 rtx src = machopic_function_base_sym ();
15067 /* Save and restore LR locally around this call (in R0). */
15068 if (!info->lr_save_p)
15069 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode, 0), lr));
15071 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr, src)));
15073 insn = emit_move_insn (gen_rtx_REG (Pmode,
15074 RS6000_PIC_OFFSET_TABLE_REGNUM),
15075 lr);
15076 rs6000_maybe_dead (insn);
15078 if (!info->lr_save_p)
15079 rs6000_maybe_dead (emit_move_insn (lr, gen_rtx_REG (Pmode, 0)));
15081 #endif
15084 /* Write function prologue. */
15086 static void
15087 rs6000_output_function_prologue (FILE *file,
15088 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
15090 rs6000_stack_t *info = rs6000_stack_info ();
15092 if (TARGET_DEBUG_STACK)
15093 debug_stack_info (info);
15095 /* Write .extern for any function we will call to save and restore
15096 fp values. */
15097 if (info->first_fp_reg_save < 64
15098 && !FP_SAVE_INLINE (info->first_fp_reg_save))
15099 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
15100 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
15101 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
15102 RESTORE_FP_SUFFIX);
15104 /* Write .extern for AIX common mode routines, if needed. */
15105 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
15107 fputs ("\t.extern __mulh\n", file);
15108 fputs ("\t.extern __mull\n", file);
15109 fputs ("\t.extern __divss\n", file);
15110 fputs ("\t.extern __divus\n", file);
15111 fputs ("\t.extern __quoss\n", file);
15112 fputs ("\t.extern __quous\n", file);
15113 common_mode_defined = 1;
15116 if (! HAVE_prologue)
15118 start_sequence ();
15120 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
15121 the "toplevel" insn chain. */
15122 emit_note (NOTE_INSN_DELETED);
15123 rs6000_emit_prologue ();
15124 emit_note (NOTE_INSN_DELETED);
15126 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15128 rtx insn;
15129 unsigned addr = 0;
15130 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15132 INSN_ADDRESSES_NEW (insn, addr);
15133 addr += 4;
15137 if (TARGET_DEBUG_STACK)
15138 debug_rtx_list (get_insns (), 100);
15139 final (get_insns (), file, FALSE);
15140 end_sequence ();
15143 rs6000_pic_labelno++;
15146 /* Emit function epilogue as insns.
15148 At present, dwarf2out_frame_debug_expr doesn't understand
15149 register restores, so we don't bother setting RTX_FRAME_RELATED_P
15150 anywhere in the epilogue. Most of the insns below would in any case
15151 need special notes to explain where r11 is in relation to the stack. */
15153 void
15154 rs6000_emit_epilogue (int sibcall)
15156 rs6000_stack_t *info;
15157 int restoring_FPRs_inline;
15158 int using_load_multiple;
15159 int using_mtcr_multiple;
15160 int use_backchain_to_restore_sp;
15161 int sp_offset = 0;
15162 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
15163 rtx frame_reg_rtx = sp_reg_rtx;
15164 enum machine_mode reg_mode = Pmode;
15165 int reg_size = TARGET_32BIT ? 4 : 8;
15166 int i;
15168 info = rs6000_stack_info ();
15170 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15172 reg_mode = V2SImode;
15173 reg_size = 8;
15176 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
15177 && (!TARGET_SPE_ABI
15178 || info->spe_64bit_regs_used == 0)
15179 && info->first_gp_reg_save < 31
15180 && no_global_regs_above (info->first_gp_reg_save));
15181 restoring_FPRs_inline = (sibcall
15182 || current_function_calls_eh_return
15183 || info->first_fp_reg_save == 64
15184 || FP_SAVE_INLINE (info->first_fp_reg_save));
15185 use_backchain_to_restore_sp = (frame_pointer_needed
15186 || current_function_calls_alloca
15187 || info->total_size > 32767);
15188 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
15189 || rs6000_cpu == PROCESSOR_PPC603
15190 || rs6000_cpu == PROCESSOR_PPC750
15191 || optimize_size);
15193 if (WORLD_SAVE_P (info))
15195 int i, j;
15196 char rname[30];
15197 const char *alloc_rname;
15198 rtvec p;
15200 /* eh_rest_world_r10 will return to the location saved in the LR
15201 stack slot (which is not likely to be our caller.)
15202 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
15203 rest_world is similar, except any R10 parameter is ignored.
15204 The exception-handling stuff that was here in 2.95 is no
15205 longer necessary. */
15207 p = rtvec_alloc (9
15209 + 32 - info->first_gp_reg_save
15210 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
15211 + 63 + 1 - info->first_fp_reg_save);
15213 strcpy (rname, ((current_function_calls_eh_return) ?
15214 "*eh_rest_world_r10" : "*rest_world"));
15215 alloc_rname = ggc_strdup (rname);
15217 j = 0;
15218 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
15219 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
15220 gen_rtx_REG (Pmode,
15221 LINK_REGISTER_REGNUM));
15222 RTVEC_ELT (p, j++)
15223 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
15224 /* The instruction pattern requires a clobber here;
15225 it is shared with the restVEC helper. */
15226 RTVEC_ELT (p, j++)
15227 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
15230 /* CR register traditionally saved as CR2. */
15231 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
15232 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15233 GEN_INT (info->cr_save_offset));
15234 rtx mem = gen_frame_mem (reg_mode, addr);
15236 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15239 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15241 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15242 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15243 GEN_INT (info->gp_save_offset
15244 + reg_size * i));
15245 rtx mem = gen_frame_mem (reg_mode, addr);
15247 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15249 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
15251 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
15252 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15253 GEN_INT (info->altivec_save_offset
15254 + 16 * i));
15255 rtx mem = gen_frame_mem (V4SImode, addr);
15257 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15259 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
15261 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15262 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15263 GEN_INT (info->fp_save_offset
15264 + 8 * i));
15265 rtx mem = gen_frame_mem (DFmode, addr);
15267 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15269 RTVEC_ELT (p, j++)
15270 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
15271 RTVEC_ELT (p, j++)
15272 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
15273 RTVEC_ELT (p, j++)
15274 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
15275 RTVEC_ELT (p, j++)
15276 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
15277 RTVEC_ELT (p, j++)
15278 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
15279 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15281 return;
15284 /* If we have a frame pointer, a call to alloca, or a large stack
15285 frame, restore the old stack pointer using the backchain. Otherwise,
15286 we know what size to update it with. */
15287 if (use_backchain_to_restore_sp)
15289 /* Under V.4, don't reset the stack pointer until after we're done
15290 loading the saved registers. */
15291 if (DEFAULT_ABI == ABI_V4)
15292 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
15294 emit_move_insn (frame_reg_rtx,
15295 gen_rtx_MEM (Pmode, sp_reg_rtx));
15297 else if (info->push_p)
15299 if (DEFAULT_ABI == ABI_V4
15300 || current_function_calls_eh_return)
15301 sp_offset = info->total_size;
15302 else
15304 emit_insn (TARGET_32BIT
15305 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15306 GEN_INT (info->total_size))
15307 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15308 GEN_INT (info->total_size)));
15312 /* Restore AltiVec registers if needed. */
15313 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
15315 int i;
15317 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
15318 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
15320 rtx addr, areg, mem;
15322 areg = gen_rtx_REG (Pmode, 0);
15323 emit_move_insn
15324 (areg, GEN_INT (info->altivec_save_offset
15325 + sp_offset
15326 + 16 * (i - info->first_altivec_reg_save)));
15328 /* AltiVec addressing mode is [reg+reg]. */
15329 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
15330 mem = gen_frame_mem (V4SImode, addr);
15332 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
15336 /* Restore VRSAVE if needed. */
15337 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
15338 && info->vrsave_mask != 0)
15340 rtx addr, mem, reg;
15342 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15343 GEN_INT (info->vrsave_save_offset + sp_offset));
15344 mem = gen_frame_mem (SImode, addr);
15345 reg = gen_rtx_REG (SImode, 12);
15346 emit_move_insn (reg, mem);
15348 emit_insn (generate_set_vrsave (reg, info, 1));
15351 /* Get the old lr if we saved it. */
15352 if (info->lr_save_p)
15354 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
15355 info->lr_save_offset + sp_offset);
15357 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
15360 /* Get the old cr if we saved it. */
15361 if (info->cr_save_p)
15363 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15364 GEN_INT (info->cr_save_offset + sp_offset));
15365 rtx mem = gen_frame_mem (SImode, addr);
15367 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
15370 /* Set LR here to try to overlap restores below. */
15371 if (info->lr_save_p)
15372 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
15373 gen_rtx_REG (Pmode, 0));
15375 /* Load exception handler data registers, if needed. */
15376 if (current_function_calls_eh_return)
15378 unsigned int i, regno;
15380 if (TARGET_AIX)
15382 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15383 GEN_INT (sp_offset + 5 * reg_size));
15384 rtx mem = gen_frame_mem (reg_mode, addr);
15386 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
15389 for (i = 0; ; ++i)
15391 rtx mem;
15393 regno = EH_RETURN_DATA_REGNO (i);
15394 if (regno == INVALID_REGNUM)
15395 break;
15397 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
15398 info->ehrd_offset + sp_offset
15399 + reg_size * (int) i);
15401 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
15405 /* Restore GPRs. This is done as a PARALLEL if we are using
15406 the load-multiple instructions. */
15407 if (using_load_multiple)
15409 rtvec p;
15410 p = rtvec_alloc (32 - info->first_gp_reg_save);
15411 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15413 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15414 GEN_INT (info->gp_save_offset
15415 + sp_offset
15416 + reg_size * i));
15417 rtx mem = gen_frame_mem (reg_mode, addr);
15419 RTVEC_ELT (p, i) =
15420 gen_rtx_SET (VOIDmode,
15421 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
15422 mem);
15424 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15426 else
15427 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15428 if ((regs_ever_live[info->first_gp_reg_save + i]
15429 && (!call_used_regs[info->first_gp_reg_save + i]
15430 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
15431 && TARGET_TOC && TARGET_MINIMAL_TOC)))
15432 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
15433 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
15434 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
15436 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15437 GEN_INT (info->gp_save_offset
15438 + sp_offset
15439 + reg_size * i));
15440 rtx mem = gen_frame_mem (reg_mode, addr);
15442 /* Restore 64-bit quantities for SPE. */
15443 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15445 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
15446 rtx b;
15448 if (!SPE_CONST_OFFSET_OK (offset))
15450 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
15451 emit_move_insn (b, GEN_INT (offset));
15453 else
15454 b = GEN_INT (offset);
15456 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
15457 mem = gen_frame_mem (V2SImode, addr);
15460 emit_move_insn (gen_rtx_REG (reg_mode,
15461 info->first_gp_reg_save + i), mem);
15464 /* Restore fpr's if we need to do it without calling a function. */
15465 if (restoring_FPRs_inline)
15466 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15467 if ((regs_ever_live[info->first_fp_reg_save+i]
15468 && ! call_used_regs[info->first_fp_reg_save+i]))
15470 rtx addr, mem;
15471 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15472 GEN_INT (info->fp_save_offset
15473 + sp_offset
15474 + 8 * i));
15475 mem = gen_frame_mem (DFmode, addr);
15477 emit_move_insn (gen_rtx_REG (DFmode,
15478 info->first_fp_reg_save + i),
15479 mem);
15482 /* If we saved cr, restore it here. Just those that were used. */
15483 if (info->cr_save_p)
15485 rtx r12_rtx = gen_rtx_REG (SImode, 12);
15486 int count = 0;
15488 if (using_mtcr_multiple)
15490 for (i = 0; i < 8; i++)
15491 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15492 count++;
15493 gcc_assert (count);
15496 if (using_mtcr_multiple && count > 1)
15498 rtvec p;
15499 int ndx;
15501 p = rtvec_alloc (count);
15503 ndx = 0;
15504 for (i = 0; i < 8; i++)
15505 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15507 rtvec r = rtvec_alloc (2);
15508 RTVEC_ELT (r, 0) = r12_rtx;
15509 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
15510 RTVEC_ELT (p, ndx) =
15511 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
15512 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
15513 ndx++;
15515 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15516 gcc_assert (ndx == count);
15518 else
15519 for (i = 0; i < 8; i++)
15520 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15522 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
15523 CR0_REGNO+i),
15524 r12_rtx));
15528 /* If this is V.4, unwind the stack pointer after all of the loads
15529 have been done. */
15530 if (frame_reg_rtx != sp_reg_rtx)
15532 /* This blockage is needed so that sched doesn't decide to move
15533 the sp change before the register restores. */
15534 rs6000_emit_stack_tie ();
15535 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
15537 else if (sp_offset != 0)
15538 emit_insn (TARGET_32BIT
15539 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15540 GEN_INT (sp_offset))
15541 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15542 GEN_INT (sp_offset)));
15544 if (current_function_calls_eh_return)
15546 rtx sa = EH_RETURN_STACKADJ_RTX;
15547 emit_insn (TARGET_32BIT
15548 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
15549 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
15552 if (!sibcall)
15554 rtvec p;
15555 if (! restoring_FPRs_inline)
15556 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
15557 else
15558 p = rtvec_alloc (2);
15560 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
15561 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
15562 gen_rtx_REG (Pmode,
15563 LINK_REGISTER_REGNUM));
15565 /* If we have to restore more than two FP registers, branch to the
15566 restore function. It will return to our caller. */
15567 if (! restoring_FPRs_inline)
15569 int i;
15570 char rname[30];
15571 const char *alloc_rname;
15573 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
15574 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
15575 alloc_rname = ggc_strdup (rname);
15576 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
15577 gen_rtx_SYMBOL_REF (Pmode,
15578 alloc_rname));
15580 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15582 rtx addr, mem;
15583 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
15584 GEN_INT (info->fp_save_offset + 8*i));
15585 mem = gen_frame_mem (DFmode, addr);
15587 RTVEC_ELT (p, i+3) =
15588 gen_rtx_SET (VOIDmode,
15589 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
15590 mem);
15594 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15598 /* Write function epilogue. */
15600 static void
15601 rs6000_output_function_epilogue (FILE *file,
15602 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
15604 if (! HAVE_epilogue)
15606 rtx insn = get_last_insn ();
15607 /* If the last insn was a BARRIER, we don't have to write anything except
15608 the trace table. */
15609 if (GET_CODE (insn) == NOTE)
15610 insn = prev_nonnote_insn (insn);
15611 if (insn == 0 || GET_CODE (insn) != BARRIER)
15613 /* This is slightly ugly, but at least we don't have two
15614 copies of the epilogue-emitting code. */
15615 start_sequence ();
15617 /* A NOTE_INSN_DELETED is supposed to be at the start
15618 and end of the "toplevel" insn chain. */
15619 emit_note (NOTE_INSN_DELETED);
15620 rs6000_emit_epilogue (FALSE);
15621 emit_note (NOTE_INSN_DELETED);
15623 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15625 rtx insn;
15626 unsigned addr = 0;
15627 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15629 INSN_ADDRESSES_NEW (insn, addr);
15630 addr += 4;
15634 if (TARGET_DEBUG_STACK)
15635 debug_rtx_list (get_insns (), 100);
15636 final (get_insns (), file, FALSE);
15637 end_sequence ();
15641 #if TARGET_MACHO
15642 macho_branch_islands ();
15643 /* Mach-O doesn't support labels at the end of objects, so if
15644 it looks like we might want one, insert a NOP. */
15646 rtx insn = get_last_insn ();
15647 while (insn
15648 && NOTE_P (insn)
15649 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL)
15650 insn = PREV_INSN (insn);
15651 if (insn
15652 && (LABEL_P (insn)
15653 || (NOTE_P (insn)
15654 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
15655 fputs ("\tnop\n", file);
15657 #endif
15659 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15660 on its format.
15662 We don't output a traceback table if -finhibit-size-directive was
15663 used. The documentation for -finhibit-size-directive reads
15664 ``don't output a @code{.size} assembler directive, or anything
15665 else that would cause trouble if the function is split in the
15666 middle, and the two halves are placed at locations far apart in
15667 memory.'' The traceback table has this property, since it
15668 includes the offset from the start of the function to the
15669 traceback table itself.
15671 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15672 different traceback table. */
15673 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
15674 && rs6000_traceback != traceback_none && !current_function_is_thunk)
15676 const char *fname = NULL;
15677 const char *language_string = lang_hooks.name;
15678 int fixed_parms = 0, float_parms = 0, parm_info = 0;
15679 int i;
15680 int optional_tbtab;
15681 rs6000_stack_t *info = rs6000_stack_info ();
15683 if (rs6000_traceback == traceback_full)
15684 optional_tbtab = 1;
15685 else if (rs6000_traceback == traceback_part)
15686 optional_tbtab = 0;
15687 else
15688 optional_tbtab = !optimize_size && !TARGET_ELF;
15690 if (optional_tbtab)
15692 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
15693 while (*fname == '.') /* V.4 encodes . in the name */
15694 fname++;
15696 /* Need label immediately before tbtab, so we can compute
15697 its offset from the function start. */
15698 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15699 ASM_OUTPUT_LABEL (file, fname);
15702 /* The .tbtab pseudo-op can only be used for the first eight
15703 expressions, since it can't handle the possibly variable
15704 length fields that follow. However, if you omit the optional
15705 fields, the assembler outputs zeros for all optional fields
15706 anyways, giving each variable length field is minimum length
15707 (as defined in sys/debug.h). Thus we can not use the .tbtab
15708 pseudo-op at all. */
15710 /* An all-zero word flags the start of the tbtab, for debuggers
15711 that have to find it by searching forward from the entry
15712 point or from the current pc. */
15713 fputs ("\t.long 0\n", file);
15715 /* Tbtab format type. Use format type 0. */
15716 fputs ("\t.byte 0,", file);
15718 /* Language type. Unfortunately, there does not seem to be any
15719 official way to discover the language being compiled, so we
15720 use language_string.
15721 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15722 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
15723 a number, so for now use 9. */
15724 if (! strcmp (language_string, "GNU C"))
15725 i = 0;
15726 else if (! strcmp (language_string, "GNU F77")
15727 || ! strcmp (language_string, "GNU F95"))
15728 i = 1;
15729 else if (! strcmp (language_string, "GNU Pascal"))
15730 i = 2;
15731 else if (! strcmp (language_string, "GNU Ada"))
15732 i = 3;
15733 else if (! strcmp (language_string, "GNU C++")
15734 || ! strcmp (language_string, "GNU Objective-C++"))
15735 i = 9;
15736 else if (! strcmp (language_string, "GNU Java"))
15737 i = 13;
15738 else if (! strcmp (language_string, "GNU Objective-C"))
15739 i = 14;
15740 else
15741 gcc_unreachable ();
15742 fprintf (file, "%d,", i);
15744 /* 8 single bit fields: global linkage (not set for C extern linkage,
15745 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15746 from start of procedure stored in tbtab, internal function, function
15747 has controlled storage, function has no toc, function uses fp,
15748 function logs/aborts fp operations. */
15749 /* Assume that fp operations are used if any fp reg must be saved. */
15750 fprintf (file, "%d,",
15751 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
15753 /* 6 bitfields: function is interrupt handler, name present in
15754 proc table, function calls alloca, on condition directives
15755 (controls stack walks, 3 bits), saves condition reg, saves
15756 link reg. */
15757 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15758 set up as a frame pointer, even when there is no alloca call. */
15759 fprintf (file, "%d,",
15760 ((optional_tbtab << 6)
15761 | ((optional_tbtab & frame_pointer_needed) << 5)
15762 | (info->cr_save_p << 1)
15763 | (info->lr_save_p)));
15765 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15766 (6 bits). */
15767 fprintf (file, "%d,",
15768 (info->push_p << 7) | (64 - info->first_fp_reg_save));
15770 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15771 fprintf (file, "%d,", (32 - first_reg_to_save ()));
15773 if (optional_tbtab)
15775 /* Compute the parameter info from the function decl argument
15776 list. */
15777 tree decl;
15778 int next_parm_info_bit = 31;
15780 for (decl = DECL_ARGUMENTS (current_function_decl);
15781 decl; decl = TREE_CHAIN (decl))
15783 rtx parameter = DECL_INCOMING_RTL (decl);
15784 enum machine_mode mode = GET_MODE (parameter);
15786 if (GET_CODE (parameter) == REG)
15788 if (SCALAR_FLOAT_MODE_P (mode))
15790 int bits;
15792 float_parms++;
15794 switch (mode)
15796 case SFmode:
15797 bits = 0x2;
15798 break;
15800 case DFmode:
15801 case TFmode:
15802 bits = 0x3;
15803 break;
15805 default:
15806 gcc_unreachable ();
15809 /* If only one bit will fit, don't or in this entry. */
15810 if (next_parm_info_bit > 0)
15811 parm_info |= (bits << (next_parm_info_bit - 1));
15812 next_parm_info_bit -= 2;
15814 else
15816 fixed_parms += ((GET_MODE_SIZE (mode)
15817 + (UNITS_PER_WORD - 1))
15818 / UNITS_PER_WORD);
15819 next_parm_info_bit -= 1;
15825 /* Number of fixed point parameters. */
15826 /* This is actually the number of words of fixed point parameters; thus
15827 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15828 fprintf (file, "%d,", fixed_parms);
15830 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15831 all on stack. */
15832 /* This is actually the number of fp registers that hold parameters;
15833 and thus the maximum value is 13. */
15834 /* Set parameters on stack bit if parameters are not in their original
15835 registers, regardless of whether they are on the stack? Xlc
15836 seems to set the bit when not optimizing. */
15837 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
15839 if (! optional_tbtab)
15840 return;
15842 /* Optional fields follow. Some are variable length. */
15844 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15845 11 double float. */
15846 /* There is an entry for each parameter in a register, in the order that
15847 they occur in the parameter list. Any intervening arguments on the
15848 stack are ignored. If the list overflows a long (max possible length
15849 34 bits) then completely leave off all elements that don't fit. */
15850 /* Only emit this long if there was at least one parameter. */
15851 if (fixed_parms || float_parms)
15852 fprintf (file, "\t.long %d\n", parm_info);
15854 /* Offset from start of code to tb table. */
15855 fputs ("\t.long ", file);
15856 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15857 if (TARGET_AIX)
15858 RS6000_OUTPUT_BASENAME (file, fname);
15859 else
15860 assemble_name (file, fname);
15861 putc ('-', file);
15862 rs6000_output_function_entry (file, fname);
15863 putc ('\n', file);
15865 /* Interrupt handler mask. */
15866 /* Omit this long, since we never set the interrupt handler bit
15867 above. */
15869 /* Number of CTL (controlled storage) anchors. */
15870 /* Omit this long, since the has_ctl bit is never set above. */
15872 /* Displacement into stack of each CTL anchor. */
15873 /* Omit this list of longs, because there are no CTL anchors. */
15875 /* Length of function name. */
15876 if (*fname == '*')
15877 ++fname;
15878 fprintf (file, "\t.short %d\n", (int) strlen (fname));
15880 /* Function name. */
15881 assemble_string (fname, strlen (fname));
15883 /* Register for alloca automatic storage; this is always reg 31.
15884 Only emit this if the alloca bit was set above. */
15885 if (frame_pointer_needed)
15886 fputs ("\t.byte 31\n", file);
15888 fputs ("\t.align 2\n", file);
15892 /* A C compound statement that outputs the assembler code for a thunk
15893 function, used to implement C++ virtual function calls with
15894 multiple inheritance. The thunk acts as a wrapper around a virtual
15895 function, adjusting the implicit object parameter before handing
15896 control off to the real function.
15898 First, emit code to add the integer DELTA to the location that
15899 contains the incoming first argument. Assume that this argument
15900 contains a pointer, and is the one used to pass the `this' pointer
15901 in C++. This is the incoming argument *before* the function
15902 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15903 values of all other incoming arguments.
15905 After the addition, emit code to jump to FUNCTION, which is a
15906 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15907 not touch the return address. Hence returning from FUNCTION will
15908 return to whoever called the current `thunk'.
15910 The effect must be as if FUNCTION had been called directly with the
15911 adjusted first argument. This macro is responsible for emitting
15912 all of the code for a thunk function; output_function_prologue()
15913 and output_function_epilogue() are not invoked.
15915 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15916 been extracted from it.) It might possibly be useful on some
15917 targets, but probably not.
15919 If you do not define this macro, the target-independent code in the
15920 C++ frontend will generate a less efficient heavyweight thunk that
15921 calls FUNCTION instead of jumping to it. The generic approach does
15922 not support varargs. */
15924 static void
15925 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
15926 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
15927 tree function)
15929 rtx this, insn, funexp;
15931 reload_completed = 1;
15932 epilogue_completed = 1;
15933 no_new_pseudos = 1;
15934 reset_block_changes ();
15936 /* Mark the end of the (empty) prologue. */
15937 emit_note (NOTE_INSN_PROLOGUE_END);
15939 /* Find the "this" pointer. If the function returns a structure,
15940 the structure return pointer is in r3. */
15941 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
15942 this = gen_rtx_REG (Pmode, 4);
15943 else
15944 this = gen_rtx_REG (Pmode, 3);
15946 /* Apply the constant offset, if required. */
15947 if (delta)
15949 rtx delta_rtx = GEN_INT (delta);
15950 emit_insn (TARGET_32BIT
15951 ? gen_addsi3 (this, this, delta_rtx)
15952 : gen_adddi3 (this, this, delta_rtx));
15955 /* Apply the offset from the vtable, if required. */
15956 if (vcall_offset)
15958 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
15959 rtx tmp = gen_rtx_REG (Pmode, 12);
15961 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
15962 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
15964 emit_insn (TARGET_32BIT
15965 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
15966 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
15967 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
15969 else
15971 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
15973 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
15975 emit_insn (TARGET_32BIT
15976 ? gen_addsi3 (this, this, tmp)
15977 : gen_adddi3 (this, this, tmp));
15980 /* Generate a tail call to the target function. */
15981 if (!TREE_USED (function))
15983 assemble_external (function);
15984 TREE_USED (function) = 1;
15986 funexp = XEXP (DECL_RTL (function), 0);
15987 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
15989 #if TARGET_MACHO
15990 if (MACHOPIC_INDIRECT)
15991 funexp = machopic_indirect_call_target (funexp);
15992 #endif
15994 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
15995 generate sibcall RTL explicitly. */
15996 insn = emit_call_insn (
15997 gen_rtx_PARALLEL (VOIDmode,
15998 gen_rtvec (4,
15999 gen_rtx_CALL (VOIDmode,
16000 funexp, const0_rtx),
16001 gen_rtx_USE (VOIDmode, const0_rtx),
16002 gen_rtx_USE (VOIDmode,
16003 gen_rtx_REG (SImode,
16004 LINK_REGISTER_REGNUM)),
16005 gen_rtx_RETURN (VOIDmode))));
16006 SIBLING_CALL_P (insn) = 1;
16007 emit_barrier ();
16009 /* Run just enough of rest_of_compilation to get the insns emitted.
16010 There's not really enough bulk here to make other passes such as
16011 instruction scheduling worth while. Note that use_thunk calls
16012 assemble_start_function and assemble_end_function. */
16013 insn = get_insns ();
16014 insn_locators_initialize ();
16015 shorten_branches (insn);
16016 final_start_function (insn, file, 1);
16017 final (insn, file, 1);
16018 final_end_function ();
16020 reload_completed = 0;
16021 epilogue_completed = 0;
16022 no_new_pseudos = 0;
16025 /* A quick summary of the various types of 'constant-pool tables'
16026 under PowerPC:
16028 Target Flags Name One table per
16029 AIX (none) AIX TOC object file
16030 AIX -mfull-toc AIX TOC object file
16031 AIX -mminimal-toc AIX minimal TOC translation unit
16032 SVR4/EABI (none) SVR4 SDATA object file
16033 SVR4/EABI -fpic SVR4 pic object file
16034 SVR4/EABI -fPIC SVR4 PIC translation unit
16035 SVR4/EABI -mrelocatable EABI TOC function
16036 SVR4/EABI -maix AIX TOC object file
16037 SVR4/EABI -maix -mminimal-toc
16038 AIX minimal TOC translation unit
16040 Name Reg. Set by entries contains:
16041 made by addrs? fp? sum?
16043 AIX TOC 2 crt0 as Y option option
16044 AIX minimal TOC 30 prolog gcc Y Y option
16045 SVR4 SDATA 13 crt0 gcc N Y N
16046 SVR4 pic 30 prolog ld Y not yet N
16047 SVR4 PIC 30 prolog gcc Y option option
16048 EABI TOC 30 prolog gcc Y option option
16052 /* Hash functions for the hash table. */
16054 static unsigned
16055 rs6000_hash_constant (rtx k)
16057 enum rtx_code code = GET_CODE (k);
16058 enum machine_mode mode = GET_MODE (k);
16059 unsigned result = (code << 3) ^ mode;
16060 const char *format;
16061 int flen, fidx;
16063 format = GET_RTX_FORMAT (code);
16064 flen = strlen (format);
16065 fidx = 0;
16067 switch (code)
16069 case LABEL_REF:
16070 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
16072 case CONST_DOUBLE:
16073 if (mode != VOIDmode)
16074 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
16075 flen = 2;
16076 break;
16078 case CODE_LABEL:
16079 fidx = 3;
16080 break;
16082 default:
16083 break;
16086 for (; fidx < flen; fidx++)
16087 switch (format[fidx])
16089 case 's':
16091 unsigned i, len;
16092 const char *str = XSTR (k, fidx);
16093 len = strlen (str);
16094 result = result * 613 + len;
16095 for (i = 0; i < len; i++)
16096 result = result * 613 + (unsigned) str[i];
16097 break;
16099 case 'u':
16100 case 'e':
16101 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
16102 break;
16103 case 'i':
16104 case 'n':
16105 result = result * 613 + (unsigned) XINT (k, fidx);
16106 break;
16107 case 'w':
16108 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
16109 result = result * 613 + (unsigned) XWINT (k, fidx);
16110 else
16112 size_t i;
16113 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
16114 result = result * 613 + (unsigned) (XWINT (k, fidx)
16115 >> CHAR_BIT * i);
16117 break;
16118 case '0':
16119 break;
16120 default:
16121 gcc_unreachable ();
16124 return result;
16127 static unsigned
16128 toc_hash_function (const void *hash_entry)
16130 const struct toc_hash_struct *thc =
16131 (const struct toc_hash_struct *) hash_entry;
16132 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
16135 /* Compare H1 and H2 for equivalence. */
16137 static int
16138 toc_hash_eq (const void *h1, const void *h2)
16140 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
16141 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
16143 if (((const struct toc_hash_struct *) h1)->key_mode
16144 != ((const struct toc_hash_struct *) h2)->key_mode)
16145 return 0;
16147 return rtx_equal_p (r1, r2);
16150 /* These are the names given by the C++ front-end to vtables, and
16151 vtable-like objects. Ideally, this logic should not be here;
16152 instead, there should be some programmatic way of inquiring as
16153 to whether or not an object is a vtable. */
16155 #define VTABLE_NAME_P(NAME) \
16156 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
16157 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
16158 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
16159 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
16160 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
16162 void
16163 rs6000_output_symbol_ref (FILE *file, rtx x)
16165 /* Currently C++ toc references to vtables can be emitted before it
16166 is decided whether the vtable is public or private. If this is
16167 the case, then the linker will eventually complain that there is
16168 a reference to an unknown section. Thus, for vtables only,
16169 we emit the TOC reference to reference the symbol and not the
16170 section. */
16171 const char *name = XSTR (x, 0);
16173 if (VTABLE_NAME_P (name))
16175 RS6000_OUTPUT_BASENAME (file, name);
16177 else
16178 assemble_name (file, name);
16181 /* Output a TOC entry. We derive the entry name from what is being
16182 written. */
16184 void
16185 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
16187 char buf[256];
16188 const char *name = buf;
16189 const char *real_name;
16190 rtx base = x;
16191 HOST_WIDE_INT offset = 0;
16193 gcc_assert (!TARGET_NO_TOC);
16195 /* When the linker won't eliminate them, don't output duplicate
16196 TOC entries (this happens on AIX if there is any kind of TOC,
16197 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
16198 CODE_LABELs. */
16199 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
16201 struct toc_hash_struct *h;
16202 void * * found;
16204 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
16205 time because GGC is not initialized at that point. */
16206 if (toc_hash_table == NULL)
16207 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
16208 toc_hash_eq, NULL);
16210 h = ggc_alloc (sizeof (*h));
16211 h->key = x;
16212 h->key_mode = mode;
16213 h->labelno = labelno;
16215 found = htab_find_slot (toc_hash_table, h, 1);
16216 if (*found == NULL)
16217 *found = h;
16218 else /* This is indeed a duplicate.
16219 Set this label equal to that label. */
16221 fputs ("\t.set ", file);
16222 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
16223 fprintf (file, "%d,", labelno);
16224 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
16225 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
16226 found)->labelno));
16227 return;
16231 /* If we're going to put a double constant in the TOC, make sure it's
16232 aligned properly when strict alignment is on. */
16233 if (GET_CODE (x) == CONST_DOUBLE
16234 && STRICT_ALIGNMENT
16235 && GET_MODE_BITSIZE (mode) >= 64
16236 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
16237 ASM_OUTPUT_ALIGN (file, 3);
16240 (*targetm.asm_out.internal_label) (file, "LC", labelno);
16242 /* Handle FP constants specially. Note that if we have a minimal
16243 TOC, things we put here aren't actually in the TOC, so we can allow
16244 FP constants. */
16245 if (GET_CODE (x) == CONST_DOUBLE &&
16246 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
16248 REAL_VALUE_TYPE rv;
16249 long k[4];
16251 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16252 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16253 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
16254 else
16255 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
16257 if (TARGET_64BIT)
16259 if (TARGET_MINIMAL_TOC)
16260 fputs (DOUBLE_INT_ASM_OP, file);
16261 else
16262 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16263 k[0] & 0xffffffff, k[1] & 0xffffffff,
16264 k[2] & 0xffffffff, k[3] & 0xffffffff);
16265 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
16266 k[0] & 0xffffffff, k[1] & 0xffffffff,
16267 k[2] & 0xffffffff, k[3] & 0xffffffff);
16268 return;
16270 else
16272 if (TARGET_MINIMAL_TOC)
16273 fputs ("\t.long ", file);
16274 else
16275 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16276 k[0] & 0xffffffff, k[1] & 0xffffffff,
16277 k[2] & 0xffffffff, k[3] & 0xffffffff);
16278 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
16279 k[0] & 0xffffffff, k[1] & 0xffffffff,
16280 k[2] & 0xffffffff, k[3] & 0xffffffff);
16281 return;
16284 else if (GET_CODE (x) == CONST_DOUBLE &&
16285 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
16287 REAL_VALUE_TYPE rv;
16288 long k[2];
16290 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16292 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16293 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
16294 else
16295 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
16297 if (TARGET_64BIT)
16299 if (TARGET_MINIMAL_TOC)
16300 fputs (DOUBLE_INT_ASM_OP, file);
16301 else
16302 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
16303 k[0] & 0xffffffff, k[1] & 0xffffffff);
16304 fprintf (file, "0x%lx%08lx\n",
16305 k[0] & 0xffffffff, k[1] & 0xffffffff);
16306 return;
16308 else
16310 if (TARGET_MINIMAL_TOC)
16311 fputs ("\t.long ", file);
16312 else
16313 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
16314 k[0] & 0xffffffff, k[1] & 0xffffffff);
16315 fprintf (file, "0x%lx,0x%lx\n",
16316 k[0] & 0xffffffff, k[1] & 0xffffffff);
16317 return;
16320 else if (GET_CODE (x) == CONST_DOUBLE &&
16321 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
16323 REAL_VALUE_TYPE rv;
16324 long l;
16326 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
16327 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
16328 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
16329 else
16330 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
16332 if (TARGET_64BIT)
16334 if (TARGET_MINIMAL_TOC)
16335 fputs (DOUBLE_INT_ASM_OP, file);
16336 else
16337 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
16338 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
16339 return;
16341 else
16343 if (TARGET_MINIMAL_TOC)
16344 fputs ("\t.long ", file);
16345 else
16346 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
16347 fprintf (file, "0x%lx\n", l & 0xffffffff);
16348 return;
16351 else if (GET_MODE (x) == VOIDmode
16352 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
16354 unsigned HOST_WIDE_INT low;
16355 HOST_WIDE_INT high;
16357 if (GET_CODE (x) == CONST_DOUBLE)
16359 low = CONST_DOUBLE_LOW (x);
16360 high = CONST_DOUBLE_HIGH (x);
16362 else
16363 #if HOST_BITS_PER_WIDE_INT == 32
16365 low = INTVAL (x);
16366 high = (low & 0x80000000) ? ~0 : 0;
16368 #else
16370 low = INTVAL (x) & 0xffffffff;
16371 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
16373 #endif
16375 /* TOC entries are always Pmode-sized, but since this
16376 is a bigendian machine then if we're putting smaller
16377 integer constants in the TOC we have to pad them.
16378 (This is still a win over putting the constants in
16379 a separate constant pool, because then we'd have
16380 to have both a TOC entry _and_ the actual constant.)
16382 For a 32-bit target, CONST_INT values are loaded and shifted
16383 entirely within `low' and can be stored in one TOC entry. */
16385 /* It would be easy to make this work, but it doesn't now. */
16386 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
16388 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
16390 #if HOST_BITS_PER_WIDE_INT == 32
16391 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
16392 POINTER_SIZE, &low, &high, 0);
16393 #else
16394 low |= high << 32;
16395 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
16396 high = (HOST_WIDE_INT) low >> 32;
16397 low &= 0xffffffff;
16398 #endif
16401 if (TARGET_64BIT)
16403 if (TARGET_MINIMAL_TOC)
16404 fputs (DOUBLE_INT_ASM_OP, file);
16405 else
16406 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
16407 (long) high & 0xffffffff, (long) low & 0xffffffff);
16408 fprintf (file, "0x%lx%08lx\n",
16409 (long) high & 0xffffffff, (long) low & 0xffffffff);
16410 return;
16412 else
16414 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
16416 if (TARGET_MINIMAL_TOC)
16417 fputs ("\t.long ", file);
16418 else
16419 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
16420 (long) high & 0xffffffff, (long) low & 0xffffffff);
16421 fprintf (file, "0x%lx,0x%lx\n",
16422 (long) high & 0xffffffff, (long) low & 0xffffffff);
16424 else
16426 if (TARGET_MINIMAL_TOC)
16427 fputs ("\t.long ", file);
16428 else
16429 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
16430 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
16432 return;
16436 if (GET_CODE (x) == CONST)
16438 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
16440 base = XEXP (XEXP (x, 0), 0);
16441 offset = INTVAL (XEXP (XEXP (x, 0), 1));
16444 switch (GET_CODE (base))
16446 case SYMBOL_REF:
16447 name = XSTR (base, 0);
16448 break;
16450 case LABEL_REF:
16451 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
16452 CODE_LABEL_NUMBER (XEXP (base, 0)));
16453 break;
16455 case CODE_LABEL:
16456 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
16457 break;
16459 default:
16460 gcc_unreachable ();
16463 real_name = (*targetm.strip_name_encoding) (name);
16464 if (TARGET_MINIMAL_TOC)
16465 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
16466 else
16468 fprintf (file, "\t.tc %s", real_name);
16470 if (offset < 0)
16471 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
16472 else if (offset)
16473 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
16475 fputs ("[TC],", file);
16478 /* Currently C++ toc references to vtables can be emitted before it
16479 is decided whether the vtable is public or private. If this is
16480 the case, then the linker will eventually complain that there is
16481 a TOC reference to an unknown section. Thus, for vtables only,
16482 we emit the TOC reference to reference the symbol and not the
16483 section. */
16484 if (VTABLE_NAME_P (name))
16486 RS6000_OUTPUT_BASENAME (file, name);
16487 if (offset < 0)
16488 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
16489 else if (offset > 0)
16490 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
16492 else
16493 output_addr_const (file, x);
16494 putc ('\n', file);
16497 /* Output an assembler pseudo-op to write an ASCII string of N characters
16498 starting at P to FILE.
16500 On the RS/6000, we have to do this using the .byte operation and
16501 write out special characters outside the quoted string.
16502 Also, the assembler is broken; very long strings are truncated,
16503 so we must artificially break them up early. */
16505 void
16506 output_ascii (FILE *file, const char *p, int n)
16508 char c;
16509 int i, count_string;
16510 const char *for_string = "\t.byte \"";
16511 const char *for_decimal = "\t.byte ";
16512 const char *to_close = NULL;
16514 count_string = 0;
16515 for (i = 0; i < n; i++)
16517 c = *p++;
16518 if (c >= ' ' && c < 0177)
16520 if (for_string)
16521 fputs (for_string, file);
16522 putc (c, file);
16524 /* Write two quotes to get one. */
16525 if (c == '"')
16527 putc (c, file);
16528 ++count_string;
16531 for_string = NULL;
16532 for_decimal = "\"\n\t.byte ";
16533 to_close = "\"\n";
16534 ++count_string;
16536 if (count_string >= 512)
16538 fputs (to_close, file);
16540 for_string = "\t.byte \"";
16541 for_decimal = "\t.byte ";
16542 to_close = NULL;
16543 count_string = 0;
16546 else
16548 if (for_decimal)
16549 fputs (for_decimal, file);
16550 fprintf (file, "%d", c);
16552 for_string = "\n\t.byte \"";
16553 for_decimal = ", ";
16554 to_close = "\n";
16555 count_string = 0;
16559 /* Now close the string if we have written one. Then end the line. */
16560 if (to_close)
16561 fputs (to_close, file);
16564 /* Generate a unique section name for FILENAME for a section type
16565 represented by SECTION_DESC. Output goes into BUF.
16567 SECTION_DESC can be any string, as long as it is different for each
16568 possible section type.
16570 We name the section in the same manner as xlc. The name begins with an
16571 underscore followed by the filename (after stripping any leading directory
16572 names) with the last period replaced by the string SECTION_DESC. If
16573 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16574 the name. */
16576 void
16577 rs6000_gen_section_name (char **buf, const char *filename,
16578 const char *section_desc)
16580 const char *q, *after_last_slash, *last_period = 0;
16581 char *p;
16582 int len;
16584 after_last_slash = filename;
16585 for (q = filename; *q; q++)
16587 if (*q == '/')
16588 after_last_slash = q + 1;
16589 else if (*q == '.')
16590 last_period = q;
16593 len = strlen (after_last_slash) + strlen (section_desc) + 2;
16594 *buf = (char *) xmalloc (len);
16596 p = *buf;
16597 *p++ = '_';
16599 for (q = after_last_slash; *q; q++)
16601 if (q == last_period)
16603 strcpy (p, section_desc);
16604 p += strlen (section_desc);
16605 break;
16608 else if (ISALNUM (*q))
16609 *p++ = *q;
16612 if (last_period == 0)
16613 strcpy (p, section_desc);
16614 else
16615 *p = '\0';
16618 /* Emit profile function. */
16620 void
16621 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
16623 /* Non-standard profiling for kernels, which just saves LR then calls
16624 _mcount without worrying about arg saves. The idea is to change
16625 the function prologue as little as possible as it isn't easy to
16626 account for arg save/restore code added just for _mcount. */
16627 if (TARGET_PROFILE_KERNEL)
16628 return;
16630 if (DEFAULT_ABI == ABI_AIX)
16632 #ifndef NO_PROFILE_COUNTERS
16633 # define NO_PROFILE_COUNTERS 0
16634 #endif
16635 if (NO_PROFILE_COUNTERS)
16636 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
16637 else
16639 char buf[30];
16640 const char *label_name;
16641 rtx fun;
16643 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16644 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
16645 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
16647 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
16648 fun, Pmode);
16651 else if (DEFAULT_ABI == ABI_DARWIN)
16653 const char *mcount_name = RS6000_MCOUNT;
16654 int caller_addr_regno = LINK_REGISTER_REGNUM;
16656 /* Be conservative and always set this, at least for now. */
16657 current_function_uses_pic_offset_table = 1;
16659 #if TARGET_MACHO
16660 /* For PIC code, set up a stub and collect the caller's address
16661 from r0, which is where the prologue puts it. */
16662 if (MACHOPIC_INDIRECT
16663 && current_function_uses_pic_offset_table)
16664 caller_addr_regno = 0;
16665 #endif
16666 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
16667 0, VOIDmode, 1,
16668 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
16672 /* Write function profiler code. */
16674 void
16675 output_function_profiler (FILE *file, int labelno)
16677 char buf[100];
16679 switch (DEFAULT_ABI)
16681 default:
16682 gcc_unreachable ();
16684 case ABI_V4:
16685 if (!TARGET_32BIT)
16687 warning (0, "no profiling of 64-bit code for this ABI");
16688 return;
16690 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16691 fprintf (file, "\tmflr %s\n", reg_names[0]);
16692 if (NO_PROFILE_COUNTERS)
16694 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16695 reg_names[0], reg_names[1]);
16697 else if (TARGET_SECURE_PLT && flag_pic)
16699 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16700 reg_names[0], reg_names[1]);
16701 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16702 asm_fprintf (file, "\t{cau|addis} %s,%s,",
16703 reg_names[12], reg_names[12]);
16704 assemble_name (file, buf);
16705 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
16706 assemble_name (file, buf);
16707 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
16709 else if (flag_pic == 1)
16711 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
16712 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16713 reg_names[0], reg_names[1]);
16714 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16715 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
16716 assemble_name (file, buf);
16717 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
16719 else if (flag_pic > 1)
16721 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16722 reg_names[0], reg_names[1]);
16723 /* Now, we need to get the address of the label. */
16724 fputs ("\tbcl 20,31,1f\n\t.long ", file);
16725 assemble_name (file, buf);
16726 fputs ("-.\n1:", file);
16727 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
16728 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
16729 reg_names[0], reg_names[11]);
16730 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
16731 reg_names[0], reg_names[0], reg_names[11]);
16733 else
16735 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
16736 assemble_name (file, buf);
16737 fputs ("@ha\n", file);
16738 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16739 reg_names[0], reg_names[1]);
16740 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
16741 assemble_name (file, buf);
16742 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
16745 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16746 fprintf (file, "\tbl %s%s\n",
16747 RS6000_MCOUNT, flag_pic ? "@plt" : "");
16748 break;
16750 case ABI_AIX:
16751 case ABI_DARWIN:
16752 if (!TARGET_PROFILE_KERNEL)
16754 /* Don't do anything, done in output_profile_hook (). */
16756 else
16758 gcc_assert (!TARGET_32BIT);
16760 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
16761 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
16763 if (cfun->static_chain_decl != NULL)
16765 asm_fprintf (file, "\tstd %s,24(%s)\n",
16766 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16767 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16768 asm_fprintf (file, "\tld %s,24(%s)\n",
16769 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16771 else
16772 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16774 break;
16780 /* The following variable value is the last issued insn. */
16782 static rtx last_scheduled_insn;
16784 /* The following variable helps to balance issuing of load and
16785 store instructions */
16787 static int load_store_pendulum;
16789 /* Power4 load update and store update instructions are cracked into a
16790 load or store and an integer insn which are executed in the same cycle.
16791 Branches have their own dispatch slot which does not count against the
16792 GCC issue rate, but it changes the program flow so there are no other
16793 instructions to issue in this cycle. */
16795 static int
16796 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
16797 int verbose ATTRIBUTE_UNUSED,
16798 rtx insn, int more)
16800 last_scheduled_insn = insn;
16801 if (GET_CODE (PATTERN (insn)) == USE
16802 || GET_CODE (PATTERN (insn)) == CLOBBER)
16804 cached_can_issue_more = more;
16805 return cached_can_issue_more;
16808 if (insn_terminates_group_p (insn, current_group))
16810 cached_can_issue_more = 0;
16811 return cached_can_issue_more;
16814 /* If no reservation, but reach here */
16815 if (recog_memoized (insn) < 0)
16816 return more;
16818 if (rs6000_sched_groups)
16820 if (is_microcoded_insn (insn))
16821 cached_can_issue_more = 0;
16822 else if (is_cracked_insn (insn))
16823 cached_can_issue_more = more > 2 ? more - 2 : 0;
16824 else
16825 cached_can_issue_more = more - 1;
16827 return cached_can_issue_more;
16830 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
16831 return 0;
16833 cached_can_issue_more = more - 1;
16834 return cached_can_issue_more;
16837 /* Adjust the cost of a scheduling dependency. Return the new cost of
16838 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16840 static int
16841 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
16843 enum attr_type attr_type;
16845 if (! recog_memoized (insn))
16846 return 0;
16848 switch (REG_NOTE_KIND (link))
16850 case REG_DEP_TRUE:
16852 /* Data dependency; DEP_INSN writes a register that INSN reads
16853 some cycles later. */
16855 /* Separate a load from a narrower, dependent store. */
16856 if (rs6000_sched_groups
16857 && GET_CODE (PATTERN (insn)) == SET
16858 && GET_CODE (PATTERN (dep_insn)) == SET
16859 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
16860 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
16861 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
16862 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
16863 return cost + 14;
16865 attr_type = get_attr_type (insn);
16867 switch (attr_type)
16869 case TYPE_JMPREG:
16870 /* Tell the first scheduling pass about the latency between
16871 a mtctr and bctr (and mtlr and br/blr). The first
16872 scheduling pass will not know about this latency since
16873 the mtctr instruction, which has the latency associated
16874 to it, will be generated by reload. */
16875 return TARGET_POWER ? 5 : 4;
16876 case TYPE_BRANCH:
16877 /* Leave some extra cycles between a compare and its
16878 dependent branch, to inhibit expensive mispredicts. */
16879 if ((rs6000_cpu_attr == CPU_PPC603
16880 || rs6000_cpu_attr == CPU_PPC604
16881 || rs6000_cpu_attr == CPU_PPC604E
16882 || rs6000_cpu_attr == CPU_PPC620
16883 || rs6000_cpu_attr == CPU_PPC630
16884 || rs6000_cpu_attr == CPU_PPC750
16885 || rs6000_cpu_attr == CPU_PPC7400
16886 || rs6000_cpu_attr == CPU_PPC7450
16887 || rs6000_cpu_attr == CPU_POWER4
16888 || rs6000_cpu_attr == CPU_POWER5
16889 || rs6000_cpu_attr == CPU_CELL)
16890 && recog_memoized (dep_insn)
16891 && (INSN_CODE (dep_insn) >= 0))
16893 switch (get_attr_type (dep_insn))
16895 case TYPE_CMP:
16896 case TYPE_COMPARE:
16897 case TYPE_DELAYED_COMPARE:
16898 case TYPE_IMUL_COMPARE:
16899 case TYPE_LMUL_COMPARE:
16900 case TYPE_FPCOMPARE:
16901 case TYPE_CR_LOGICAL:
16902 case TYPE_DELAYED_CR:
16903 return cost + 2;
16904 default:
16905 break;
16907 break;
16909 case TYPE_STORE:
16910 case TYPE_STORE_U:
16911 case TYPE_STORE_UX:
16912 case TYPE_FPSTORE:
16913 case TYPE_FPSTORE_U:
16914 case TYPE_FPSTORE_UX:
16915 if ((rs6000_cpu == PROCESSOR_POWER6)
16916 && recog_memoized (dep_insn)
16917 && (INSN_CODE (dep_insn) >= 0))
16920 if (GET_CODE (PATTERN (insn)) != SET)
16921 /* If this happens, we have to extend this to schedule
16922 optimally. Return default for now. */
16923 return cost;
16925 /* Adjust the cost for the case where the value written
16926 by a fixed point operation is used as the address
16927 gen value on a store. */
16928 switch (get_attr_type (dep_insn))
16930 case TYPE_LOAD:
16931 case TYPE_LOAD_U:
16932 case TYPE_LOAD_UX:
16933 case TYPE_CNTLZ:
16935 if (! store_data_bypass_p (dep_insn, insn))
16936 return 4;
16937 break;
16939 case TYPE_LOAD_EXT:
16940 case TYPE_LOAD_EXT_U:
16941 case TYPE_LOAD_EXT_UX:
16942 case TYPE_VAR_SHIFT_ROTATE:
16943 case TYPE_VAR_DELAYED_COMPARE:
16945 if (! store_data_bypass_p (dep_insn, insn))
16946 return 6;
16947 break;
16949 case TYPE_INTEGER:
16950 case TYPE_COMPARE:
16951 case TYPE_FAST_COMPARE:
16952 case TYPE_EXTS:
16953 case TYPE_SHIFT:
16954 case TYPE_INSERT_WORD:
16955 case TYPE_INSERT_DWORD:
16956 case TYPE_FPLOAD_U:
16957 case TYPE_FPLOAD_UX:
16958 case TYPE_STORE_U:
16959 case TYPE_STORE_UX:
16960 case TYPE_FPSTORE_U:
16961 case TYPE_FPSTORE_UX:
16963 if (! store_data_bypass_p (dep_insn, insn))
16964 return 3;
16965 break;
16967 case TYPE_IMUL:
16968 case TYPE_IMUL2:
16969 case TYPE_IMUL3:
16970 case TYPE_LMUL:
16971 case TYPE_IMUL_COMPARE:
16972 case TYPE_LMUL_COMPARE:
16974 if (! store_data_bypass_p (dep_insn, insn))
16975 return 17;
16976 break;
16978 case TYPE_IDIV:
16980 if (! store_data_bypass_p (dep_insn, insn))
16981 return 45;
16982 break;
16984 case TYPE_LDIV:
16986 if (! store_data_bypass_p (dep_insn, insn))
16987 return 57;
16988 break;
16990 default:
16991 break;
16994 break;
16996 case TYPE_LOAD:
16997 case TYPE_LOAD_U:
16998 case TYPE_LOAD_UX:
16999 case TYPE_LOAD_EXT:
17000 case TYPE_LOAD_EXT_U:
17001 case TYPE_LOAD_EXT_UX:
17002 if ((rs6000_cpu == PROCESSOR_POWER6)
17003 && recog_memoized (dep_insn)
17004 && (INSN_CODE (dep_insn) >= 0))
17007 /* Adjust the cost for the case where the value written
17008 by a fixed point instruction is used within the address
17009 gen portion of a subsequent load(u)(x) */
17010 switch (get_attr_type (dep_insn))
17012 case TYPE_LOAD:
17013 case TYPE_LOAD_U:
17014 case TYPE_LOAD_UX:
17015 case TYPE_CNTLZ:
17017 if (set_to_load_agen (dep_insn, insn))
17018 return 4;
17019 break;
17021 case TYPE_LOAD_EXT:
17022 case TYPE_LOAD_EXT_U:
17023 case TYPE_LOAD_EXT_UX:
17024 case TYPE_VAR_SHIFT_ROTATE:
17025 case TYPE_VAR_DELAYED_COMPARE:
17027 if (set_to_load_agen (dep_insn, insn))
17028 return 6;
17029 break;
17031 case TYPE_INTEGER:
17032 case TYPE_COMPARE:
17033 case TYPE_FAST_COMPARE:
17034 case TYPE_EXTS:
17035 case TYPE_SHIFT:
17036 case TYPE_INSERT_WORD:
17037 case TYPE_INSERT_DWORD:
17038 case TYPE_FPLOAD_U:
17039 case TYPE_FPLOAD_UX:
17040 case TYPE_STORE_U:
17041 case TYPE_STORE_UX:
17042 case TYPE_FPSTORE_U:
17043 case TYPE_FPSTORE_UX:
17045 if (set_to_load_agen (dep_insn, insn))
17046 return 3;
17047 break;
17049 case TYPE_IMUL:
17050 case TYPE_IMUL2:
17051 case TYPE_IMUL3:
17052 case TYPE_LMUL:
17053 case TYPE_IMUL_COMPARE:
17054 case TYPE_LMUL_COMPARE:
17056 if (set_to_load_agen (dep_insn, insn))
17057 return 17;
17058 break;
17060 case TYPE_IDIV:
17062 if (set_to_load_agen (dep_insn, insn))
17063 return 45;
17064 break;
17066 case TYPE_LDIV:
17068 if (set_to_load_agen (dep_insn, insn))
17069 return 57;
17070 break;
17072 default:
17073 break;
17076 break;
17078 case TYPE_FPLOAD:
17079 if ((rs6000_cpu == PROCESSOR_POWER6)
17080 && recog_memoized (dep_insn)
17081 && (INSN_CODE (dep_insn) >= 0)
17082 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
17083 return 2;
17085 default:
17086 break;
17089 /* Fall out to return default cost. */
17091 break;
17093 case REG_DEP_OUTPUT:
17094 /* Output dependency; DEP_INSN writes a register that INSN writes some
17095 cycles later. */
17096 if ((rs6000_cpu == PROCESSOR_POWER6)
17097 && recog_memoized (dep_insn)
17098 && (INSN_CODE (dep_insn) >= 0))
17100 attr_type = get_attr_type (insn);
17102 switch (attr_type)
17104 case TYPE_FP:
17105 if (get_attr_type (dep_insn) == TYPE_FP)
17106 return 1;
17107 break;
17108 case TYPE_FPLOAD:
17109 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
17110 return 2;
17111 break;
17112 default:
17113 break;
17116 case REG_DEP_ANTI:
17117 /* Anti dependency; DEP_INSN reads a register that INSN writes some
17118 cycles later. */
17119 return 0;
17121 default:
17122 gcc_unreachable ();
17125 return cost;
17128 /* The function returns a true if INSN is microcoded.
17129 Return false otherwise. */
17131 static bool
17132 is_microcoded_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_cpu_attr == CPU_CELL)
17140 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
17142 if (rs6000_sched_groups)
17144 enum attr_type type = get_attr_type (insn);
17145 if (type == TYPE_LOAD_EXT_U
17146 || type == TYPE_LOAD_EXT_UX
17147 || type == TYPE_LOAD_UX
17148 || type == TYPE_STORE_UX
17149 || type == TYPE_MFCR)
17150 return true;
17153 return false;
17156 /* The function returns true if INSN is cracked into 2 instructions
17157 by the processor (and therefore occupies 2 issue slots). */
17159 static bool
17160 is_cracked_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_LOAD_U || type == TYPE_STORE_U
17171 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
17172 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
17173 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
17174 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
17175 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
17176 || type == TYPE_IDIV || type == TYPE_LDIV
17177 || type == TYPE_INSERT_WORD)
17178 return true;
17181 return false;
17184 /* The function returns true if INSN can be issued only from
17185 the branch slot. */
17187 static bool
17188 is_branch_slot_insn (rtx insn)
17190 if (!insn || !INSN_P (insn)
17191 || GET_CODE (PATTERN (insn)) == USE
17192 || GET_CODE (PATTERN (insn)) == CLOBBER)
17193 return false;
17195 if (rs6000_sched_groups)
17197 enum attr_type type = get_attr_type (insn);
17198 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
17199 return true;
17200 return false;
17203 return false;
17206 /* The function returns true if out_inst sets a value that is
17207 used in the address generation computation of in_insn */
17208 static bool
17209 set_to_load_agen (rtx out_insn, rtx in_insn)
17211 rtx out_set, in_set;
17213 /* For performance reasons, only handle the simple case where
17214 both loads are a single_set. */
17215 out_set = single_set (out_insn);
17216 if (out_set)
17218 in_set = single_set (in_insn);
17219 if (in_set)
17220 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
17223 return false;
17226 /* The function returns true if the target storage location of
17227 out_insn is adjacent to the target storage location of in_insn */
17228 /* Return 1 if memory locations are adjacent. */
17230 static bool
17231 adjacent_mem_locations (rtx insn1, rtx insn2)
17234 rtx a = get_store_dest (PATTERN (insn1));
17235 rtx b = get_store_dest (PATTERN (insn2));
17237 if ((GET_CODE (XEXP (a, 0)) == REG
17238 || (GET_CODE (XEXP (a, 0)) == PLUS
17239 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
17240 && (GET_CODE (XEXP (b, 0)) == REG
17241 || (GET_CODE (XEXP (b, 0)) == PLUS
17242 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
17244 HOST_WIDE_INT val0 = 0, val1 = 0;
17245 rtx reg0, reg1;
17246 int val_diff;
17248 if (GET_CODE (XEXP (a, 0)) == PLUS)
17250 reg0 = XEXP (XEXP (a, 0), 0);
17251 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
17253 else
17254 reg0 = XEXP (a, 0);
17256 if (GET_CODE (XEXP (b, 0)) == PLUS)
17258 reg1 = XEXP (XEXP (b, 0), 0);
17259 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
17261 else
17262 reg1 = XEXP (b, 0);
17264 val_diff = val1 - val0;
17266 return ((REGNO (reg0) == REGNO (reg1))
17267 && (val_diff == INTVAL (MEM_SIZE (a))
17268 || val_diff == -INTVAL (MEM_SIZE (b))));
17271 return false;
17274 /* A C statement (sans semicolon) to update the integer scheduling
17275 priority INSN_PRIORITY (INSN). Increase the priority to execute the
17276 INSN earlier, reduce the priority to execute INSN later. Do not
17277 define this macro if you do not need to adjust the scheduling
17278 priorities of insns. */
17280 static int
17281 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
17283 /* On machines (like the 750) which have asymmetric integer units,
17284 where one integer unit can do multiply and divides and the other
17285 can't, reduce the priority of multiply/divide so it is scheduled
17286 before other integer operations. */
17288 #if 0
17289 if (! INSN_P (insn))
17290 return priority;
17292 if (GET_CODE (PATTERN (insn)) == USE)
17293 return priority;
17295 switch (rs6000_cpu_attr) {
17296 case CPU_PPC750:
17297 switch (get_attr_type (insn))
17299 default:
17300 break;
17302 case TYPE_IMUL:
17303 case TYPE_IDIV:
17304 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
17305 priority, priority);
17306 if (priority >= 0 && priority < 0x01000000)
17307 priority >>= 3;
17308 break;
17311 #endif
17313 if (insn_must_be_first_in_group (insn)
17314 && reload_completed
17315 && current_sched_info->sched_max_insns_priority
17316 && rs6000_sched_restricted_insns_priority)
17319 /* Prioritize insns that can be dispatched only in the first
17320 dispatch slot. */
17321 if (rs6000_sched_restricted_insns_priority == 1)
17322 /* Attach highest priority to insn. This means that in
17323 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
17324 precede 'priority' (critical path) considerations. */
17325 return current_sched_info->sched_max_insns_priority;
17326 else if (rs6000_sched_restricted_insns_priority == 2)
17327 /* Increase priority of insn by a minimal amount. This means that in
17328 haifa-sched.c:ready_sort(), only 'priority' (critical path)
17329 considerations precede dispatch-slot restriction considerations. */
17330 return (priority + 1);
17333 if (rs6000_cpu == PROCESSOR_POWER6
17334 && ((load_store_pendulum == -2 && is_load_insn (insn))
17335 || (load_store_pendulum == 2 && is_store_insn (insn))))
17336 /* Attach highest priority to insn if the scheduler has just issued two
17337 stores and this instruction is a load, or two loads and this instruction
17338 is a store. Power6 wants loads and stores scheduled alternately
17339 when possible */
17340 return current_sched_info->sched_max_insns_priority;
17342 return priority;
17345 /* Return true if the instruction is nonpipelined on the Cell. */
17346 static bool
17347 is_nonpipeline_insn (rtx insn)
17349 enum attr_type type;
17350 if (!insn || !INSN_P (insn)
17351 || GET_CODE (PATTERN (insn)) == USE
17352 || GET_CODE (PATTERN (insn)) == CLOBBER)
17353 return false;
17355 type = get_attr_type (insn);
17356 if (type == TYPE_IMUL
17357 || type == TYPE_IMUL2
17358 || type == TYPE_IMUL3
17359 || type == TYPE_LMUL
17360 || type == TYPE_IDIV
17361 || type == TYPE_LDIV
17362 || type == TYPE_SDIV
17363 || type == TYPE_DDIV
17364 || type == TYPE_SSQRT
17365 || type == TYPE_DSQRT
17366 || type == TYPE_MFCR
17367 || type == TYPE_MFCRF
17368 || type == TYPE_MFJMPR)
17370 return true;
17372 return false;
17376 /* Return how many instructions the machine can issue per cycle. */
17378 static int
17379 rs6000_issue_rate (void)
17381 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
17382 if (!reload_completed)
17383 return 1;
17385 switch (rs6000_cpu_attr) {
17386 case CPU_RIOS1: /* ? */
17387 case CPU_RS64A:
17388 case CPU_PPC601: /* ? */
17389 case CPU_PPC7450:
17390 return 3;
17391 case CPU_PPC440:
17392 case CPU_PPC603:
17393 case CPU_PPC750:
17394 case CPU_PPC7400:
17395 case CPU_PPC8540:
17396 case CPU_CELL:
17397 return 2;
17398 case CPU_RIOS2:
17399 case CPU_PPC604:
17400 case CPU_PPC604E:
17401 case CPU_PPC620:
17402 case CPU_PPC630:
17403 return 4;
17404 case CPU_POWER4:
17405 case CPU_POWER5:
17406 case CPU_POWER6:
17407 return 5;
17408 default:
17409 return 1;
17413 /* Return how many instructions to look ahead for better insn
17414 scheduling. */
17416 static int
17417 rs6000_use_sched_lookahead (void)
17419 if (rs6000_cpu_attr == CPU_PPC8540)
17420 return 4;
17421 if (rs6000_cpu_attr == CPU_CELL)
17422 return (reload_completed ? 8 : 0);
17423 return 0;
17426 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
17427 static int
17428 rs6000_use_sched_lookahead_guard (rtx insn)
17430 if (rs6000_cpu_attr != CPU_CELL)
17431 return 1;
17433 if (insn == NULL_RTX || !INSN_P (insn))
17434 abort ();
17436 if (!reload_completed
17437 || is_nonpipeline_insn (insn)
17438 || is_microcoded_insn (insn))
17439 return 0;
17441 return 1;
17444 /* Determine is PAT refers to memory. */
17446 static bool
17447 is_mem_ref (rtx pat)
17449 const char * fmt;
17450 int i, j;
17451 bool ret = false;
17453 if (GET_CODE (pat) == MEM)
17454 return true;
17456 /* Recursively process the pattern. */
17457 fmt = GET_RTX_FORMAT (GET_CODE (pat));
17459 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
17461 if (fmt[i] == 'e')
17462 ret |= is_mem_ref (XEXP (pat, i));
17463 else if (fmt[i] == 'E')
17464 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
17465 ret |= is_mem_ref (XVECEXP (pat, i, j));
17468 return ret;
17471 /* Determine if PAT is a PATTERN of a load insn. */
17473 static bool
17474 is_load_insn1 (rtx pat)
17476 if (!pat || pat == NULL_RTX)
17477 return false;
17479 if (GET_CODE (pat) == SET)
17480 return is_mem_ref (SET_SRC (pat));
17482 if (GET_CODE (pat) == PARALLEL)
17484 int i;
17486 for (i = 0; i < XVECLEN (pat, 0); i++)
17487 if (is_load_insn1 (XVECEXP (pat, 0, i)))
17488 return true;
17491 return false;
17494 /* Determine if INSN loads from memory. */
17496 static bool
17497 is_load_insn (rtx insn)
17499 if (!insn || !INSN_P (insn))
17500 return false;
17502 if (GET_CODE (insn) == CALL_INSN)
17503 return false;
17505 return is_load_insn1 (PATTERN (insn));
17508 /* Determine if PAT is a PATTERN of a store insn. */
17510 static bool
17511 is_store_insn1 (rtx pat)
17513 if (!pat || pat == NULL_RTX)
17514 return false;
17516 if (GET_CODE (pat) == SET)
17517 return is_mem_ref (SET_DEST (pat));
17519 if (GET_CODE (pat) == PARALLEL)
17521 int i;
17523 for (i = 0; i < XVECLEN (pat, 0); i++)
17524 if (is_store_insn1 (XVECEXP (pat, 0, i)))
17525 return true;
17528 return false;
17531 /* Determine if INSN stores to memory. */
17533 static bool
17534 is_store_insn (rtx insn)
17536 if (!insn || !INSN_P (insn))
17537 return false;
17539 return is_store_insn1 (PATTERN (insn));
17542 /* Return the dest of a store insn. */
17544 static rtx
17545 get_store_dest (rtx pat)
17547 gcc_assert (is_store_insn1 (pat));
17549 if (GET_CODE (pat) == SET)
17550 return SET_DEST (pat);
17551 else if (GET_CODE (pat) == PARALLEL)
17553 int i;
17555 for (i = 0; i < XVECLEN (pat, 0); i++)
17557 rtx inner_pat = XVECEXP (pat, 0, i);
17558 if (GET_CODE (inner_pat) == SET
17559 && is_mem_ref (SET_DEST (inner_pat)))
17560 return inner_pat;
17563 /* We shouldn't get here, because we should have either a simple
17564 store insn or a store with update which are covered above. */
17565 gcc_unreachable();
17568 /* Returns whether the dependence between INSN and NEXT is considered
17569 costly by the given target. */
17571 static bool
17572 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
17574 rtx insn;
17575 rtx next;
17577 /* If the flag is not enabled - no dependence is considered costly;
17578 allow all dependent insns in the same group.
17579 This is the most aggressive option. */
17580 if (rs6000_sched_costly_dep == no_dep_costly)
17581 return false;
17583 /* If the flag is set to 1 - a dependence is always considered costly;
17584 do not allow dependent instructions in the same group.
17585 This is the most conservative option. */
17586 if (rs6000_sched_costly_dep == all_deps_costly)
17587 return true;
17589 insn = DEP_PRO (dep);
17590 next = DEP_CON (dep);
17592 if (rs6000_sched_costly_dep == store_to_load_dep_costly
17593 && is_load_insn (next)
17594 && is_store_insn (insn))
17595 /* Prevent load after store in the same group. */
17596 return true;
17598 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
17599 && is_load_insn (next)
17600 && is_store_insn (insn)
17601 && DEP_KIND (dep) == REG_DEP_TRUE)
17602 /* Prevent load after store in the same group if it is a true
17603 dependence. */
17604 return true;
17606 /* The flag is set to X; dependences with latency >= X are considered costly,
17607 and will not be scheduled in the same group. */
17608 if (rs6000_sched_costly_dep <= max_dep_latency
17609 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
17610 return true;
17612 return false;
17615 /* Return the next insn after INSN that is found before TAIL is reached,
17616 skipping any "non-active" insns - insns that will not actually occupy
17617 an issue slot. Return NULL_RTX if such an insn is not found. */
17619 static rtx
17620 get_next_active_insn (rtx insn, rtx tail)
17622 if (insn == NULL_RTX || insn == tail)
17623 return NULL_RTX;
17625 while (1)
17627 insn = NEXT_INSN (insn);
17628 if (insn == NULL_RTX || insn == tail)
17629 return NULL_RTX;
17631 if (CALL_P (insn)
17632 || JUMP_P (insn)
17633 || (NONJUMP_INSN_P (insn)
17634 && GET_CODE (PATTERN (insn)) != USE
17635 && GET_CODE (PATTERN (insn)) != CLOBBER
17636 && INSN_CODE (insn) != CODE_FOR_stack_tie))
17637 break;
17639 return insn;
17642 /* We are about to begin issuing insns for this clock cycle. */
17644 static int
17645 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
17646 rtx *ready ATTRIBUTE_UNUSED,
17647 int *pn_ready ATTRIBUTE_UNUSED,
17648 int clock_var ATTRIBUTE_UNUSED)
17650 int n_ready = *pn_ready;
17652 if (sched_verbose)
17653 fprintf (dump, "// rs6000_sched_reorder :\n");
17655 /* Reorder the ready list, if the second to last ready insn
17656 is a nonepipeline insn. */
17657 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
17659 if (is_nonpipeline_insn (ready[n_ready - 1])
17660 && (recog_memoized (ready[n_ready - 2]) > 0))
17661 /* Simply swap first two insns. */
17663 rtx tmp = ready[n_ready - 1];
17664 ready[n_ready - 1] = ready[n_ready - 2];
17665 ready[n_ready - 2] = tmp;
17669 if (rs6000_cpu == PROCESSOR_POWER6)
17670 load_store_pendulum = 0;
17672 return rs6000_issue_rate ();
17675 /* Like rs6000_sched_reorder, but called after issuing each insn. */
17677 static int
17678 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
17679 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
17681 if (sched_verbose)
17682 fprintf (dump, "// rs6000_sched_reorder2 :\n");
17684 /* For Power6, we need to handle some special cases to try and keep the
17685 store queue from overflowing and triggering expensive flushes.
17687 This code monitors how load and store instructions are being issued
17688 and skews the ready list one way or the other to increase the likelihood
17689 that a desired instruction is issued at the proper time.
17691 A couple of things are done. First, we maintain a "load_store_pendulum"
17692 to track the current state of load/store issue.
17694 - If the pendulum is at zero, then no loads or stores have been
17695 issued in the current cycle so we do nothing.
17697 - If the pendulum is 1, then a single load has been issued in this
17698 cycle and we attempt to locate another load in the ready list to
17699 issue with it.
17701 - If the pendulum is -2, then two stores have already been
17702 issued in this cycle, so we increase the priority of the first load
17703 in the ready list to increase it's likelihood of being chosen first
17704 in the next cycle.
17706 - If the pendulum is -1, then a single store has been issued in this
17707 cycle and we attempt to locate another store in the ready list to
17708 issue with it, preferring a store to an adjacent memory location to
17709 facilitate store pairing in the store queue.
17711 - If the pendulum is 2, then two loads have already been
17712 issued in this cycle, so we increase the priority of the first store
17713 in the ready list to increase it's likelihood of being chosen first
17714 in the next cycle.
17716 - If the pendulum < -2 or > 2, then do nothing.
17718 Note: This code covers the most common scenarios. There exist non
17719 load/store instructions which make use of the LSU and which
17720 would need to be accounted for to strictly model the behavior
17721 of the machine. Those instructions are currently unaccounted
17722 for to help minimize compile time overhead of this code.
17724 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
17726 int pos;
17727 int i;
17728 rtx tmp;
17730 if (is_store_insn (last_scheduled_insn))
17731 /* Issuing a store, swing the load_store_pendulum to the left */
17732 load_store_pendulum--;
17733 else if (is_load_insn (last_scheduled_insn))
17734 /* Issuing a load, swing the load_store_pendulum to the right */
17735 load_store_pendulum++;
17736 else
17737 return cached_can_issue_more;
17739 /* If the pendulum is balanced, or there is only one instruction on
17740 the ready list, then all is well, so return. */
17741 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
17742 return cached_can_issue_more;
17744 if (load_store_pendulum == 1)
17746 /* A load has been issued in this cycle. Scan the ready list
17747 for another load to issue with it */
17748 pos = *pn_ready-1;
17750 while (pos >= 0)
17752 if (is_load_insn (ready[pos]))
17754 /* Found a load. Move it to the head of the ready list,
17755 and adjust it's priority so that it is more likely to
17756 stay there */
17757 tmp = ready[pos];
17758 for (i=pos; i<*pn_ready-1; i++)
17759 ready[i] = ready[i + 1];
17760 ready[*pn_ready-1] = tmp;
17761 if INSN_PRIORITY_KNOWN (tmp)
17762 INSN_PRIORITY (tmp)++;
17763 break;
17765 pos--;
17768 else if (load_store_pendulum == -2)
17770 /* Two stores have been issued in this cycle. Increase the
17771 priority of the first load in the ready list to favor it for
17772 issuing in the next cycle. */
17773 pos = *pn_ready-1;
17775 while (pos >= 0)
17777 if (is_load_insn (ready[pos])
17778 && INSN_PRIORITY_KNOWN (ready[pos]))
17780 INSN_PRIORITY (ready[pos])++;
17782 /* Adjust the pendulum to account for the fact that a load
17783 was found and increased in priority. This is to prevent
17784 increasing the priority of multiple loads */
17785 load_store_pendulum--;
17787 break;
17789 pos--;
17792 else if (load_store_pendulum == -1)
17794 /* A store has been issued in this cycle. Scan the ready list for
17795 another store to issue with it, preferring a store to an adjacent
17796 memory location */
17797 int first_store_pos = -1;
17799 pos = *pn_ready-1;
17801 while (pos >= 0)
17803 if (is_store_insn (ready[pos]))
17805 /* Maintain the index of the first store found on the
17806 list */
17807 if (first_store_pos == -1)
17808 first_store_pos = pos;
17810 if (is_store_insn (last_scheduled_insn)
17811 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
17813 /* Found an adjacent store. Move it to the head of the
17814 ready list, and adjust it's priority so that it is
17815 more likely to stay there */
17816 tmp = ready[pos];
17817 for (i=pos; i<*pn_ready-1; i++)
17818 ready[i] = ready[i + 1];
17819 ready[*pn_ready-1] = tmp;
17820 if INSN_PRIORITY_KNOWN (tmp)
17821 INSN_PRIORITY (tmp)++;
17822 first_store_pos = -1;
17824 break;
17827 pos--;
17830 if (first_store_pos >= 0)
17832 /* An adjacent store wasn't found, but a non-adjacent store was,
17833 so move the non-adjacent store to the front of the ready
17834 list, and adjust its priority so that it is more likely to
17835 stay there. */
17836 tmp = ready[first_store_pos];
17837 for (i=first_store_pos; i<*pn_ready-1; i++)
17838 ready[i] = ready[i + 1];
17839 ready[*pn_ready-1] = tmp;
17840 if INSN_PRIORITY_KNOWN (tmp)
17841 INSN_PRIORITY (tmp)++;
17844 else if (load_store_pendulum == 2)
17846 /* Two loads have been issued in this cycle. Increase the priority
17847 of the first store in the ready list to favor it for issuing in
17848 the next cycle. */
17849 pos = *pn_ready-1;
17851 while (pos >= 0)
17853 if (is_store_insn (ready[pos])
17854 && INSN_PRIORITY_KNOWN (ready[pos]))
17856 INSN_PRIORITY (ready[pos])++;
17858 /* Adjust the pendulum to account for the fact that a store
17859 was found and increased in priority. This is to prevent
17860 increasing the priority of multiple stores */
17861 load_store_pendulum++;
17863 break;
17865 pos--;
17870 return cached_can_issue_more;
17873 /* Return whether the presence of INSN causes a dispatch group termination
17874 of group WHICH_GROUP.
17876 If WHICH_GROUP == current_group, this function will return true if INSN
17877 causes the termination of the current group (i.e, the dispatch group to
17878 which INSN belongs). This means that INSN will be the last insn in the
17879 group it belongs to.
17881 If WHICH_GROUP == previous_group, this function will return true if INSN
17882 causes the termination of the previous group (i.e, the dispatch group that
17883 precedes the group to which INSN belongs). This means that INSN will be
17884 the first insn in the group it belongs to). */
17886 static bool
17887 insn_terminates_group_p (rtx insn, enum group_termination which_group)
17889 bool first, last;
17891 if (! insn)
17892 return false;
17894 first = insn_must_be_first_in_group (insn);
17895 last = insn_must_be_last_in_group (insn);
17897 if (first && last)
17898 return true;
17900 if (which_group == current_group)
17901 return last;
17902 else if (which_group == previous_group)
17903 return first;
17905 return false;
17909 static bool
17910 insn_must_be_first_in_group (rtx insn)
17912 enum attr_type type;
17914 if (!insn
17915 || insn == NULL_RTX
17916 || GET_CODE (insn) == NOTE
17917 || GET_CODE (PATTERN (insn)) == USE
17918 || GET_CODE (PATTERN (insn)) == CLOBBER)
17919 return false;
17921 switch (rs6000_cpu)
17923 case PROCESSOR_POWER5:
17924 if (is_cracked_insn (insn))
17925 return true;
17926 case PROCESSOR_POWER4:
17927 if (is_microcoded_insn (insn))
17928 return true;
17930 if (!rs6000_sched_groups)
17931 return false;
17933 type = get_attr_type (insn);
17935 switch (type)
17937 case TYPE_MFCR:
17938 case TYPE_MFCRF:
17939 case TYPE_MTCR:
17940 case TYPE_DELAYED_CR:
17941 case TYPE_CR_LOGICAL:
17942 case TYPE_MTJMPR:
17943 case TYPE_MFJMPR:
17944 case TYPE_IDIV:
17945 case TYPE_LDIV:
17946 case TYPE_LOAD_L:
17947 case TYPE_STORE_C:
17948 case TYPE_ISYNC:
17949 case TYPE_SYNC:
17950 return true;
17951 default:
17952 break;
17954 break;
17955 case PROCESSOR_POWER6:
17956 type = get_attr_type (insn);
17958 switch (type)
17960 case TYPE_INSERT_DWORD:
17961 case TYPE_EXTS:
17962 case TYPE_CNTLZ:
17963 case TYPE_SHIFT:
17964 case TYPE_VAR_SHIFT_ROTATE:
17965 case TYPE_TRAP:
17966 case TYPE_IMUL:
17967 case TYPE_IMUL2:
17968 case TYPE_IMUL3:
17969 case TYPE_LMUL:
17970 case TYPE_IDIV:
17971 case TYPE_INSERT_WORD:
17972 case TYPE_DELAYED_COMPARE:
17973 case TYPE_IMUL_COMPARE:
17974 case TYPE_LMUL_COMPARE:
17975 case TYPE_FPCOMPARE:
17976 case TYPE_MFCR:
17977 case TYPE_MTCR:
17978 case TYPE_MFJMPR:
17979 case TYPE_MTJMPR:
17980 case TYPE_ISYNC:
17981 case TYPE_SYNC:
17982 case TYPE_LOAD_L:
17983 case TYPE_STORE_C:
17984 case TYPE_LOAD_U:
17985 case TYPE_LOAD_UX:
17986 case TYPE_LOAD_EXT_UX:
17987 case TYPE_STORE_U:
17988 case TYPE_STORE_UX:
17989 case TYPE_FPLOAD_U:
17990 case TYPE_FPLOAD_UX:
17991 case TYPE_FPSTORE_U:
17992 case TYPE_FPSTORE_UX:
17993 return true;
17994 default:
17995 break;
17997 break;
17998 default:
17999 break;
18002 return false;
18005 static bool
18006 insn_must_be_last_in_group (rtx insn)
18008 enum attr_type type;
18010 if (!insn
18011 || insn == NULL_RTX
18012 || GET_CODE (insn) == NOTE
18013 || GET_CODE (PATTERN (insn)) == USE
18014 || GET_CODE (PATTERN (insn)) == CLOBBER)
18015 return false;
18017 switch (rs6000_cpu) {
18018 case PROCESSOR_POWER4:
18019 case PROCESSOR_POWER5:
18020 if (is_microcoded_insn (insn))
18021 return true;
18023 if (is_branch_slot_insn (insn))
18024 return true;
18026 break;
18027 case PROCESSOR_POWER6:
18028 type = get_attr_type (insn);
18030 switch (type)
18032 case TYPE_EXTS:
18033 case TYPE_CNTLZ:
18034 case TYPE_SHIFT:
18035 case TYPE_VAR_SHIFT_ROTATE:
18036 case TYPE_TRAP:
18037 case TYPE_IMUL:
18038 case TYPE_IMUL2:
18039 case TYPE_IMUL3:
18040 case TYPE_LMUL:
18041 case TYPE_IDIV:
18042 case TYPE_DELAYED_COMPARE:
18043 case TYPE_IMUL_COMPARE:
18044 case TYPE_LMUL_COMPARE:
18045 case TYPE_FPCOMPARE:
18046 case TYPE_MFCR:
18047 case TYPE_MTCR:
18048 case TYPE_MFJMPR:
18049 case TYPE_MTJMPR:
18050 case TYPE_ISYNC:
18051 case TYPE_SYNC:
18052 case TYPE_LOAD_L:
18053 case TYPE_STORE_C:
18054 return true;
18055 default:
18056 break;
18058 break;
18059 default:
18060 break;
18063 return false;
18066 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
18067 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
18069 static bool
18070 is_costly_group (rtx *group_insns, rtx next_insn)
18072 int i;
18073 int issue_rate = rs6000_issue_rate ();
18075 for (i = 0; i < issue_rate; i++)
18077 dep_link_t link;
18078 rtx insn = group_insns[i];
18080 if (!insn)
18081 continue;
18083 FOR_EACH_DEP_LINK (link, INSN_FORW_DEPS (insn))
18085 dep_t dep = DEP_LINK_DEP (link);
18086 rtx next = DEP_CON (dep);
18088 if (next == next_insn
18089 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
18090 return true;
18094 return false;
18097 /* Utility of the function redefine_groups.
18098 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
18099 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
18100 to keep it "far" (in a separate group) from GROUP_INSNS, following
18101 one of the following schemes, depending on the value of the flag
18102 -minsert_sched_nops = X:
18103 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
18104 in order to force NEXT_INSN into a separate group.
18105 (2) X < sched_finish_regroup_exact: insert exactly X nops.
18106 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
18107 insertion (has a group just ended, how many vacant issue slots remain in the
18108 last group, and how many dispatch groups were encountered so far). */
18110 static int
18111 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
18112 rtx next_insn, bool *group_end, int can_issue_more,
18113 int *group_count)
18115 rtx nop;
18116 bool force;
18117 int issue_rate = rs6000_issue_rate ();
18118 bool end = *group_end;
18119 int i;
18121 if (next_insn == NULL_RTX)
18122 return can_issue_more;
18124 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
18125 return can_issue_more;
18127 force = is_costly_group (group_insns, next_insn);
18128 if (!force)
18129 return can_issue_more;
18131 if (sched_verbose > 6)
18132 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
18133 *group_count ,can_issue_more);
18135 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
18137 if (*group_end)
18138 can_issue_more = 0;
18140 /* Since only a branch can be issued in the last issue_slot, it is
18141 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
18142 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
18143 in this case the last nop will start a new group and the branch
18144 will be forced to the new group. */
18145 if (can_issue_more && !is_branch_slot_insn (next_insn))
18146 can_issue_more--;
18148 while (can_issue_more > 0)
18150 nop = gen_nop ();
18151 emit_insn_before (nop, next_insn);
18152 can_issue_more--;
18155 *group_end = true;
18156 return 0;
18159 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
18161 int n_nops = rs6000_sched_insert_nops;
18163 /* Nops can't be issued from the branch slot, so the effective
18164 issue_rate for nops is 'issue_rate - 1'. */
18165 if (can_issue_more == 0)
18166 can_issue_more = issue_rate;
18167 can_issue_more--;
18168 if (can_issue_more == 0)
18170 can_issue_more = issue_rate - 1;
18171 (*group_count)++;
18172 end = true;
18173 for (i = 0; i < issue_rate; i++)
18175 group_insns[i] = 0;
18179 while (n_nops > 0)
18181 nop = gen_nop ();
18182 emit_insn_before (nop, next_insn);
18183 if (can_issue_more == issue_rate - 1) /* new group begins */
18184 end = false;
18185 can_issue_more--;
18186 if (can_issue_more == 0)
18188 can_issue_more = issue_rate - 1;
18189 (*group_count)++;
18190 end = true;
18191 for (i = 0; i < issue_rate; i++)
18193 group_insns[i] = 0;
18196 n_nops--;
18199 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
18200 can_issue_more++;
18202 /* Is next_insn going to start a new group? */
18203 *group_end
18204 = (end
18205 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
18206 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
18207 || (can_issue_more < issue_rate &&
18208 insn_terminates_group_p (next_insn, previous_group)));
18209 if (*group_end && end)
18210 (*group_count)--;
18212 if (sched_verbose > 6)
18213 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
18214 *group_count, can_issue_more);
18215 return can_issue_more;
18218 return can_issue_more;
18221 /* This function tries to synch the dispatch groups that the compiler "sees"
18222 with the dispatch groups that the processor dispatcher is expected to
18223 form in practice. It tries to achieve this synchronization by forcing the
18224 estimated processor grouping on the compiler (as opposed to the function
18225 'pad_goups' which tries to force the scheduler's grouping on the processor).
18227 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
18228 examines the (estimated) dispatch groups that will be formed by the processor
18229 dispatcher. It marks these group boundaries to reflect the estimated
18230 processor grouping, overriding the grouping that the scheduler had marked.
18231 Depending on the value of the flag '-minsert-sched-nops' this function can
18232 force certain insns into separate groups or force a certain distance between
18233 them by inserting nops, for example, if there exists a "costly dependence"
18234 between the insns.
18236 The function estimates the group boundaries that the processor will form as
18237 follows: It keeps track of how many vacant issue slots are available after
18238 each insn. A subsequent insn will start a new group if one of the following
18239 4 cases applies:
18240 - no more vacant issue slots remain in the current dispatch group.
18241 - only the last issue slot, which is the branch slot, is vacant, but the next
18242 insn is not a branch.
18243 - only the last 2 or less issue slots, including the branch slot, are vacant,
18244 which means that a cracked insn (which occupies two issue slots) can't be
18245 issued in this group.
18246 - less than 'issue_rate' slots are vacant, and the next insn always needs to
18247 start a new group. */
18249 static int
18250 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
18252 rtx insn, next_insn;
18253 int issue_rate;
18254 int can_issue_more;
18255 int slot, i;
18256 bool group_end;
18257 int group_count = 0;
18258 rtx *group_insns;
18260 /* Initialize. */
18261 issue_rate = rs6000_issue_rate ();
18262 group_insns = alloca (issue_rate * sizeof (rtx));
18263 for (i = 0; i < issue_rate; i++)
18265 group_insns[i] = 0;
18267 can_issue_more = issue_rate;
18268 slot = 0;
18269 insn = get_next_active_insn (prev_head_insn, tail);
18270 group_end = false;
18272 while (insn != NULL_RTX)
18274 slot = (issue_rate - can_issue_more);
18275 group_insns[slot] = insn;
18276 can_issue_more =
18277 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
18278 if (insn_terminates_group_p (insn, current_group))
18279 can_issue_more = 0;
18281 next_insn = get_next_active_insn (insn, tail);
18282 if (next_insn == NULL_RTX)
18283 return group_count + 1;
18285 /* Is next_insn going to start a new group? */
18286 group_end
18287 = (can_issue_more == 0
18288 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
18289 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
18290 || (can_issue_more < issue_rate &&
18291 insn_terminates_group_p (next_insn, previous_group)));
18293 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
18294 next_insn, &group_end, can_issue_more,
18295 &group_count);
18297 if (group_end)
18299 group_count++;
18300 can_issue_more = 0;
18301 for (i = 0; i < issue_rate; i++)
18303 group_insns[i] = 0;
18307 if (GET_MODE (next_insn) == TImode && can_issue_more)
18308 PUT_MODE (next_insn, VOIDmode);
18309 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
18310 PUT_MODE (next_insn, TImode);
18312 insn = next_insn;
18313 if (can_issue_more == 0)
18314 can_issue_more = issue_rate;
18315 } /* while */
18317 return group_count;
18320 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
18321 dispatch group boundaries that the scheduler had marked. Pad with nops
18322 any dispatch groups which have vacant issue slots, in order to force the
18323 scheduler's grouping on the processor dispatcher. The function
18324 returns the number of dispatch groups found. */
18326 static int
18327 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
18329 rtx insn, next_insn;
18330 rtx nop;
18331 int issue_rate;
18332 int can_issue_more;
18333 int group_end;
18334 int group_count = 0;
18336 /* Initialize issue_rate. */
18337 issue_rate = rs6000_issue_rate ();
18338 can_issue_more = issue_rate;
18340 insn = get_next_active_insn (prev_head_insn, tail);
18341 next_insn = get_next_active_insn (insn, tail);
18343 while (insn != NULL_RTX)
18345 can_issue_more =
18346 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
18348 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
18350 if (next_insn == NULL_RTX)
18351 break;
18353 if (group_end)
18355 /* If the scheduler had marked group termination at this location
18356 (between insn and next_indn), and neither insn nor next_insn will
18357 force group termination, pad the group with nops to force group
18358 termination. */
18359 if (can_issue_more
18360 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
18361 && !insn_terminates_group_p (insn, current_group)
18362 && !insn_terminates_group_p (next_insn, previous_group))
18364 if (!is_branch_slot_insn (next_insn))
18365 can_issue_more--;
18367 while (can_issue_more)
18369 nop = gen_nop ();
18370 emit_insn_before (nop, next_insn);
18371 can_issue_more--;
18375 can_issue_more = issue_rate;
18376 group_count++;
18379 insn = next_insn;
18380 next_insn = get_next_active_insn (insn, tail);
18383 return group_count;
18386 /* We're beginning a new block. Initialize data structures as necessary. */
18388 static void
18389 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
18390 int sched_verbose ATTRIBUTE_UNUSED,
18391 int max_ready ATTRIBUTE_UNUSED)
18393 last_scheduled_insn = NULL_RTX;
18394 load_store_pendulum = 0;
18397 /* The following function is called at the end of scheduling BB.
18398 After reload, it inserts nops at insn group bundling. */
18400 static void
18401 rs6000_sched_finish (FILE *dump, int sched_verbose)
18403 int n_groups;
18405 if (sched_verbose)
18406 fprintf (dump, "=== Finishing schedule.\n");
18408 if (reload_completed && rs6000_sched_groups)
18410 if (rs6000_sched_insert_nops == sched_finish_none)
18411 return;
18413 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
18414 n_groups = pad_groups (dump, sched_verbose,
18415 current_sched_info->prev_head,
18416 current_sched_info->next_tail);
18417 else
18418 n_groups = redefine_groups (dump, sched_verbose,
18419 current_sched_info->prev_head,
18420 current_sched_info->next_tail);
18422 if (sched_verbose >= 6)
18424 fprintf (dump, "ngroups = %d\n", n_groups);
18425 print_rtl (dump, current_sched_info->prev_head);
18426 fprintf (dump, "Done finish_sched\n");
18431 /* Length in units of the trampoline for entering a nested function. */
18434 rs6000_trampoline_size (void)
18436 int ret = 0;
18438 switch (DEFAULT_ABI)
18440 default:
18441 gcc_unreachable ();
18443 case ABI_AIX:
18444 ret = (TARGET_32BIT) ? 12 : 24;
18445 break;
18447 case ABI_DARWIN:
18448 case ABI_V4:
18449 ret = (TARGET_32BIT) ? 40 : 48;
18450 break;
18453 return ret;
18456 /* Emit RTL insns to initialize the variable parts of a trampoline.
18457 FNADDR is an RTX for the address of the function's pure code.
18458 CXT is an RTX for the static chain value for the function. */
18460 void
18461 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
18463 int regsize = (TARGET_32BIT) ? 4 : 8;
18464 rtx ctx_reg = force_reg (Pmode, cxt);
18466 switch (DEFAULT_ABI)
18468 default:
18469 gcc_unreachable ();
18471 /* Macros to shorten the code expansions below. */
18472 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
18473 #define MEM_PLUS(addr,offset) \
18474 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
18476 /* Under AIX, just build the 3 word function descriptor */
18477 case ABI_AIX:
18479 rtx fn_reg = gen_reg_rtx (Pmode);
18480 rtx toc_reg = gen_reg_rtx (Pmode);
18481 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
18482 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
18483 emit_move_insn (MEM_DEREF (addr), fn_reg);
18484 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
18485 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
18487 break;
18489 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
18490 case ABI_DARWIN:
18491 case ABI_V4:
18492 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
18493 FALSE, VOIDmode, 4,
18494 addr, Pmode,
18495 GEN_INT (rs6000_trampoline_size ()), SImode,
18496 fnaddr, Pmode,
18497 ctx_reg, Pmode);
18498 break;
18501 return;
18505 /* Table of valid machine attributes. */
18507 const struct attribute_spec rs6000_attribute_table[] =
18509 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
18510 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
18511 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
18512 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
18513 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
18514 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
18515 #ifdef SUBTARGET_ATTRIBUTE_TABLE
18516 SUBTARGET_ATTRIBUTE_TABLE,
18517 #endif
18518 { NULL, 0, 0, false, false, false, NULL }
18521 /* Handle the "altivec" attribute. The attribute may have
18522 arguments as follows:
18524 __attribute__((altivec(vector__)))
18525 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
18526 __attribute__((altivec(bool__))) (always followed by 'unsigned')
18528 and may appear more than once (e.g., 'vector bool char') in a
18529 given declaration. */
18531 static tree
18532 rs6000_handle_altivec_attribute (tree *node,
18533 tree name ATTRIBUTE_UNUSED,
18534 tree args,
18535 int flags ATTRIBUTE_UNUSED,
18536 bool *no_add_attrs)
18538 tree type = *node, result = NULL_TREE;
18539 enum machine_mode mode;
18540 int unsigned_p;
18541 char altivec_type
18542 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
18543 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
18544 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
18545 : '?');
18547 while (POINTER_TYPE_P (type)
18548 || TREE_CODE (type) == FUNCTION_TYPE
18549 || TREE_CODE (type) == METHOD_TYPE
18550 || TREE_CODE (type) == ARRAY_TYPE)
18551 type = TREE_TYPE (type);
18553 mode = TYPE_MODE (type);
18555 /* Check for invalid AltiVec type qualifiers. */
18556 if (type == long_unsigned_type_node || type == long_integer_type_node)
18558 if (TARGET_64BIT)
18559 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
18560 else if (rs6000_warn_altivec_long)
18561 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
18563 else if (type == long_long_unsigned_type_node
18564 || type == long_long_integer_type_node)
18565 error ("use of %<long long%> in AltiVec types is invalid");
18566 else if (type == double_type_node)
18567 error ("use of %<double%> in AltiVec types is invalid");
18568 else if (type == long_double_type_node)
18569 error ("use of %<long double%> in AltiVec types is invalid");
18570 else if (type == boolean_type_node)
18571 error ("use of boolean types in AltiVec types is invalid");
18572 else if (TREE_CODE (type) == COMPLEX_TYPE)
18573 error ("use of %<complex%> in AltiVec types is invalid");
18574 else if (DECIMAL_FLOAT_MODE_P (mode))
18575 error ("use of decimal floating point types in AltiVec types is invalid");
18577 switch (altivec_type)
18579 case 'v':
18580 unsigned_p = TYPE_UNSIGNED (type);
18581 switch (mode)
18583 case SImode:
18584 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
18585 break;
18586 case HImode:
18587 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
18588 break;
18589 case QImode:
18590 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
18591 break;
18592 case SFmode: result = V4SF_type_node; break;
18593 /* If the user says 'vector int bool', we may be handed the 'bool'
18594 attribute _before_ the 'vector' attribute, and so select the
18595 proper type in the 'b' case below. */
18596 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
18597 result = type;
18598 default: break;
18600 break;
18601 case 'b':
18602 switch (mode)
18604 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
18605 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
18606 case QImode: case V16QImode: result = bool_V16QI_type_node;
18607 default: break;
18609 break;
18610 case 'p':
18611 switch (mode)
18613 case V8HImode: result = pixel_V8HI_type_node;
18614 default: break;
18616 default: break;
18619 if (result && result != type && TYPE_READONLY (type))
18620 result = build_qualified_type (result, TYPE_QUAL_CONST);
18622 *no_add_attrs = true; /* No need to hang on to the attribute. */
18624 if (result)
18625 *node = reconstruct_complex_type (*node, result);
18627 return NULL_TREE;
18630 /* AltiVec defines four built-in scalar types that serve as vector
18631 elements; we must teach the compiler how to mangle them. */
18633 static const char *
18634 rs6000_mangle_fundamental_type (tree type)
18636 if (type == bool_char_type_node) return "U6__boolc";
18637 if (type == bool_short_type_node) return "U6__bools";
18638 if (type == pixel_type_node) return "u7__pixel";
18639 if (type == bool_int_type_node) return "U6__booli";
18641 /* Mangle IBM extended float long double as `g' (__float128) on
18642 powerpc*-linux where long-double-64 previously was the default. */
18643 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
18644 && TARGET_ELF
18645 && TARGET_LONG_DOUBLE_128
18646 && !TARGET_IEEEQUAD)
18647 return "g";
18649 /* For all other types, use normal C++ mangling. */
18650 return NULL;
18653 /* Handle a "longcall" or "shortcall" attribute; arguments as in
18654 struct attribute_spec.handler. */
18656 static tree
18657 rs6000_handle_longcall_attribute (tree *node, tree name,
18658 tree args ATTRIBUTE_UNUSED,
18659 int flags ATTRIBUTE_UNUSED,
18660 bool *no_add_attrs)
18662 if (TREE_CODE (*node) != FUNCTION_TYPE
18663 && TREE_CODE (*node) != FIELD_DECL
18664 && TREE_CODE (*node) != TYPE_DECL)
18666 warning (OPT_Wattributes, "%qs attribute only applies to functions",
18667 IDENTIFIER_POINTER (name));
18668 *no_add_attrs = true;
18671 return NULL_TREE;
18674 /* Set longcall attributes on all functions declared when
18675 rs6000_default_long_calls is true. */
18676 static void
18677 rs6000_set_default_type_attributes (tree type)
18679 if (rs6000_default_long_calls
18680 && (TREE_CODE (type) == FUNCTION_TYPE
18681 || TREE_CODE (type) == METHOD_TYPE))
18682 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
18683 NULL_TREE,
18684 TYPE_ATTRIBUTES (type));
18686 #if TARGET_MACHO
18687 darwin_set_default_type_attributes (type);
18688 #endif
18691 /* Return a reference suitable for calling a function with the
18692 longcall attribute. */
18695 rs6000_longcall_ref (rtx call_ref)
18697 const char *call_name;
18698 tree node;
18700 if (GET_CODE (call_ref) != SYMBOL_REF)
18701 return call_ref;
18703 /* System V adds '.' to the internal name, so skip them. */
18704 call_name = XSTR (call_ref, 0);
18705 if (*call_name == '.')
18707 while (*call_name == '.')
18708 call_name++;
18710 node = get_identifier (call_name);
18711 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
18714 return force_reg (Pmode, call_ref);
18717 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
18718 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
18719 #endif
18721 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
18722 struct attribute_spec.handler. */
18723 static tree
18724 rs6000_handle_struct_attribute (tree *node, tree name,
18725 tree args ATTRIBUTE_UNUSED,
18726 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
18728 tree *type = NULL;
18729 if (DECL_P (*node))
18731 if (TREE_CODE (*node) == TYPE_DECL)
18732 type = &TREE_TYPE (*node);
18734 else
18735 type = node;
18737 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
18738 || TREE_CODE (*type) == UNION_TYPE)))
18740 warning (OPT_Wattributes, "%qs attribute ignored", IDENTIFIER_POINTER (name));
18741 *no_add_attrs = true;
18744 else if ((is_attribute_p ("ms_struct", name)
18745 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
18746 || ((is_attribute_p ("gcc_struct", name)
18747 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
18749 warning (OPT_Wattributes, "%qs incompatible attribute ignored",
18750 IDENTIFIER_POINTER (name));
18751 *no_add_attrs = true;
18754 return NULL_TREE;
18757 static bool
18758 rs6000_ms_bitfield_layout_p (tree record_type)
18760 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
18761 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
18762 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
18765 #ifdef USING_ELFOS_H
18767 /* A get_unnamed_section callback, used for switching to toc_section. */
18769 static void
18770 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
18772 if (DEFAULT_ABI == ABI_AIX
18773 && TARGET_MINIMAL_TOC
18774 && !TARGET_RELOCATABLE)
18776 if (!toc_initialized)
18778 toc_initialized = 1;
18779 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
18780 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
18781 fprintf (asm_out_file, "\t.tc ");
18782 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
18783 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18784 fprintf (asm_out_file, "\n");
18786 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18787 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18788 fprintf (asm_out_file, " = .+32768\n");
18790 else
18791 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18793 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
18794 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
18795 else
18797 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18798 if (!toc_initialized)
18800 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
18801 fprintf (asm_out_file, " = .+32768\n");
18802 toc_initialized = 1;
18807 /* Implement TARGET_ASM_INIT_SECTIONS. */
18809 static void
18810 rs6000_elf_asm_init_sections (void)
18812 toc_section
18813 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
18815 sdata2_section
18816 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
18817 SDATA2_SECTION_ASM_OP);
18820 /* Implement TARGET_SELECT_RTX_SECTION. */
18822 static section *
18823 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
18824 unsigned HOST_WIDE_INT align)
18826 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
18827 return toc_section;
18828 else
18829 return default_elf_select_rtx_section (mode, x, align);
18832 /* Implement TARGET_ASM_SELECT_SECTION for ELF targets. */
18834 static section *
18835 rs6000_elf_select_section (tree decl, int reloc,
18836 unsigned HOST_WIDE_INT align)
18838 /* Pretend that we're always building for a shared library when
18839 ABI_AIX, because otherwise we end up with dynamic relocations
18840 in read-only sections. This happens for function pointers,
18841 references to vtables in typeinfo, and probably other cases. */
18842 return default_elf_select_section_1 (decl, reloc, align,
18843 flag_pic || DEFAULT_ABI == ABI_AIX);
18846 /* A C statement to build up a unique section name, expressed as a
18847 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
18848 RELOC indicates whether the initial value of EXP requires
18849 link-time relocations. If you do not define this macro, GCC will use
18850 the symbol name prefixed by `.' as the section name. Note - this
18851 macro can now be called for uninitialized data items as well as
18852 initialized data and functions. */
18854 static void
18855 rs6000_elf_unique_section (tree decl, int reloc)
18857 /* As above, pretend that we're always building for a shared library
18858 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
18859 default_unique_section_1 (decl, reloc,
18860 flag_pic || DEFAULT_ABI == ABI_AIX);
18863 /* For a SYMBOL_REF, set generic flags and then perform some
18864 target-specific processing.
18866 When the AIX ABI is requested on a non-AIX system, replace the
18867 function name with the real name (with a leading .) rather than the
18868 function descriptor name. This saves a lot of overriding code to
18869 read the prefixes. */
18871 static void
18872 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
18874 default_encode_section_info (decl, rtl, first);
18876 if (first
18877 && TREE_CODE (decl) == FUNCTION_DECL
18878 && !TARGET_AIX
18879 && DEFAULT_ABI == ABI_AIX)
18881 rtx sym_ref = XEXP (rtl, 0);
18882 size_t len = strlen (XSTR (sym_ref, 0));
18883 char *str = alloca (len + 2);
18884 str[0] = '.';
18885 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
18886 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
18890 bool
18891 rs6000_elf_in_small_data_p (tree decl)
18893 if (rs6000_sdata == SDATA_NONE)
18894 return false;
18896 /* We want to merge strings, so we never consider them small data. */
18897 if (TREE_CODE (decl) == STRING_CST)
18898 return false;
18900 /* Functions are never in the small data area. */
18901 if (TREE_CODE (decl) == FUNCTION_DECL)
18902 return false;
18904 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
18906 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
18907 if (strcmp (section, ".sdata") == 0
18908 || strcmp (section, ".sdata2") == 0
18909 || strcmp (section, ".sbss") == 0
18910 || strcmp (section, ".sbss2") == 0
18911 || strcmp (section, ".PPC.EMB.sdata0") == 0
18912 || strcmp (section, ".PPC.EMB.sbss0") == 0)
18913 return true;
18915 else
18917 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
18919 if (size > 0
18920 && (unsigned HOST_WIDE_INT) size <= g_switch_value
18921 /* If it's not public, and we're not going to reference it there,
18922 there's no need to put it in the small data section. */
18923 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
18924 return true;
18927 return false;
18930 #endif /* USING_ELFOS_H */
18932 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
18934 static bool
18935 rs6000_use_blocks_for_constant_p (enum machine_mode mode, rtx x)
18937 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
18940 /* Return a REG that occurs in ADDR with coefficient 1.
18941 ADDR can be effectively incremented by incrementing REG.
18943 r0 is special and we must not select it as an address
18944 register by this routine since our caller will try to
18945 increment the returned register via an "la" instruction. */
18948 find_addr_reg (rtx addr)
18950 while (GET_CODE (addr) == PLUS)
18952 if (GET_CODE (XEXP (addr, 0)) == REG
18953 && REGNO (XEXP (addr, 0)) != 0)
18954 addr = XEXP (addr, 0);
18955 else if (GET_CODE (XEXP (addr, 1)) == REG
18956 && REGNO (XEXP (addr, 1)) != 0)
18957 addr = XEXP (addr, 1);
18958 else if (CONSTANT_P (XEXP (addr, 0)))
18959 addr = XEXP (addr, 1);
18960 else if (CONSTANT_P (XEXP (addr, 1)))
18961 addr = XEXP (addr, 0);
18962 else
18963 gcc_unreachable ();
18965 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
18966 return addr;
18969 void
18970 rs6000_fatal_bad_address (rtx op)
18972 fatal_insn ("bad address", op);
18975 #if TARGET_MACHO
18977 static tree branch_island_list = 0;
18979 /* Remember to generate a branch island for far calls to the given
18980 function. */
18982 static void
18983 add_compiler_branch_island (tree label_name, tree function_name,
18984 int line_number)
18986 tree branch_island = build_tree_list (function_name, label_name);
18987 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
18988 TREE_CHAIN (branch_island) = branch_island_list;
18989 branch_island_list = branch_island;
18992 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
18993 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
18994 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
18995 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
18997 /* Generate far-jump branch islands for everything on the
18998 branch_island_list. Invoked immediately after the last instruction
18999 of the epilogue has been emitted; the branch-islands must be
19000 appended to, and contiguous with, the function body. Mach-O stubs
19001 are generated in machopic_output_stub(). */
19003 static void
19004 macho_branch_islands (void)
19006 char tmp_buf[512];
19007 tree branch_island;
19009 for (branch_island = branch_island_list;
19010 branch_island;
19011 branch_island = TREE_CHAIN (branch_island))
19013 const char *label =
19014 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
19015 const char *name =
19016 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
19017 char name_buf[512];
19018 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
19019 if (name[0] == '*' || name[0] == '&')
19020 strcpy (name_buf, name+1);
19021 else
19023 name_buf[0] = '_';
19024 strcpy (name_buf+1, name);
19026 strcpy (tmp_buf, "\n");
19027 strcat (tmp_buf, label);
19028 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
19029 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
19030 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
19031 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
19032 if (flag_pic)
19034 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
19035 strcat (tmp_buf, label);
19036 strcat (tmp_buf, "_pic\n");
19037 strcat (tmp_buf, label);
19038 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
19040 strcat (tmp_buf, "\taddis r11,r11,ha16(");
19041 strcat (tmp_buf, name_buf);
19042 strcat (tmp_buf, " - ");
19043 strcat (tmp_buf, label);
19044 strcat (tmp_buf, "_pic)\n");
19046 strcat (tmp_buf, "\tmtlr r0\n");
19048 strcat (tmp_buf, "\taddi r12,r11,lo16(");
19049 strcat (tmp_buf, name_buf);
19050 strcat (tmp_buf, " - ");
19051 strcat (tmp_buf, label);
19052 strcat (tmp_buf, "_pic)\n");
19054 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
19056 else
19058 strcat (tmp_buf, ":\nlis r12,hi16(");
19059 strcat (tmp_buf, name_buf);
19060 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
19061 strcat (tmp_buf, name_buf);
19062 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
19064 output_asm_insn (tmp_buf, 0);
19065 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
19066 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
19067 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
19068 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
19071 branch_island_list = 0;
19074 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
19075 already there or not. */
19077 static int
19078 no_previous_def (tree function_name)
19080 tree branch_island;
19081 for (branch_island = branch_island_list;
19082 branch_island;
19083 branch_island = TREE_CHAIN (branch_island))
19084 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
19085 return 0;
19086 return 1;
19089 /* GET_PREV_LABEL gets the label name from the previous definition of
19090 the function. */
19092 static tree
19093 get_prev_label (tree function_name)
19095 tree branch_island;
19096 for (branch_island = branch_island_list;
19097 branch_island;
19098 branch_island = TREE_CHAIN (branch_island))
19099 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
19100 return BRANCH_ISLAND_LABEL_NAME (branch_island);
19101 return 0;
19104 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
19105 #define DARWIN_LINKER_GENERATES_ISLANDS 0
19106 #endif
19108 /* KEXTs still need branch islands. */
19109 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
19110 || flag_mkernel || flag_apple_kext)
19112 /* INSN is either a function call or a millicode call. It may have an
19113 unconditional jump in its delay slot.
19115 CALL_DEST is the routine we are calling. */
19117 char *
19118 output_call (rtx insn, rtx *operands, int dest_operand_number,
19119 int cookie_operand_number)
19121 static char buf[256];
19122 if (DARWIN_GENERATE_ISLANDS
19123 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
19124 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
19126 tree labelname;
19127 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
19129 if (no_previous_def (funname))
19131 int line_number = 0;
19132 rtx label_rtx = gen_label_rtx ();
19133 char *label_buf, temp_buf[256];
19134 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
19135 CODE_LABEL_NUMBER (label_rtx));
19136 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
19137 labelname = get_identifier (label_buf);
19138 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
19139 if (insn)
19140 line_number = NOTE_LINE_NUMBER (insn);
19141 add_compiler_branch_island (labelname, funname, line_number);
19143 else
19144 labelname = get_prev_label (funname);
19146 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
19147 instruction will reach 'foo', otherwise link as 'bl L42'".
19148 "L42" should be a 'branch island', that will do a far jump to
19149 'foo'. Branch islands are generated in
19150 macho_branch_islands(). */
19151 sprintf (buf, "jbsr %%z%d,%.246s",
19152 dest_operand_number, IDENTIFIER_POINTER (labelname));
19154 else
19155 sprintf (buf, "bl %%z%d", dest_operand_number);
19156 return buf;
19159 /* Generate PIC and indirect symbol stubs. */
19161 void
19162 machopic_output_stub (FILE *file, const char *symb, const char *stub)
19164 unsigned int length;
19165 char *symbol_name, *lazy_ptr_name;
19166 char *local_label_0;
19167 static int label = 0;
19169 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
19170 symb = (*targetm.strip_name_encoding) (symb);
19173 length = strlen (symb);
19174 symbol_name = alloca (length + 32);
19175 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
19177 lazy_ptr_name = alloca (length + 32);
19178 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
19180 if (flag_pic == 2)
19181 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
19182 else
19183 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
19185 if (flag_pic == 2)
19187 fprintf (file, "\t.align 5\n");
19189 fprintf (file, "%s:\n", stub);
19190 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19192 label++;
19193 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
19194 sprintf (local_label_0, "\"L%011d$spb\"", label);
19196 fprintf (file, "\tmflr r0\n");
19197 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
19198 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
19199 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
19200 lazy_ptr_name, local_label_0);
19201 fprintf (file, "\tmtlr r0\n");
19202 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
19203 (TARGET_64BIT ? "ldu" : "lwzu"),
19204 lazy_ptr_name, local_label_0);
19205 fprintf (file, "\tmtctr r12\n");
19206 fprintf (file, "\tbctr\n");
19208 else
19210 fprintf (file, "\t.align 4\n");
19212 fprintf (file, "%s:\n", stub);
19213 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19215 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
19216 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
19217 (TARGET_64BIT ? "ldu" : "lwzu"),
19218 lazy_ptr_name);
19219 fprintf (file, "\tmtctr r12\n");
19220 fprintf (file, "\tbctr\n");
19223 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
19224 fprintf (file, "%s:\n", lazy_ptr_name);
19225 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19226 fprintf (file, "%sdyld_stub_binding_helper\n",
19227 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
19230 /* Legitimize PIC addresses. If the address is already
19231 position-independent, we return ORIG. Newly generated
19232 position-independent addresses go into a reg. This is REG if non
19233 zero, otherwise we allocate register(s) as necessary. */
19235 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
19238 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
19239 rtx reg)
19241 rtx base, offset;
19243 if (reg == NULL && ! reload_in_progress && ! reload_completed)
19244 reg = gen_reg_rtx (Pmode);
19246 if (GET_CODE (orig) == CONST)
19248 rtx reg_temp;
19250 if (GET_CODE (XEXP (orig, 0)) == PLUS
19251 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
19252 return orig;
19254 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
19256 /* Use a different reg for the intermediate value, as
19257 it will be marked UNCHANGING. */
19258 reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
19259 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
19260 Pmode, reg_temp);
19261 offset =
19262 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
19263 Pmode, reg);
19265 if (GET_CODE (offset) == CONST_INT)
19267 if (SMALL_INT (offset))
19268 return plus_constant (base, INTVAL (offset));
19269 else if (! reload_in_progress && ! reload_completed)
19270 offset = force_reg (Pmode, offset);
19271 else
19273 rtx mem = force_const_mem (Pmode, orig);
19274 return machopic_legitimize_pic_address (mem, Pmode, reg);
19277 return gen_rtx_PLUS (Pmode, base, offset);
19280 /* Fall back on generic machopic code. */
19281 return machopic_legitimize_pic_address (orig, mode, reg);
19284 /* Output a .machine directive for the Darwin assembler, and call
19285 the generic start_file routine. */
19287 static void
19288 rs6000_darwin_file_start (void)
19290 static const struct
19292 const char *arg;
19293 const char *name;
19294 int if_set;
19295 } mapping[] = {
19296 { "ppc64", "ppc64", MASK_64BIT },
19297 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
19298 { "power4", "ppc970", 0 },
19299 { "G5", "ppc970", 0 },
19300 { "7450", "ppc7450", 0 },
19301 { "7400", "ppc7400", MASK_ALTIVEC },
19302 { "G4", "ppc7400", 0 },
19303 { "750", "ppc750", 0 },
19304 { "740", "ppc750", 0 },
19305 { "G3", "ppc750", 0 },
19306 { "604e", "ppc604e", 0 },
19307 { "604", "ppc604", 0 },
19308 { "603e", "ppc603", 0 },
19309 { "603", "ppc603", 0 },
19310 { "601", "ppc601", 0 },
19311 { NULL, "ppc", 0 } };
19312 const char *cpu_id = "";
19313 size_t i;
19315 rs6000_file_start ();
19316 darwin_file_start ();
19318 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
19319 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
19320 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
19321 && rs6000_select[i].string[0] != '\0')
19322 cpu_id = rs6000_select[i].string;
19324 /* Look through the mapping array. Pick the first name that either
19325 matches the argument, has a bit set in IF_SET that is also set
19326 in the target flags, or has a NULL name. */
19328 i = 0;
19329 while (mapping[i].arg != NULL
19330 && strcmp (mapping[i].arg, cpu_id) != 0
19331 && (mapping[i].if_set & target_flags) == 0)
19332 i++;
19334 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
19337 #endif /* TARGET_MACHO */
19339 #if TARGET_ELF
19340 static unsigned int
19341 rs6000_elf_section_type_flags (tree decl, const char *name, int reloc)
19343 return default_section_type_flags_1 (decl, name, reloc,
19344 flag_pic || DEFAULT_ABI == ABI_AIX);
19347 /* Record an element in the table of global constructors. SYMBOL is
19348 a SYMBOL_REF of the function to be called; PRIORITY is a number
19349 between 0 and MAX_INIT_PRIORITY.
19351 This differs from default_named_section_asm_out_constructor in
19352 that we have special handling for -mrelocatable. */
19354 static void
19355 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
19357 const char *section = ".ctors";
19358 char buf[16];
19360 if (priority != DEFAULT_INIT_PRIORITY)
19362 sprintf (buf, ".ctors.%.5u",
19363 /* Invert the numbering so the linker puts us in the proper
19364 order; constructors are run from right to left, and the
19365 linker sorts in increasing order. */
19366 MAX_INIT_PRIORITY - priority);
19367 section = buf;
19370 switch_to_section (get_section (section, SECTION_WRITE, NULL));
19371 assemble_align (POINTER_SIZE);
19373 if (TARGET_RELOCATABLE)
19375 fputs ("\t.long (", asm_out_file);
19376 output_addr_const (asm_out_file, symbol);
19377 fputs (")@fixup\n", asm_out_file);
19379 else
19380 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
19383 static void
19384 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
19386 const char *section = ".dtors";
19387 char buf[16];
19389 if (priority != DEFAULT_INIT_PRIORITY)
19391 sprintf (buf, ".dtors.%.5u",
19392 /* Invert the numbering so the linker puts us in the proper
19393 order; constructors are run from right to left, and the
19394 linker sorts in increasing order. */
19395 MAX_INIT_PRIORITY - priority);
19396 section = buf;
19399 switch_to_section (get_section (section, SECTION_WRITE, NULL));
19400 assemble_align (POINTER_SIZE);
19402 if (TARGET_RELOCATABLE)
19404 fputs ("\t.long (", asm_out_file);
19405 output_addr_const (asm_out_file, symbol);
19406 fputs (")@fixup\n", asm_out_file);
19408 else
19409 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
19412 void
19413 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
19415 if (TARGET_64BIT)
19417 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
19418 ASM_OUTPUT_LABEL (file, name);
19419 fputs (DOUBLE_INT_ASM_OP, file);
19420 rs6000_output_function_entry (file, name);
19421 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
19422 if (DOT_SYMBOLS)
19424 fputs ("\t.size\t", file);
19425 assemble_name (file, name);
19426 fputs (",24\n\t.type\t.", file);
19427 assemble_name (file, name);
19428 fputs (",@function\n", file);
19429 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
19431 fputs ("\t.globl\t.", file);
19432 assemble_name (file, name);
19433 putc ('\n', file);
19436 else
19437 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
19438 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
19439 rs6000_output_function_entry (file, name);
19440 fputs (":\n", file);
19441 return;
19444 if (TARGET_RELOCATABLE
19445 && !TARGET_SECURE_PLT
19446 && (get_pool_size () != 0 || current_function_profile)
19447 && uses_TOC ())
19449 char buf[256];
19451 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
19453 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19454 fprintf (file, "\t.long ");
19455 assemble_name (file, buf);
19456 putc ('-', file);
19457 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19458 assemble_name (file, buf);
19459 putc ('\n', file);
19462 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
19463 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
19465 if (DEFAULT_ABI == ABI_AIX)
19467 const char *desc_name, *orig_name;
19469 orig_name = (*targetm.strip_name_encoding) (name);
19470 desc_name = orig_name;
19471 while (*desc_name == '.')
19472 desc_name++;
19474 if (TREE_PUBLIC (decl))
19475 fprintf (file, "\t.globl %s\n", desc_name);
19477 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
19478 fprintf (file, "%s:\n", desc_name);
19479 fprintf (file, "\t.long %s\n", orig_name);
19480 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
19481 if (DEFAULT_ABI == ABI_AIX)
19482 fputs ("\t.long 0\n", file);
19483 fprintf (file, "\t.previous\n");
19485 ASM_OUTPUT_LABEL (file, name);
19488 static void
19489 rs6000_elf_end_indicate_exec_stack (void)
19491 if (TARGET_32BIT)
19492 file_end_indicate_exec_stack ();
19494 #endif
19496 #if TARGET_XCOFF
19497 static void
19498 rs6000_xcoff_asm_output_anchor (rtx symbol)
19500 char buffer[100];
19502 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
19503 SYMBOL_REF_BLOCK_OFFSET (symbol));
19504 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
19507 static void
19508 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
19510 fputs (GLOBAL_ASM_OP, stream);
19511 RS6000_OUTPUT_BASENAME (stream, name);
19512 putc ('\n', stream);
19515 /* A get_unnamed_decl callback, used for read-only sections. PTR
19516 points to the section string variable. */
19518 static void
19519 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
19521 fprintf (asm_out_file, "\t.csect %s[RO],3\n",
19522 *(const char *const *) directive);
19525 /* Likewise for read-write sections. */
19527 static void
19528 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
19530 fprintf (asm_out_file, "\t.csect %s[RW],3\n",
19531 *(const char *const *) directive);
19534 /* A get_unnamed_section callback, used for switching to toc_section. */
19536 static void
19537 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
19539 if (TARGET_MINIMAL_TOC)
19541 /* toc_section is always selected at least once from
19542 rs6000_xcoff_file_start, so this is guaranteed to
19543 always be defined once and only once in each file. */
19544 if (!toc_initialized)
19546 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
19547 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
19548 toc_initialized = 1;
19550 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
19551 (TARGET_32BIT ? "" : ",3"));
19553 else
19554 fputs ("\t.toc\n", asm_out_file);
19557 /* Implement TARGET_ASM_INIT_SECTIONS. */
19559 static void
19560 rs6000_xcoff_asm_init_sections (void)
19562 read_only_data_section
19563 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
19564 &xcoff_read_only_section_name);
19566 private_data_section
19567 = get_unnamed_section (SECTION_WRITE,
19568 rs6000_xcoff_output_readwrite_section_asm_op,
19569 &xcoff_private_data_section_name);
19571 read_only_private_data_section
19572 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
19573 &xcoff_private_data_section_name);
19575 toc_section
19576 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
19578 readonly_data_section = read_only_data_section;
19579 exception_section = data_section;
19582 static void
19583 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
19584 tree decl ATTRIBUTE_UNUSED)
19586 int smclass;
19587 static const char * const suffix[3] = { "PR", "RO", "RW" };
19589 if (flags & SECTION_CODE)
19590 smclass = 0;
19591 else if (flags & SECTION_WRITE)
19592 smclass = 2;
19593 else
19594 smclass = 1;
19596 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
19597 (flags & SECTION_CODE) ? "." : "",
19598 name, suffix[smclass], flags & SECTION_ENTSIZE);
19601 static section *
19602 rs6000_xcoff_select_section (tree decl, int reloc,
19603 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
19605 if (decl_readonly_section_1 (decl, reloc, 1))
19607 if (TREE_PUBLIC (decl))
19608 return read_only_data_section;
19609 else
19610 return read_only_private_data_section;
19612 else
19614 if (TREE_PUBLIC (decl))
19615 return data_section;
19616 else
19617 return private_data_section;
19621 static void
19622 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
19624 const char *name;
19626 /* Use select_section for private and uninitialized data. */
19627 if (!TREE_PUBLIC (decl)
19628 || DECL_COMMON (decl)
19629 || DECL_INITIAL (decl) == NULL_TREE
19630 || DECL_INITIAL (decl) == error_mark_node
19631 || (flag_zero_initialized_in_bss
19632 && initializer_zerop (DECL_INITIAL (decl))))
19633 return;
19635 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
19636 name = (*targetm.strip_name_encoding) (name);
19637 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
19640 /* Select section for constant in constant pool.
19642 On RS/6000, all constants are in the private read-only data area.
19643 However, if this is being placed in the TOC it must be output as a
19644 toc entry. */
19646 static section *
19647 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
19648 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
19650 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
19651 return toc_section;
19652 else
19653 return read_only_private_data_section;
19656 /* Remove any trailing [DS] or the like from the symbol name. */
19658 static const char *
19659 rs6000_xcoff_strip_name_encoding (const char *name)
19661 size_t len;
19662 if (*name == '*')
19663 name++;
19664 len = strlen (name);
19665 if (name[len - 1] == ']')
19666 return ggc_alloc_string (name, len - 4);
19667 else
19668 return name;
19671 /* Section attributes. AIX is always PIC. */
19673 static unsigned int
19674 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
19676 unsigned int align;
19677 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
19679 /* Align to at least UNIT size. */
19680 if (flags & SECTION_CODE)
19681 align = MIN_UNITS_PER_WORD;
19682 else
19683 /* Increase alignment of large objects if not already stricter. */
19684 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
19685 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
19686 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
19688 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
19691 /* Output at beginning of assembler file.
19693 Initialize the section names for the RS/6000 at this point.
19695 Specify filename, including full path, to assembler.
19697 We want to go into the TOC section so at least one .toc will be emitted.
19698 Also, in order to output proper .bs/.es pairs, we need at least one static
19699 [RW] section emitted.
19701 Finally, declare mcount when profiling to make the assembler happy. */
19703 static void
19704 rs6000_xcoff_file_start (void)
19706 rs6000_gen_section_name (&xcoff_bss_section_name,
19707 main_input_filename, ".bss_");
19708 rs6000_gen_section_name (&xcoff_private_data_section_name,
19709 main_input_filename, ".rw_");
19710 rs6000_gen_section_name (&xcoff_read_only_section_name,
19711 main_input_filename, ".ro_");
19713 fputs ("\t.file\t", asm_out_file);
19714 output_quoted_string (asm_out_file, main_input_filename);
19715 fputc ('\n', asm_out_file);
19716 if (write_symbols != NO_DEBUG)
19717 switch_to_section (private_data_section);
19718 switch_to_section (text_section);
19719 if (profile_flag)
19720 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
19721 rs6000_file_start ();
19724 /* Output at end of assembler file.
19725 On the RS/6000, referencing data should automatically pull in text. */
19727 static void
19728 rs6000_xcoff_file_end (void)
19730 switch_to_section (text_section);
19731 fputs ("_section_.text:\n", asm_out_file);
19732 switch_to_section (data_section);
19733 fputs (TARGET_32BIT
19734 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
19735 asm_out_file);
19737 #endif /* TARGET_XCOFF */
19739 /* Compute a (partial) cost for rtx X. Return true if the complete
19740 cost has been computed, and false if subexpressions should be
19741 scanned. In either case, *TOTAL contains the cost result. */
19743 static bool
19744 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
19746 enum machine_mode mode = GET_MODE (x);
19748 switch (code)
19750 /* On the RS/6000, if it is valid in the insn, it is free. */
19751 case CONST_INT:
19752 if (((outer_code == SET
19753 || outer_code == PLUS
19754 || outer_code == MINUS)
19755 && (satisfies_constraint_I (x)
19756 || satisfies_constraint_L (x)))
19757 || (outer_code == AND
19758 && (satisfies_constraint_K (x)
19759 || (mode == SImode
19760 ? satisfies_constraint_L (x)
19761 : satisfies_constraint_J (x))
19762 || mask_operand (x, mode)
19763 || (mode == DImode
19764 && mask64_operand (x, DImode))))
19765 || ((outer_code == IOR || outer_code == XOR)
19766 && (satisfies_constraint_K (x)
19767 || (mode == SImode
19768 ? satisfies_constraint_L (x)
19769 : satisfies_constraint_J (x))))
19770 || outer_code == ASHIFT
19771 || outer_code == ASHIFTRT
19772 || outer_code == LSHIFTRT
19773 || outer_code == ROTATE
19774 || outer_code == ROTATERT
19775 || outer_code == ZERO_EXTRACT
19776 || (outer_code == MULT
19777 && satisfies_constraint_I (x))
19778 || ((outer_code == DIV || outer_code == UDIV
19779 || outer_code == MOD || outer_code == UMOD)
19780 && exact_log2 (INTVAL (x)) >= 0)
19781 || (outer_code == COMPARE
19782 && (satisfies_constraint_I (x)
19783 || satisfies_constraint_K (x)))
19784 || (outer_code == EQ
19785 && (satisfies_constraint_I (x)
19786 || satisfies_constraint_K (x)
19787 || (mode == SImode
19788 ? satisfies_constraint_L (x)
19789 : satisfies_constraint_J (x))))
19790 || (outer_code == GTU
19791 && satisfies_constraint_I (x))
19792 || (outer_code == LTU
19793 && satisfies_constraint_P (x)))
19795 *total = 0;
19796 return true;
19798 else if ((outer_code == PLUS
19799 && reg_or_add_cint_operand (x, VOIDmode))
19800 || (outer_code == MINUS
19801 && reg_or_sub_cint_operand (x, VOIDmode))
19802 || ((outer_code == SET
19803 || outer_code == IOR
19804 || outer_code == XOR)
19805 && (INTVAL (x)
19806 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
19808 *total = COSTS_N_INSNS (1);
19809 return true;
19811 /* FALLTHRU */
19813 case CONST_DOUBLE:
19814 if (mode == DImode && code == CONST_DOUBLE)
19816 if ((outer_code == IOR || outer_code == XOR)
19817 && CONST_DOUBLE_HIGH (x) == 0
19818 && (CONST_DOUBLE_LOW (x)
19819 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
19821 *total = 0;
19822 return true;
19824 else if ((outer_code == AND && and64_2_operand (x, DImode))
19825 || ((outer_code == SET
19826 || outer_code == IOR
19827 || outer_code == XOR)
19828 && CONST_DOUBLE_HIGH (x) == 0))
19830 *total = COSTS_N_INSNS (1);
19831 return true;
19834 /* FALLTHRU */
19836 case CONST:
19837 case HIGH:
19838 case SYMBOL_REF:
19839 case MEM:
19840 /* When optimizing for size, MEM should be slightly more expensive
19841 than generating address, e.g., (plus (reg) (const)).
19842 L1 cache latency is about two instructions. */
19843 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
19844 return true;
19846 case LABEL_REF:
19847 *total = 0;
19848 return true;
19850 case PLUS:
19851 if (mode == DFmode)
19853 if (GET_CODE (XEXP (x, 0)) == MULT)
19855 /* FNMA accounted in outer NEG. */
19856 if (outer_code == NEG)
19857 *total = rs6000_cost->dmul - rs6000_cost->fp;
19858 else
19859 *total = rs6000_cost->dmul;
19861 else
19862 *total = rs6000_cost->fp;
19864 else if (mode == SFmode)
19866 /* FNMA accounted in outer NEG. */
19867 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
19868 *total = 0;
19869 else
19870 *total = rs6000_cost->fp;
19872 else
19873 *total = COSTS_N_INSNS (1);
19874 return false;
19876 case MINUS:
19877 if (mode == DFmode)
19879 if (GET_CODE (XEXP (x, 0)) == MULT
19880 || GET_CODE (XEXP (x, 1)) == MULT)
19882 /* FNMA accounted in outer NEG. */
19883 if (outer_code == NEG)
19884 *total = rs6000_cost->dmul - rs6000_cost->fp;
19885 else
19886 *total = rs6000_cost->dmul;
19888 else
19889 *total = rs6000_cost->fp;
19891 else if (mode == SFmode)
19893 /* FNMA accounted in outer NEG. */
19894 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
19895 *total = 0;
19896 else
19897 *total = rs6000_cost->fp;
19899 else
19900 *total = COSTS_N_INSNS (1);
19901 return false;
19903 case MULT:
19904 if (GET_CODE (XEXP (x, 1)) == CONST_INT
19905 && satisfies_constraint_I (XEXP (x, 1)))
19907 if (INTVAL (XEXP (x, 1)) >= -256
19908 && INTVAL (XEXP (x, 1)) <= 255)
19909 *total = rs6000_cost->mulsi_const9;
19910 else
19911 *total = rs6000_cost->mulsi_const;
19913 /* FMA accounted in outer PLUS/MINUS. */
19914 else if ((mode == DFmode || mode == SFmode)
19915 && (outer_code == PLUS || outer_code == MINUS))
19916 *total = 0;
19917 else if (mode == DFmode)
19918 *total = rs6000_cost->dmul;
19919 else if (mode == SFmode)
19920 *total = rs6000_cost->fp;
19921 else if (mode == DImode)
19922 *total = rs6000_cost->muldi;
19923 else
19924 *total = rs6000_cost->mulsi;
19925 return false;
19927 case DIV:
19928 case MOD:
19929 if (FLOAT_MODE_P (mode))
19931 *total = mode == DFmode ? rs6000_cost->ddiv
19932 : rs6000_cost->sdiv;
19933 return false;
19935 /* FALLTHRU */
19937 case UDIV:
19938 case UMOD:
19939 if (GET_CODE (XEXP (x, 1)) == CONST_INT
19940 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
19942 if (code == DIV || code == MOD)
19943 /* Shift, addze */
19944 *total = COSTS_N_INSNS (2);
19945 else
19946 /* Shift */
19947 *total = COSTS_N_INSNS (1);
19949 else
19951 if (GET_MODE (XEXP (x, 1)) == DImode)
19952 *total = rs6000_cost->divdi;
19953 else
19954 *total = rs6000_cost->divsi;
19956 /* Add in shift and subtract for MOD. */
19957 if (code == MOD || code == UMOD)
19958 *total += COSTS_N_INSNS (2);
19959 return false;
19961 case FFS:
19962 *total = COSTS_N_INSNS (4);
19963 return false;
19965 case NOT:
19966 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
19968 *total = 0;
19969 return false;
19971 /* FALLTHRU */
19973 case AND:
19974 case IOR:
19975 case XOR:
19976 case ZERO_EXTRACT:
19977 *total = COSTS_N_INSNS (1);
19978 return false;
19980 case ASHIFT:
19981 case ASHIFTRT:
19982 case LSHIFTRT:
19983 case ROTATE:
19984 case ROTATERT:
19985 /* Handle mul_highpart. */
19986 if (outer_code == TRUNCATE
19987 && GET_CODE (XEXP (x, 0)) == MULT)
19989 if (mode == DImode)
19990 *total = rs6000_cost->muldi;
19991 else
19992 *total = rs6000_cost->mulsi;
19993 return true;
19995 else if (outer_code == AND)
19996 *total = 0;
19997 else
19998 *total = COSTS_N_INSNS (1);
19999 return false;
20001 case SIGN_EXTEND:
20002 case ZERO_EXTEND:
20003 if (GET_CODE (XEXP (x, 0)) == MEM)
20004 *total = 0;
20005 else
20006 *total = COSTS_N_INSNS (1);
20007 return false;
20009 case COMPARE:
20010 case NEG:
20011 case ABS:
20012 if (!FLOAT_MODE_P (mode))
20014 *total = COSTS_N_INSNS (1);
20015 return false;
20017 /* FALLTHRU */
20019 case FLOAT:
20020 case UNSIGNED_FLOAT:
20021 case FIX:
20022 case UNSIGNED_FIX:
20023 case FLOAT_TRUNCATE:
20024 *total = rs6000_cost->fp;
20025 return false;
20027 case FLOAT_EXTEND:
20028 if (mode == DFmode)
20029 *total = 0;
20030 else
20031 *total = rs6000_cost->fp;
20032 return false;
20034 case UNSPEC:
20035 switch (XINT (x, 1))
20037 case UNSPEC_FRSP:
20038 *total = rs6000_cost->fp;
20039 return true;
20041 default:
20042 break;
20044 break;
20046 case CALL:
20047 case IF_THEN_ELSE:
20048 if (optimize_size)
20050 *total = COSTS_N_INSNS (1);
20051 return true;
20053 else if (FLOAT_MODE_P (mode)
20054 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
20056 *total = rs6000_cost->fp;
20057 return false;
20059 break;
20061 case EQ:
20062 case GTU:
20063 case LTU:
20064 /* Carry bit requires mode == Pmode.
20065 NEG or PLUS already counted so only add one. */
20066 if (mode == Pmode
20067 && (outer_code == NEG || outer_code == PLUS))
20069 *total = COSTS_N_INSNS (1);
20070 return true;
20072 if (outer_code == SET)
20074 if (XEXP (x, 1) == const0_rtx)
20076 *total = COSTS_N_INSNS (2);
20077 return true;
20079 else if (mode == Pmode)
20081 *total = COSTS_N_INSNS (3);
20082 return false;
20085 /* FALLTHRU */
20087 case GT:
20088 case LT:
20089 case UNORDERED:
20090 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
20092 *total = COSTS_N_INSNS (2);
20093 return true;
20095 /* CC COMPARE. */
20096 if (outer_code == COMPARE)
20098 *total = 0;
20099 return true;
20101 break;
20103 default:
20104 break;
20107 return false;
20110 /* A C expression returning the cost of moving data from a register of class
20111 CLASS1 to one of CLASS2. */
20114 rs6000_register_move_cost (enum machine_mode mode,
20115 enum reg_class from, enum reg_class to)
20117 /* Moves from/to GENERAL_REGS. */
20118 if (reg_classes_intersect_p (to, GENERAL_REGS)
20119 || reg_classes_intersect_p (from, GENERAL_REGS))
20121 if (! reg_classes_intersect_p (to, GENERAL_REGS))
20122 from = to;
20124 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
20125 return (rs6000_memory_move_cost (mode, from, 0)
20126 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
20128 /* It's more expensive to move CR_REGS than CR0_REGS because of the
20129 shift. */
20130 else if (from == CR_REGS)
20131 return 4;
20133 else
20134 /* A move will cost one instruction per GPR moved. */
20135 return 2 * hard_regno_nregs[0][mode];
20138 /* Moving between two similar registers is just one instruction. */
20139 else if (reg_classes_intersect_p (to, from))
20140 return mode == TFmode ? 4 : 2;
20142 /* Everything else has to go through GENERAL_REGS. */
20143 else
20144 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
20145 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
20148 /* A C expressions returning the cost of moving data of MODE from a register to
20149 or from memory. */
20152 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
20153 int in ATTRIBUTE_UNUSED)
20155 if (reg_classes_intersect_p (class, GENERAL_REGS))
20156 return 4 * hard_regno_nregs[0][mode];
20157 else if (reg_classes_intersect_p (class, FLOAT_REGS))
20158 return 4 * hard_regno_nregs[32][mode];
20159 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
20160 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
20161 else
20162 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
20165 /* Newton-Raphson approximation of single-precision floating point divide n/d.
20166 Assumes no trapping math and finite arguments. */
20168 void
20169 rs6000_emit_swdivsf (rtx res, rtx n, rtx d)
20171 rtx x0, e0, e1, y1, u0, v0, one;
20173 x0 = gen_reg_rtx (SFmode);
20174 e0 = gen_reg_rtx (SFmode);
20175 e1 = gen_reg_rtx (SFmode);
20176 y1 = gen_reg_rtx (SFmode);
20177 u0 = gen_reg_rtx (SFmode);
20178 v0 = gen_reg_rtx (SFmode);
20179 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
20181 /* x0 = 1./d estimate */
20182 emit_insn (gen_rtx_SET (VOIDmode, x0,
20183 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
20184 UNSPEC_FRES)));
20185 /* e0 = 1. - d * x0 */
20186 emit_insn (gen_rtx_SET (VOIDmode, e0,
20187 gen_rtx_MINUS (SFmode, one,
20188 gen_rtx_MULT (SFmode, d, x0))));
20189 /* e1 = e0 + e0 * e0 */
20190 emit_insn (gen_rtx_SET (VOIDmode, e1,
20191 gen_rtx_PLUS (SFmode,
20192 gen_rtx_MULT (SFmode, e0, e0), e0)));
20193 /* y1 = x0 + e1 * x0 */
20194 emit_insn (gen_rtx_SET (VOIDmode, y1,
20195 gen_rtx_PLUS (SFmode,
20196 gen_rtx_MULT (SFmode, e1, x0), x0)));
20197 /* u0 = n * y1 */
20198 emit_insn (gen_rtx_SET (VOIDmode, u0,
20199 gen_rtx_MULT (SFmode, n, y1)));
20200 /* v0 = n - d * u0 */
20201 emit_insn (gen_rtx_SET (VOIDmode, v0,
20202 gen_rtx_MINUS (SFmode, n,
20203 gen_rtx_MULT (SFmode, d, u0))));
20204 /* res = u0 + v0 * y1 */
20205 emit_insn (gen_rtx_SET (VOIDmode, res,
20206 gen_rtx_PLUS (SFmode,
20207 gen_rtx_MULT (SFmode, v0, y1), u0)));
20210 /* Newton-Raphson approximation of double-precision floating point divide n/d.
20211 Assumes no trapping math and finite arguments. */
20213 void
20214 rs6000_emit_swdivdf (rtx res, rtx n, rtx d)
20216 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
20218 x0 = gen_reg_rtx (DFmode);
20219 e0 = gen_reg_rtx (DFmode);
20220 e1 = gen_reg_rtx (DFmode);
20221 e2 = gen_reg_rtx (DFmode);
20222 y1 = gen_reg_rtx (DFmode);
20223 y2 = gen_reg_rtx (DFmode);
20224 y3 = gen_reg_rtx (DFmode);
20225 u0 = gen_reg_rtx (DFmode);
20226 v0 = gen_reg_rtx (DFmode);
20227 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
20229 /* x0 = 1./d estimate */
20230 emit_insn (gen_rtx_SET (VOIDmode, x0,
20231 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
20232 UNSPEC_FRES)));
20233 /* e0 = 1. - d * x0 */
20234 emit_insn (gen_rtx_SET (VOIDmode, e0,
20235 gen_rtx_MINUS (DFmode, one,
20236 gen_rtx_MULT (SFmode, d, x0))));
20237 /* y1 = x0 + e0 * x0 */
20238 emit_insn (gen_rtx_SET (VOIDmode, y1,
20239 gen_rtx_PLUS (DFmode,
20240 gen_rtx_MULT (DFmode, e0, x0), x0)));
20241 /* e1 = e0 * e0 */
20242 emit_insn (gen_rtx_SET (VOIDmode, e1,
20243 gen_rtx_MULT (DFmode, e0, e0)));
20244 /* y2 = y1 + e1 * y1 */
20245 emit_insn (gen_rtx_SET (VOIDmode, y2,
20246 gen_rtx_PLUS (DFmode,
20247 gen_rtx_MULT (DFmode, e1, y1), y1)));
20248 /* e2 = e1 * e1 */
20249 emit_insn (gen_rtx_SET (VOIDmode, e2,
20250 gen_rtx_MULT (DFmode, e1, e1)));
20251 /* y3 = y2 + e2 * y2 */
20252 emit_insn (gen_rtx_SET (VOIDmode, y3,
20253 gen_rtx_PLUS (DFmode,
20254 gen_rtx_MULT (DFmode, e2, y2), y2)));
20255 /* u0 = n * y3 */
20256 emit_insn (gen_rtx_SET (VOIDmode, u0,
20257 gen_rtx_MULT (DFmode, n, y3)));
20258 /* v0 = n - d * u0 */
20259 emit_insn (gen_rtx_SET (VOIDmode, v0,
20260 gen_rtx_MINUS (DFmode, n,
20261 gen_rtx_MULT (DFmode, d, u0))));
20262 /* res = u0 + v0 * y3 */
20263 emit_insn (gen_rtx_SET (VOIDmode, res,
20264 gen_rtx_PLUS (DFmode,
20265 gen_rtx_MULT (DFmode, v0, y3), u0)));
20269 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
20270 target, and SRC is the argument operand. */
20272 void
20273 rs6000_emit_popcount (rtx dst, rtx src)
20275 enum machine_mode mode = GET_MODE (dst);
20276 rtx tmp1, tmp2;
20278 tmp1 = gen_reg_rtx (mode);
20280 if (mode == SImode)
20282 emit_insn (gen_popcntbsi2 (tmp1, src));
20283 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
20284 NULL_RTX, 0);
20285 tmp2 = force_reg (SImode, tmp2);
20286 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
20288 else
20290 emit_insn (gen_popcntbdi2 (tmp1, src));
20291 tmp2 = expand_mult (DImode, tmp1,
20292 GEN_INT ((HOST_WIDE_INT)
20293 0x01010101 << 32 | 0x01010101),
20294 NULL_RTX, 0);
20295 tmp2 = force_reg (DImode, tmp2);
20296 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
20301 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
20302 target, and SRC is the argument operand. */
20304 void
20305 rs6000_emit_parity (rtx dst, rtx src)
20307 enum machine_mode mode = GET_MODE (dst);
20308 rtx tmp;
20310 tmp = gen_reg_rtx (mode);
20311 if (mode == SImode)
20313 /* Is mult+shift >= shift+xor+shift+xor? */
20314 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
20316 rtx tmp1, tmp2, tmp3, tmp4;
20318 tmp1 = gen_reg_rtx (SImode);
20319 emit_insn (gen_popcntbsi2 (tmp1, src));
20321 tmp2 = gen_reg_rtx (SImode);
20322 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
20323 tmp3 = gen_reg_rtx (SImode);
20324 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
20326 tmp4 = gen_reg_rtx (SImode);
20327 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
20328 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
20330 else
20331 rs6000_emit_popcount (tmp, src);
20332 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
20334 else
20336 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
20337 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
20339 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
20341 tmp1 = gen_reg_rtx (DImode);
20342 emit_insn (gen_popcntbdi2 (tmp1, src));
20344 tmp2 = gen_reg_rtx (DImode);
20345 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
20346 tmp3 = gen_reg_rtx (DImode);
20347 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
20349 tmp4 = gen_reg_rtx (DImode);
20350 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
20351 tmp5 = gen_reg_rtx (DImode);
20352 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
20354 tmp6 = gen_reg_rtx (DImode);
20355 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
20356 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
20358 else
20359 rs6000_emit_popcount (tmp, src);
20360 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
20364 /* Return an RTX representing where to find the function value of a
20365 function returning MODE. */
20366 static rtx
20367 rs6000_complex_function_value (enum machine_mode mode)
20369 unsigned int regno;
20370 rtx r1, r2;
20371 enum machine_mode inner = GET_MODE_INNER (mode);
20372 unsigned int inner_bytes = GET_MODE_SIZE (inner);
20374 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
20375 regno = FP_ARG_RETURN;
20376 else
20378 regno = GP_ARG_RETURN;
20380 /* 32-bit is OK since it'll go in r3/r4. */
20381 if (TARGET_32BIT && inner_bytes >= 4)
20382 return gen_rtx_REG (mode, regno);
20385 if (inner_bytes >= 8)
20386 return gen_rtx_REG (mode, regno);
20388 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
20389 const0_rtx);
20390 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
20391 GEN_INT (inner_bytes));
20392 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
20395 /* Define how to find the value returned by a function.
20396 VALTYPE is the data type of the value (as a tree).
20397 If the precise function being called is known, FUNC is its FUNCTION_DECL;
20398 otherwise, FUNC is 0.
20400 On the SPE, both FPs and vectors are returned in r3.
20402 On RS/6000 an integer value is in r3 and a floating-point value is in
20403 fp1, unless -msoft-float. */
20406 rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
20408 enum machine_mode mode;
20409 unsigned int regno;
20411 /* Special handling for structs in darwin64. */
20412 if (rs6000_darwin64_abi
20413 && TYPE_MODE (valtype) == BLKmode
20414 && TREE_CODE (valtype) == RECORD_TYPE
20415 && int_size_in_bytes (valtype) > 0)
20417 CUMULATIVE_ARGS valcum;
20418 rtx valret;
20420 valcum.words = 0;
20421 valcum.fregno = FP_ARG_MIN_REG;
20422 valcum.vregno = ALTIVEC_ARG_MIN_REG;
20423 /* Do a trial code generation as if this were going to be passed as
20424 an argument; if any part goes in memory, we return NULL. */
20425 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
20426 if (valret)
20427 return valret;
20428 /* Otherwise fall through to standard ABI rules. */
20431 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
20433 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20434 return gen_rtx_PARALLEL (DImode,
20435 gen_rtvec (2,
20436 gen_rtx_EXPR_LIST (VOIDmode,
20437 gen_rtx_REG (SImode, GP_ARG_RETURN),
20438 const0_rtx),
20439 gen_rtx_EXPR_LIST (VOIDmode,
20440 gen_rtx_REG (SImode,
20441 GP_ARG_RETURN + 1),
20442 GEN_INT (4))));
20444 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
20446 return gen_rtx_PARALLEL (DCmode,
20447 gen_rtvec (4,
20448 gen_rtx_EXPR_LIST (VOIDmode,
20449 gen_rtx_REG (SImode, GP_ARG_RETURN),
20450 const0_rtx),
20451 gen_rtx_EXPR_LIST (VOIDmode,
20452 gen_rtx_REG (SImode,
20453 GP_ARG_RETURN + 1),
20454 GEN_INT (4)),
20455 gen_rtx_EXPR_LIST (VOIDmode,
20456 gen_rtx_REG (SImode,
20457 GP_ARG_RETURN + 2),
20458 GEN_INT (8)),
20459 gen_rtx_EXPR_LIST (VOIDmode,
20460 gen_rtx_REG (SImode,
20461 GP_ARG_RETURN + 3),
20462 GEN_INT (12))));
20465 if ((INTEGRAL_TYPE_P (valtype)
20466 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
20467 || POINTER_TYPE_P (valtype))
20468 mode = TARGET_32BIT ? SImode : DImode;
20469 else
20470 mode = TYPE_MODE (valtype);
20472 if (DECIMAL_FLOAT_MODE_P (mode))
20473 regno = GP_ARG_RETURN;
20474 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
20475 regno = FP_ARG_RETURN;
20476 else if (TREE_CODE (valtype) == COMPLEX_TYPE
20477 && targetm.calls.split_complex_arg)
20478 return rs6000_complex_function_value (mode);
20479 else if (TREE_CODE (valtype) == VECTOR_TYPE
20480 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
20481 && ALTIVEC_VECTOR_MODE (mode))
20482 regno = ALTIVEC_ARG_RETURN;
20483 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
20484 && (mode == DFmode || mode == DCmode
20485 || mode == TFmode || mode == TCmode))
20486 return spe_build_register_parallel (mode, GP_ARG_RETURN);
20487 else
20488 regno = GP_ARG_RETURN;
20490 return gen_rtx_REG (mode, regno);
20493 /* Define how to find the value returned by a library function
20494 assuming the value has mode MODE. */
20496 rs6000_libcall_value (enum machine_mode mode)
20498 unsigned int regno;
20500 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
20502 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20503 return gen_rtx_PARALLEL (DImode,
20504 gen_rtvec (2,
20505 gen_rtx_EXPR_LIST (VOIDmode,
20506 gen_rtx_REG (SImode, GP_ARG_RETURN),
20507 const0_rtx),
20508 gen_rtx_EXPR_LIST (VOIDmode,
20509 gen_rtx_REG (SImode,
20510 GP_ARG_RETURN + 1),
20511 GEN_INT (4))));
20514 if (DECIMAL_FLOAT_MODE_P (mode))
20515 regno = GP_ARG_RETURN;
20516 else if (SCALAR_FLOAT_MODE_P (mode)
20517 && TARGET_HARD_FLOAT && TARGET_FPRS)
20518 regno = FP_ARG_RETURN;
20519 else if (ALTIVEC_VECTOR_MODE (mode)
20520 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
20521 regno = ALTIVEC_ARG_RETURN;
20522 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
20523 return rs6000_complex_function_value (mode);
20524 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
20525 && (mode == DFmode || mode == DCmode
20526 || mode == TFmode || mode == TCmode))
20527 return spe_build_register_parallel (mode, GP_ARG_RETURN);
20528 else
20529 regno = GP_ARG_RETURN;
20531 return gen_rtx_REG (mode, regno);
20534 /* Define the offset between two registers, FROM to be eliminated and its
20535 replacement TO, at the start of a routine. */
20536 HOST_WIDE_INT
20537 rs6000_initial_elimination_offset (int from, int to)
20539 rs6000_stack_t *info = rs6000_stack_info ();
20540 HOST_WIDE_INT offset;
20542 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20543 offset = info->push_p ? 0 : -info->total_size;
20544 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20546 offset = info->push_p ? 0 : -info->total_size;
20547 if (FRAME_GROWS_DOWNWARD)
20548 offset += info->fixed_size + info->vars_size + info->parm_size;
20550 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
20551 offset = FRAME_GROWS_DOWNWARD
20552 ? info->fixed_size + info->vars_size + info->parm_size
20553 : 0;
20554 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
20555 offset = info->total_size;
20556 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
20557 offset = info->push_p ? info->total_size : 0;
20558 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
20559 offset = 0;
20560 else
20561 gcc_unreachable ();
20563 return offset;
20566 /* Return true if TYPE is a SPE or AltiVec opaque type. */
20568 static bool
20569 rs6000_is_opaque_type (tree type)
20571 return (type == opaque_V2SI_type_node
20572 || type == opaque_V2SF_type_node
20573 || type == opaque_p_V2SI_type_node
20574 || type == opaque_V4SI_type_node);
20577 static rtx
20578 rs6000_dwarf_register_span (rtx reg)
20580 unsigned regno;
20582 if (TARGET_SPE
20583 && (SPE_VECTOR_MODE (GET_MODE (reg))
20584 || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
20586 else
20587 return NULL_RTX;
20589 regno = REGNO (reg);
20591 /* The duality of the SPE register size wreaks all kinds of havoc.
20592 This is a way of distinguishing r0 in 32-bits from r0 in
20593 64-bits. */
20594 return
20595 gen_rtx_PARALLEL (VOIDmode,
20596 BYTES_BIG_ENDIAN
20597 ? gen_rtvec (2,
20598 gen_rtx_REG (SImode, regno + 1200),
20599 gen_rtx_REG (SImode, regno))
20600 : gen_rtvec (2,
20601 gen_rtx_REG (SImode, regno),
20602 gen_rtx_REG (SImode, regno + 1200)));
20605 /* Map internal gcc register numbers to DWARF2 register numbers. */
20607 unsigned int
20608 rs6000_dbx_register_number (unsigned int regno)
20610 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
20611 return regno;
20612 if (regno == MQ_REGNO)
20613 return 100;
20614 if (regno == LINK_REGISTER_REGNUM)
20615 return 108;
20616 if (regno == COUNT_REGISTER_REGNUM)
20617 return 109;
20618 if (CR_REGNO_P (regno))
20619 return regno - CR0_REGNO + 86;
20620 if (regno == XER_REGNO)
20621 return 101;
20622 if (ALTIVEC_REGNO_P (regno))
20623 return regno - FIRST_ALTIVEC_REGNO + 1124;
20624 if (regno == VRSAVE_REGNO)
20625 return 356;
20626 if (regno == VSCR_REGNO)
20627 return 67;
20628 if (regno == SPE_ACC_REGNO)
20629 return 99;
20630 if (regno == SPEFSCR_REGNO)
20631 return 612;
20632 /* SPE high reg number. We get these values of regno from
20633 rs6000_dwarf_register_span. */
20634 gcc_assert (regno >= 1200 && regno < 1232);
20635 return regno;
20638 /* target hook eh_return_filter_mode */
20639 static enum machine_mode
20640 rs6000_eh_return_filter_mode (void)
20642 return TARGET_32BIT ? SImode : word_mode;
20645 /* Target hook for scalar_mode_supported_p. */
20646 static bool
20647 rs6000_scalar_mode_supported_p (enum machine_mode mode)
20649 if (DECIMAL_FLOAT_MODE_P (mode))
20650 return true;
20651 else
20652 return default_scalar_mode_supported_p (mode);
20655 /* Target hook for vector_mode_supported_p. */
20656 static bool
20657 rs6000_vector_mode_supported_p (enum machine_mode mode)
20660 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
20661 return true;
20663 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
20664 return true;
20666 else
20667 return false;
20670 /* Target hook for invalid_arg_for_unprototyped_fn. */
20671 static const char *
20672 invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
20674 return (!rs6000_darwin64_abi
20675 && typelist == 0
20676 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
20677 && (funcdecl == NULL_TREE
20678 || (TREE_CODE (funcdecl) == FUNCTION_DECL
20679 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
20680 ? N_("AltiVec argument passed to unprototyped function")
20681 : NULL;
20684 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
20685 setup by using __stack_chk_fail_local hidden function instead of
20686 calling __stack_chk_fail directly. Otherwise it is better to call
20687 __stack_chk_fail directly. */
20689 static tree
20690 rs6000_stack_protect_fail (void)
20692 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
20693 ? default_hidden_stack_protect_fail ()
20694 : default_external_stack_protect_fail ();
20697 #include "gt-rs6000.h"