re PR target/23649 (gcc.dg/ppc-and-1.c failure due to not using rlwinm)
[official-gcc.git] / gcc / config / rs6000 / rs6000.c
blobca58f306d7f2799f948f75051d809677c560de58
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 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published
10 by the Free Software Foundation; either version 2, or (at your
11 option) any later version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the
20 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "recog.h"
36 #include "obstack.h"
37 #include "tree.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "except.h"
41 #include "function.h"
42 #include "output.h"
43 #include "basic-block.h"
44 #include "integrate.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "hashtab.h"
48 #include "tm_p.h"
49 #include "target.h"
50 #include "target-def.h"
51 #include "langhooks.h"
52 #include "reload.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
55 #include "tree-gimple.h"
56 #include "intl.h"
57 #if TARGET_XCOFF
58 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
59 #endif
60 #if TARGET_MACHO
61 #include "gstab.h" /* for N_SLINE */
62 #endif
64 #ifndef TARGET_NO_PROTOTYPE
65 #define TARGET_NO_PROTOTYPE 0
66 #endif
68 #define min(A,B) ((A) < (B) ? (A) : (B))
69 #define max(A,B) ((A) > (B) ? (A) : (B))
71 /* Structure used to define the rs6000 stack */
72 typedef struct rs6000_stack {
73 int first_gp_reg_save; /* first callee saved GP register used */
74 int first_fp_reg_save; /* first callee saved FP register used */
75 int first_altivec_reg_save; /* first callee saved AltiVec register used */
76 int lr_save_p; /* true if the link reg needs to be saved */
77 int cr_save_p; /* true if the CR reg needs to be saved */
78 unsigned int vrsave_mask; /* mask of vec registers to save */
79 int toc_save_p; /* true if the TOC needs to be saved */
80 int push_p; /* true if we need to allocate stack space */
81 int calls_p; /* true if the function makes any calls */
82 int world_save_p; /* true if we're saving *everything*:
83 r13-r31, cr, f14-f31, vrsave, v20-v31 */
84 enum rs6000_abi abi; /* which ABI to use */
85 int gp_save_offset; /* offset to save GP regs from initial SP */
86 int fp_save_offset; /* offset to save FP regs from initial SP */
87 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
88 int lr_save_offset; /* offset to save LR from initial SP */
89 int cr_save_offset; /* offset to save CR from initial SP */
90 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
91 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
92 int toc_save_offset; /* offset to save the TOC pointer */
93 int varargs_save_offset; /* offset to save the varargs registers */
94 int ehrd_offset; /* offset to EH return data */
95 int reg_size; /* register size (4 or 8) */
96 HOST_WIDE_INT vars_size; /* variable save area size */
97 int parm_size; /* outgoing parameter size */
98 int save_size; /* save area size */
99 int fixed_size; /* fixed size of stack frame */
100 int gp_size; /* size of saved GP registers */
101 int fp_size; /* size of saved FP registers */
102 int altivec_size; /* size of saved AltiVec registers */
103 int cr_size; /* size to hold CR if not in save_size */
104 int lr_size; /* size to hold LR 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 int toc_size; /* size to hold TOC if not in save_size */
111 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
112 int spe_64bit_regs_used;
113 } rs6000_stack_t;
115 /* A C structure for machine-specific, per-function data.
116 This is added to the cfun structure. */
117 typedef struct machine_function GTY(())
119 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
120 int ra_needs_full_frame;
121 /* Some local-dynamic symbol. */
122 const char *some_ld_name;
123 /* Whether the instruction chain has been scanned already. */
124 int insn_chain_scanned_p;
125 /* Flags if __builtin_return_address (0) was used. */
126 int ra_need_lr;
127 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
128 varargs save area. */
129 HOST_WIDE_INT varargs_save_offset;
130 } machine_function;
132 /* Target cpu type */
134 enum processor_type rs6000_cpu;
135 struct rs6000_cpu_select rs6000_select[3] =
137 /* switch name, tune arch */
138 { (const char *)0, "--with-cpu=", 1, 1 },
139 { (const char *)0, "-mcpu=", 1, 1 },
140 { (const char *)0, "-mtune=", 1, 0 },
143 /* Always emit branch hint bits. */
144 static GTY(()) bool rs6000_always_hint;
146 /* Schedule instructions for group formation. */
147 static GTY(()) bool rs6000_sched_groups;
149 /* Support for -msched-costly-dep option. */
150 const char *rs6000_sched_costly_dep_str;
151 enum rs6000_dependence_cost rs6000_sched_costly_dep;
153 /* Support for -minsert-sched-nops option. */
154 const char *rs6000_sched_insert_nops_str;
155 enum rs6000_nop_insertion rs6000_sched_insert_nops;
157 /* Support targetm.vectorize.builtin_mask_for_load. */
158 static GTY(()) tree altivec_builtin_mask_for_load;
160 /* Size of long double */
161 int rs6000_long_double_type_size;
163 /* Whether -mabi=altivec has appeared */
164 int rs6000_altivec_abi;
166 /* Nonzero if we want SPE ABI extensions. */
167 int rs6000_spe_abi;
169 /* Nonzero if floating point operations are done in the GPRs. */
170 int rs6000_float_gprs = 0;
172 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
173 int rs6000_darwin64_abi;
175 /* Set to nonzero once AIX common-mode calls have been defined. */
176 static GTY(()) int common_mode_defined;
178 /* Save information from a "cmpxx" operation until the branch or scc is
179 emitted. */
180 rtx rs6000_compare_op0, rs6000_compare_op1;
181 int rs6000_compare_fp_p;
183 /* Label number of label created for -mrelocatable, to call to so we can
184 get the address of the GOT section */
185 int rs6000_pic_labelno;
187 #ifdef USING_ELFOS_H
188 /* Which abi to adhere to */
189 const char *rs6000_abi_name;
191 /* Semantics of the small data area */
192 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
194 /* Which small data model to use */
195 const char *rs6000_sdata_name = (char *)0;
197 /* Counter for labels which are to be placed in .fixup. */
198 int fixuplabelno = 0;
199 #endif
201 /* Bit size of immediate TLS offsets and string from which it is decoded. */
202 int rs6000_tls_size = 32;
203 const char *rs6000_tls_size_string;
205 /* ABI enumeration available for subtarget to use. */
206 enum rs6000_abi rs6000_current_abi;
208 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
209 int dot_symbols;
211 /* Debug flags */
212 const char *rs6000_debug_name;
213 int rs6000_debug_stack; /* debug stack applications */
214 int rs6000_debug_arg; /* debug argument handling */
216 /* Value is TRUE if register/mode pair is acceptable. */
217 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
219 /* Built in types. */
221 tree rs6000_builtin_types[RS6000_BTI_MAX];
222 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
224 const char *rs6000_traceback_name;
225 static enum {
226 traceback_default = 0,
227 traceback_none,
228 traceback_part,
229 traceback_full
230 } rs6000_traceback;
232 /* Flag to say the TOC is initialized */
233 int toc_initialized;
234 char toc_label_name[10];
236 /* Alias set for saves and restores from the rs6000 stack. */
237 static GTY(()) int rs6000_sr_alias_set;
239 /* Control alignment for fields within structures. */
240 /* String from -malign-XXXXX. */
241 int rs6000_alignment_flags;
243 /* True for any options that were explicitly set. */
244 struct {
245 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
246 bool alignment; /* True if -malign- was used. */
247 bool abi; /* True if -mabi= was used. */
248 bool spe; /* True if -mspe= was used. */
249 bool float_gprs; /* True if -mfloat-gprs= was used. */
250 bool isel; /* True if -misel was used. */
251 bool long_double; /* True if -mlong-double- was used. */
252 } rs6000_explicit_options;
254 struct builtin_description
256 /* mask is not const because we're going to alter it below. This
257 nonsense will go away when we rewrite the -march infrastructure
258 to give us more target flag bits. */
259 unsigned int mask;
260 const enum insn_code icode;
261 const char *const name;
262 const enum rs6000_builtins code;
265 /* Target cpu costs. */
267 struct processor_costs {
268 const int mulsi; /* cost of SImode multiplication. */
269 const int mulsi_const; /* cost of SImode multiplication by constant. */
270 const int mulsi_const9; /* cost of SImode mult by short constant. */
271 const int muldi; /* cost of DImode multiplication. */
272 const int divsi; /* cost of SImode division. */
273 const int divdi; /* cost of DImode division. */
274 const int fp; /* cost of simple SFmode and DFmode insns. */
275 const int dmul; /* cost of DFmode multiplication (and fmadd). */
276 const int sdiv; /* cost of SFmode division (fdivs). */
277 const int ddiv; /* cost of DFmode division (fdiv). */
280 const struct processor_costs *rs6000_cost;
282 /* Processor costs (relative to an add) */
284 /* Instruction size costs on 32bit processors. */
285 static const
286 struct processor_costs size32_cost = {
287 COSTS_N_INSNS (1), /* mulsi */
288 COSTS_N_INSNS (1), /* mulsi_const */
289 COSTS_N_INSNS (1), /* mulsi_const9 */
290 COSTS_N_INSNS (1), /* muldi */
291 COSTS_N_INSNS (1), /* divsi */
292 COSTS_N_INSNS (1), /* divdi */
293 COSTS_N_INSNS (1), /* fp */
294 COSTS_N_INSNS (1), /* dmul */
295 COSTS_N_INSNS (1), /* sdiv */
296 COSTS_N_INSNS (1), /* ddiv */
299 /* Instruction size costs on 64bit processors. */
300 static const
301 struct processor_costs size64_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 costs on RIOS1 processors. */
315 static const
316 struct processor_costs rios1_cost = {
317 COSTS_N_INSNS (5), /* mulsi */
318 COSTS_N_INSNS (4), /* mulsi_const */
319 COSTS_N_INSNS (3), /* mulsi_const9 */
320 COSTS_N_INSNS (5), /* muldi */
321 COSTS_N_INSNS (19), /* divsi */
322 COSTS_N_INSNS (19), /* divdi */
323 COSTS_N_INSNS (2), /* fp */
324 COSTS_N_INSNS (2), /* dmul */
325 COSTS_N_INSNS (19), /* sdiv */
326 COSTS_N_INSNS (19), /* ddiv */
329 /* Instruction costs on RIOS2 processors. */
330 static const
331 struct processor_costs rios2_cost = {
332 COSTS_N_INSNS (2), /* mulsi */
333 COSTS_N_INSNS (2), /* mulsi_const */
334 COSTS_N_INSNS (2), /* mulsi_const9 */
335 COSTS_N_INSNS (2), /* muldi */
336 COSTS_N_INSNS (13), /* divsi */
337 COSTS_N_INSNS (13), /* divdi */
338 COSTS_N_INSNS (2), /* fp */
339 COSTS_N_INSNS (2), /* dmul */
340 COSTS_N_INSNS (17), /* sdiv */
341 COSTS_N_INSNS (17), /* ddiv */
344 /* Instruction costs on RS64A processors. */
345 static const
346 struct processor_costs rs64a_cost = {
347 COSTS_N_INSNS (20), /* mulsi */
348 COSTS_N_INSNS (12), /* mulsi_const */
349 COSTS_N_INSNS (8), /* mulsi_const9 */
350 COSTS_N_INSNS (34), /* muldi */
351 COSTS_N_INSNS (65), /* divsi */
352 COSTS_N_INSNS (67), /* divdi */
353 COSTS_N_INSNS (4), /* fp */
354 COSTS_N_INSNS (4), /* dmul */
355 COSTS_N_INSNS (31), /* sdiv */
356 COSTS_N_INSNS (31), /* ddiv */
359 /* Instruction costs on MPCCORE processors. */
360 static const
361 struct processor_costs mpccore_cost = {
362 COSTS_N_INSNS (2), /* mulsi */
363 COSTS_N_INSNS (2), /* mulsi_const */
364 COSTS_N_INSNS (2), /* mulsi_const9 */
365 COSTS_N_INSNS (2), /* muldi */
366 COSTS_N_INSNS (6), /* divsi */
367 COSTS_N_INSNS (6), /* divdi */
368 COSTS_N_INSNS (4), /* fp */
369 COSTS_N_INSNS (5), /* dmul */
370 COSTS_N_INSNS (10), /* sdiv */
371 COSTS_N_INSNS (17), /* ddiv */
374 /* Instruction costs on PPC403 processors. */
375 static const
376 struct processor_costs ppc403_cost = {
377 COSTS_N_INSNS (4), /* mulsi */
378 COSTS_N_INSNS (4), /* mulsi_const */
379 COSTS_N_INSNS (4), /* mulsi_const9 */
380 COSTS_N_INSNS (4), /* muldi */
381 COSTS_N_INSNS (33), /* divsi */
382 COSTS_N_INSNS (33), /* divdi */
383 COSTS_N_INSNS (11), /* fp */
384 COSTS_N_INSNS (11), /* dmul */
385 COSTS_N_INSNS (11), /* sdiv */
386 COSTS_N_INSNS (11), /* ddiv */
389 /* Instruction costs on PPC405 processors. */
390 static const
391 struct processor_costs ppc405_cost = {
392 COSTS_N_INSNS (5), /* mulsi */
393 COSTS_N_INSNS (4), /* mulsi_const */
394 COSTS_N_INSNS (3), /* mulsi_const9 */
395 COSTS_N_INSNS (5), /* muldi */
396 COSTS_N_INSNS (35), /* divsi */
397 COSTS_N_INSNS (35), /* 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 PPC440 processors. */
405 static const
406 struct processor_costs ppc440_cost = {
407 COSTS_N_INSNS (3), /* mulsi */
408 COSTS_N_INSNS (2), /* mulsi_const */
409 COSTS_N_INSNS (2), /* mulsi_const9 */
410 COSTS_N_INSNS (3), /* muldi */
411 COSTS_N_INSNS (34), /* divsi */
412 COSTS_N_INSNS (34), /* divdi */
413 COSTS_N_INSNS (5), /* fp */
414 COSTS_N_INSNS (5), /* dmul */
415 COSTS_N_INSNS (19), /* sdiv */
416 COSTS_N_INSNS (33), /* ddiv */
419 /* Instruction costs on PPC601 processors. */
420 static const
421 struct processor_costs ppc601_cost = {
422 COSTS_N_INSNS (5), /* mulsi */
423 COSTS_N_INSNS (5), /* mulsi_const */
424 COSTS_N_INSNS (5), /* mulsi_const9 */
425 COSTS_N_INSNS (5), /* muldi */
426 COSTS_N_INSNS (36), /* divsi */
427 COSTS_N_INSNS (36), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (5), /* dmul */
430 COSTS_N_INSNS (17), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
434 /* Instruction costs on PPC603 processors. */
435 static const
436 struct processor_costs ppc603_cost = {
437 COSTS_N_INSNS (5), /* mulsi */
438 COSTS_N_INSNS (3), /* mulsi_const */
439 COSTS_N_INSNS (2), /* mulsi_const9 */
440 COSTS_N_INSNS (5), /* muldi */
441 COSTS_N_INSNS (37), /* divsi */
442 COSTS_N_INSNS (37), /* divdi */
443 COSTS_N_INSNS (3), /* fp */
444 COSTS_N_INSNS (4), /* dmul */
445 COSTS_N_INSNS (18), /* sdiv */
446 COSTS_N_INSNS (33), /* ddiv */
449 /* Instruction costs on PPC604 processors. */
450 static const
451 struct processor_costs ppc604_cost = {
452 COSTS_N_INSNS (4), /* mulsi */
453 COSTS_N_INSNS (4), /* mulsi_const */
454 COSTS_N_INSNS (4), /* mulsi_const9 */
455 COSTS_N_INSNS (4), /* muldi */
456 COSTS_N_INSNS (20), /* divsi */
457 COSTS_N_INSNS (20), /* divdi */
458 COSTS_N_INSNS (3), /* fp */
459 COSTS_N_INSNS (3), /* dmul */
460 COSTS_N_INSNS (18), /* sdiv */
461 COSTS_N_INSNS (32), /* ddiv */
464 /* Instruction costs on PPC604e processors. */
465 static const
466 struct processor_costs ppc604e_cost = {
467 COSTS_N_INSNS (2), /* mulsi */
468 COSTS_N_INSNS (2), /* mulsi_const */
469 COSTS_N_INSNS (2), /* mulsi_const9 */
470 COSTS_N_INSNS (2), /* 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 PPC620 processors. */
480 static const
481 struct processor_costs ppc620_cost = {
482 COSTS_N_INSNS (5), /* mulsi */
483 COSTS_N_INSNS (4), /* mulsi_const */
484 COSTS_N_INSNS (3), /* mulsi_const9 */
485 COSTS_N_INSNS (7), /* muldi */
486 COSTS_N_INSNS (21), /* divsi */
487 COSTS_N_INSNS (37), /* 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 PPC630 processors. */
495 static const
496 struct processor_costs ppc630_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 (17), /* sdiv */
506 COSTS_N_INSNS (21), /* ddiv */
509 /* Instruction costs on PPC750 and PPC7400 processors. */
510 static const
511 struct processor_costs ppc750_cost = {
512 COSTS_N_INSNS (5), /* mulsi */
513 COSTS_N_INSNS (3), /* mulsi_const */
514 COSTS_N_INSNS (2), /* mulsi_const9 */
515 COSTS_N_INSNS (5), /* muldi */
516 COSTS_N_INSNS (17), /* divsi */
517 COSTS_N_INSNS (17), /* divdi */
518 COSTS_N_INSNS (3), /* fp */
519 COSTS_N_INSNS (3), /* dmul */
520 COSTS_N_INSNS (17), /* sdiv */
521 COSTS_N_INSNS (31), /* ddiv */
524 /* Instruction costs on PPC7450 processors. */
525 static const
526 struct processor_costs ppc7450_cost = {
527 COSTS_N_INSNS (4), /* mulsi */
528 COSTS_N_INSNS (3), /* mulsi_const */
529 COSTS_N_INSNS (3), /* mulsi_const9 */
530 COSTS_N_INSNS (4), /* muldi */
531 COSTS_N_INSNS (23), /* divsi */
532 COSTS_N_INSNS (23), /* divdi */
533 COSTS_N_INSNS (5), /* fp */
534 COSTS_N_INSNS (5), /* dmul */
535 COSTS_N_INSNS (21), /* sdiv */
536 COSTS_N_INSNS (35), /* ddiv */
539 /* Instruction costs on PPC8540 processors. */
540 static const
541 struct processor_costs ppc8540_cost = {
542 COSTS_N_INSNS (4), /* mulsi */
543 COSTS_N_INSNS (4), /* mulsi_const */
544 COSTS_N_INSNS (4), /* mulsi_const9 */
545 COSTS_N_INSNS (4), /* muldi */
546 COSTS_N_INSNS (19), /* divsi */
547 COSTS_N_INSNS (19), /* divdi */
548 COSTS_N_INSNS (4), /* fp */
549 COSTS_N_INSNS (4), /* dmul */
550 COSTS_N_INSNS (29), /* sdiv */
551 COSTS_N_INSNS (29), /* ddiv */
554 /* Instruction costs on POWER4 and POWER5 processors. */
555 static const
556 struct processor_costs power4_cost = {
557 COSTS_N_INSNS (3), /* mulsi */
558 COSTS_N_INSNS (2), /* mulsi_const */
559 COSTS_N_INSNS (2), /* mulsi_const9 */
560 COSTS_N_INSNS (4), /* muldi */
561 COSTS_N_INSNS (18), /* divsi */
562 COSTS_N_INSNS (34), /* divdi */
563 COSTS_N_INSNS (3), /* fp */
564 COSTS_N_INSNS (3), /* dmul */
565 COSTS_N_INSNS (17), /* sdiv */
566 COSTS_N_INSNS (17), /* ddiv */
570 static bool rs6000_function_ok_for_sibcall (tree, tree);
571 static const char *rs6000_invalid_within_doloop (rtx);
572 static rtx rs6000_generate_compare (enum rtx_code);
573 static void rs6000_maybe_dead (rtx);
574 static void rs6000_emit_stack_tie (void);
575 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
576 static rtx spe_synthesize_frame_save (rtx);
577 static bool spe_func_has_64bit_regs_p (void);
578 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
579 int, HOST_WIDE_INT);
580 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
581 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
582 static unsigned rs6000_hash_constant (rtx);
583 static unsigned toc_hash_function (const void *);
584 static int toc_hash_eq (const void *, const void *);
585 static int constant_pool_expr_1 (rtx, int *, int *);
586 static bool constant_pool_expr_p (rtx);
587 static bool legitimate_indexed_address_p (rtx, int);
588 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
589 static struct machine_function * rs6000_init_machine_status (void);
590 static bool rs6000_assemble_integer (rtx, unsigned int, int);
591 static bool no_global_regs_above (int);
592 #ifdef HAVE_GAS_HIDDEN
593 static void rs6000_assemble_visibility (tree, int);
594 #endif
595 static int rs6000_ra_ever_killed (void);
596 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
597 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
598 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
599 static const char *rs6000_mangle_fundamental_type (tree);
600 extern const struct attribute_spec rs6000_attribute_table[];
601 static void rs6000_set_default_type_attributes (tree);
602 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
603 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
604 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
605 tree);
606 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
607 static bool rs6000_return_in_memory (tree, tree);
608 static void rs6000_file_start (void);
609 #if TARGET_ELF
610 static unsigned int rs6000_elf_section_type_flags (tree, const char *, int);
611 static void rs6000_elf_asm_out_constructor (rtx, int);
612 static void rs6000_elf_asm_out_destructor (rtx, int);
613 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
614 static void rs6000_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
615 static void rs6000_elf_unique_section (tree, int);
616 static void rs6000_elf_select_rtx_section (enum machine_mode, rtx,
617 unsigned HOST_WIDE_INT);
618 static void rs6000_elf_encode_section_info (tree, rtx, int)
619 ATTRIBUTE_UNUSED;
620 static bool rs6000_elf_in_small_data_p (tree);
621 #endif
622 #if TARGET_XCOFF
623 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
624 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
625 static void rs6000_xcoff_select_section (tree, int, unsigned HOST_WIDE_INT);
626 static void rs6000_xcoff_unique_section (tree, int);
627 static void rs6000_xcoff_select_rtx_section (enum machine_mode, rtx,
628 unsigned HOST_WIDE_INT);
629 static const char * rs6000_xcoff_strip_name_encoding (const char *);
630 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
631 static void rs6000_xcoff_file_start (void);
632 static void rs6000_xcoff_file_end (void);
633 #endif
634 static int rs6000_variable_issue (FILE *, int, rtx, int);
635 static bool rs6000_rtx_costs (rtx, int, int, int *);
636 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
637 static bool is_microcoded_insn (rtx);
638 static int is_dispatch_slot_restricted (rtx);
639 static bool is_cracked_insn (rtx);
640 static bool is_branch_slot_insn (rtx);
641 static int rs6000_adjust_priority (rtx, int);
642 static int rs6000_issue_rate (void);
643 static bool rs6000_is_costly_dependence (rtx, rtx, rtx, int, int);
644 static rtx get_next_active_insn (rtx, rtx);
645 static bool insn_terminates_group_p (rtx , enum group_termination);
646 static bool is_costly_group (rtx *, rtx);
647 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
648 static int redefine_groups (FILE *, int, rtx, rtx);
649 static int pad_groups (FILE *, int, rtx, rtx);
650 static void rs6000_sched_finish (FILE *, int);
651 static int rs6000_use_sched_lookahead (void);
652 static tree rs6000_builtin_mask_for_load (void);
654 static void def_builtin (int, const char *, tree, int);
655 static void rs6000_init_builtins (void);
656 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
657 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
658 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
659 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
660 static void altivec_init_builtins (void);
661 static void rs6000_common_init_builtins (void);
662 static void rs6000_init_libfuncs (void);
664 static void enable_mask_for_builtins (struct builtin_description *, int,
665 enum rs6000_builtins,
666 enum rs6000_builtins);
667 static tree build_opaque_vector_type (tree, int);
668 static void spe_init_builtins (void);
669 static rtx spe_expand_builtin (tree, rtx, bool *);
670 static rtx spe_expand_stv_builtin (enum insn_code, tree);
671 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
672 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
673 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
674 static rs6000_stack_t *rs6000_stack_info (void);
675 static void debug_stack_info (rs6000_stack_t *);
677 static rtx altivec_expand_builtin (tree, rtx, bool *);
678 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
679 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
680 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
681 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
682 static rtx altivec_expand_predicate_builtin (enum insn_code,
683 const char *, tree, rtx);
684 static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
685 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
686 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
687 static rtx altivec_expand_vec_set_builtin (tree);
688 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
689 static int get_element_number (tree, tree);
690 static bool rs6000_handle_option (size_t, const char *, int);
691 static void rs6000_parse_tls_size_option (void);
692 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
693 static int first_altivec_reg_to_save (void);
694 static unsigned int compute_vrsave_mask (void);
695 static void compute_save_world_info (rs6000_stack_t *info_ptr);
696 static void is_altivec_return_reg (rtx, void *);
697 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
698 int easy_vector_constant (rtx, enum machine_mode);
699 static bool rs6000_is_opaque_type (tree);
700 static rtx rs6000_dwarf_register_span (rtx);
701 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
702 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
703 static rtx rs6000_tls_get_addr (void);
704 static rtx rs6000_got_sym (void);
705 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
706 static const char *rs6000_get_some_local_dynamic_name (void);
707 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
708 static rtx rs6000_complex_function_value (enum machine_mode);
709 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
710 enum machine_mode, tree);
711 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
712 HOST_WIDE_INT);
713 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
714 tree, HOST_WIDE_INT);
715 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
716 HOST_WIDE_INT,
717 rtx[], int *);
718 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
719 tree, HOST_WIDE_INT,
720 rtx[], int *);
721 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, tree, int, bool);
722 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
723 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
724 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
725 enum machine_mode, tree,
726 int *, int);
727 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
728 tree, bool);
729 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
730 tree, bool);
731 static const char *invalid_arg_for_unprototyped_fn (tree, tree, tree);
732 #if TARGET_MACHO
733 static void macho_branch_islands (void);
734 static void add_compiler_branch_island (tree, tree, int);
735 static int no_previous_def (tree function_name);
736 static tree get_prev_label (tree function_name);
737 static void rs6000_darwin_file_start (void);
738 #endif
740 static tree rs6000_build_builtin_va_list (void);
741 static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
742 static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
743 static bool rs6000_vector_mode_supported_p (enum machine_mode);
744 static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
745 enum machine_mode);
746 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
747 enum machine_mode);
748 static int get_vsel_insn (enum machine_mode);
749 static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
750 static tree rs6000_stack_protect_fail (void);
752 const int INSN_NOT_AVAILABLE = -1;
753 static enum machine_mode rs6000_eh_return_filter_mode (void);
755 /* Hash table stuff for keeping track of TOC entries. */
757 struct toc_hash_struct GTY(())
759 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
760 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
761 rtx key;
762 enum machine_mode key_mode;
763 int labelno;
766 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
768 /* Default register names. */
769 char rs6000_reg_names[][8] =
771 "0", "1", "2", "3", "4", "5", "6", "7",
772 "8", "9", "10", "11", "12", "13", "14", "15",
773 "16", "17", "18", "19", "20", "21", "22", "23",
774 "24", "25", "26", "27", "28", "29", "30", "31",
775 "0", "1", "2", "3", "4", "5", "6", "7",
776 "8", "9", "10", "11", "12", "13", "14", "15",
777 "16", "17", "18", "19", "20", "21", "22", "23",
778 "24", "25", "26", "27", "28", "29", "30", "31",
779 "mq", "lr", "ctr","ap",
780 "0", "1", "2", "3", "4", "5", "6", "7",
781 "xer",
782 /* AltiVec registers. */
783 "0", "1", "2", "3", "4", "5", "6", "7",
784 "8", "9", "10", "11", "12", "13", "14", "15",
785 "16", "17", "18", "19", "20", "21", "22", "23",
786 "24", "25", "26", "27", "28", "29", "30", "31",
787 "vrsave", "vscr",
788 /* SPE registers. */
789 "spe_acc", "spefscr",
790 /* Soft frame pointer. */
791 "sfp"
794 #ifdef TARGET_REGNAMES
795 static const char alt_reg_names[][8] =
797 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
798 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
799 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
800 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
801 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
802 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
803 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
804 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
805 "mq", "lr", "ctr", "ap",
806 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
807 "xer",
808 /* AltiVec registers. */
809 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
810 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
811 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
812 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
813 "vrsave", "vscr",
814 /* SPE registers. */
815 "spe_acc", "spefscr",
816 /* Soft frame pointer. */
817 "sfp"
819 #endif
821 #ifndef MASK_STRICT_ALIGN
822 #define MASK_STRICT_ALIGN 0
823 #endif
824 #ifndef TARGET_PROFILE_KERNEL
825 #define TARGET_PROFILE_KERNEL 0
826 #endif
828 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
829 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
831 /* Initialize the GCC target structure. */
832 #undef TARGET_ATTRIBUTE_TABLE
833 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
834 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
835 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
837 #undef TARGET_ASM_ALIGNED_DI_OP
838 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
840 /* Default unaligned ops are only provided for ELF. Find the ops needed
841 for non-ELF systems. */
842 #ifndef OBJECT_FORMAT_ELF
843 #if TARGET_XCOFF
844 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
845 64-bit targets. */
846 #undef TARGET_ASM_UNALIGNED_HI_OP
847 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
848 #undef TARGET_ASM_UNALIGNED_SI_OP
849 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
850 #undef TARGET_ASM_UNALIGNED_DI_OP
851 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
852 #else
853 /* For Darwin. */
854 #undef TARGET_ASM_UNALIGNED_HI_OP
855 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
856 #undef TARGET_ASM_UNALIGNED_SI_OP
857 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
858 #undef TARGET_ASM_UNALIGNED_DI_OP
859 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
860 #undef TARGET_ASM_ALIGNED_DI_OP
861 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
862 #endif
863 #endif
865 /* This hook deals with fixups for relocatable code and DI-mode objects
866 in 64-bit code. */
867 #undef TARGET_ASM_INTEGER
868 #define TARGET_ASM_INTEGER rs6000_assemble_integer
870 #ifdef HAVE_GAS_HIDDEN
871 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
872 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
873 #endif
875 #undef TARGET_HAVE_TLS
876 #define TARGET_HAVE_TLS HAVE_AS_TLS
878 #undef TARGET_CANNOT_FORCE_CONST_MEM
879 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
881 #undef TARGET_ASM_FUNCTION_PROLOGUE
882 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
883 #undef TARGET_ASM_FUNCTION_EPILOGUE
884 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
886 #undef TARGET_SCHED_VARIABLE_ISSUE
887 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
889 #undef TARGET_SCHED_ISSUE_RATE
890 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
891 #undef TARGET_SCHED_ADJUST_COST
892 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
893 #undef TARGET_SCHED_ADJUST_PRIORITY
894 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
895 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
896 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
897 #undef TARGET_SCHED_FINISH
898 #define TARGET_SCHED_FINISH rs6000_sched_finish
900 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
901 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
903 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
904 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
906 #undef TARGET_INIT_BUILTINS
907 #define TARGET_INIT_BUILTINS rs6000_init_builtins
909 #undef TARGET_EXPAND_BUILTIN
910 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
912 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
913 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
915 #undef TARGET_INIT_LIBFUNCS
916 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
918 #if TARGET_MACHO
919 #undef TARGET_BINDS_LOCAL_P
920 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
921 #endif
923 #undef TARGET_ASM_OUTPUT_MI_THUNK
924 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
926 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
927 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
929 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
930 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
932 #undef TARGET_INVALID_WITHIN_DOLOOP
933 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
935 #undef TARGET_RTX_COSTS
936 #define TARGET_RTX_COSTS rs6000_rtx_costs
937 #undef TARGET_ADDRESS_COST
938 #define TARGET_ADDRESS_COST hook_int_rtx_0
940 #undef TARGET_VECTOR_OPAQUE_P
941 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
943 #undef TARGET_DWARF_REGISTER_SPAN
944 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
946 /* On rs6000, function arguments are promoted, as are function return
947 values. */
948 #undef TARGET_PROMOTE_FUNCTION_ARGS
949 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
950 #undef TARGET_PROMOTE_FUNCTION_RETURN
951 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
953 #undef TARGET_RETURN_IN_MEMORY
954 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
956 #undef TARGET_SETUP_INCOMING_VARARGS
957 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
959 /* Always strict argument naming on rs6000. */
960 #undef TARGET_STRICT_ARGUMENT_NAMING
961 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
962 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
963 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
964 #undef TARGET_SPLIT_COMPLEX_ARG
965 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
966 #undef TARGET_MUST_PASS_IN_STACK
967 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
968 #undef TARGET_PASS_BY_REFERENCE
969 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
970 #undef TARGET_ARG_PARTIAL_BYTES
971 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
973 #undef TARGET_BUILD_BUILTIN_VA_LIST
974 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
976 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
977 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
979 #undef TARGET_EH_RETURN_FILTER_MODE
980 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
982 #undef TARGET_VECTOR_MODE_SUPPORTED_P
983 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
985 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
986 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
988 #undef TARGET_HANDLE_OPTION
989 #define TARGET_HANDLE_OPTION rs6000_handle_option
991 #undef TARGET_DEFAULT_TARGET_FLAGS
992 #define TARGET_DEFAULT_TARGET_FLAGS \
993 (TARGET_DEFAULT | MASK_SCHED_PROLOG)
995 #undef TARGET_STACK_PROTECT_FAIL
996 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
998 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
999 The PowerPC architecture requires only weak consistency among
1000 processors--that is, memory accesses between processors need not be
1001 sequentially consistent and memory accesses among processors can occur
1002 in any order. The ability to order memory accesses weakly provides
1003 opportunities for more efficient use of the system bus. Unless a
1004 dependency exists, the 604e allows read operations to precede store
1005 operations. */
1006 #undef TARGET_RELAXED_ORDERING
1007 #define TARGET_RELAXED_ORDERING true
1009 #ifdef HAVE_AS_TLS
1010 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1011 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1012 #endif
1014 struct gcc_target targetm = TARGET_INITIALIZER;
1017 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1018 MODE. */
1019 static int
1020 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1022 /* The GPRs can hold any mode, but values bigger than one register
1023 cannot go past R31. */
1024 if (INT_REGNO_P (regno))
1025 return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
1027 /* The float registers can only hold floating modes and DImode. */
1028 if (FP_REGNO_P (regno))
1029 return
1030 (GET_MODE_CLASS (mode) == MODE_FLOAT
1031 && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
1032 || (GET_MODE_CLASS (mode) == MODE_INT
1033 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
1035 /* The CR register can only hold CC modes. */
1036 if (CR_REGNO_P (regno))
1037 return GET_MODE_CLASS (mode) == MODE_CC;
1039 if (XER_REGNO_P (regno))
1040 return mode == PSImode;
1042 /* AltiVec only in AldyVec registers. */
1043 if (ALTIVEC_REGNO_P (regno))
1044 return ALTIVEC_VECTOR_MODE (mode);
1046 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1047 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1048 return 1;
1050 /* We cannot put TImode anywhere except general register and it must be
1051 able to fit within the register set. */
1053 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1056 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1057 static void
1058 rs6000_init_hard_regno_mode_ok (void)
1060 int r, m;
1062 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1063 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1064 if (rs6000_hard_regno_mode_ok (r, m))
1065 rs6000_hard_regno_mode_ok_p[m][r] = true;
1068 /* If not otherwise specified by a target, make 'long double' equivalent to
1069 'double'. */
1071 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1072 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1073 #endif
1075 /* Override command line options. Mostly we process the processor
1076 type and sometimes adjust other TARGET_ options. */
1078 void
1079 rs6000_override_options (const char *default_cpu)
1081 size_t i, j;
1082 struct rs6000_cpu_select *ptr;
1083 int set_masks;
1085 /* Simplifications for entries below. */
1087 enum {
1088 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1089 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1092 /* This table occasionally claims that a processor does not support
1093 a particular feature even though it does, but the feature is slower
1094 than the alternative. Thus, it shouldn't be relied on as a
1095 complete description of the processor's support.
1097 Please keep this list in order, and don't forget to update the
1098 documentation in invoke.texi when adding a new processor or
1099 flag. */
1100 static struct ptt
1102 const char *const name; /* Canonical processor name. */
1103 const enum processor_type processor; /* Processor type enum value. */
1104 const int target_enable; /* Target flags to enable. */
1105 } const processor_target_table[]
1106 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1107 {"403", PROCESSOR_PPC403,
1108 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1109 {"405", PROCESSOR_PPC405, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1110 {"405fp", PROCESSOR_PPC405, POWERPC_BASE_MASK},
1111 {"440", PROCESSOR_PPC440, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1112 {"440fp", PROCESSOR_PPC440, POWERPC_BASE_MASK},
1113 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1114 {"601", PROCESSOR_PPC601,
1115 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1116 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1117 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1118 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1119 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1120 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1121 {"620", PROCESSOR_PPC620,
1122 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1123 {"630", PROCESSOR_PPC630,
1124 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1125 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1126 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1127 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1128 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1129 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1130 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1131 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1132 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1133 /* 8548 has a dummy entry for now. */
1134 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1135 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1136 {"970", PROCESSOR_POWER4,
1137 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1138 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1139 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1140 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1141 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1142 {"G5", PROCESSOR_POWER4,
1143 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1144 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1145 {"power2", PROCESSOR_POWER,
1146 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1147 {"power3", PROCESSOR_PPC630,
1148 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1149 {"power4", PROCESSOR_POWER4,
1150 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
1151 {"power5", PROCESSOR_POWER5,
1152 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1153 | MASK_MFCRF | MASK_POPCNTB},
1154 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1155 {"powerpc64", PROCESSOR_POWERPC64,
1156 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1157 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1158 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1159 {"rios2", PROCESSOR_RIOS2,
1160 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1161 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1162 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1163 {"rs64", PROCESSOR_RS64A,
1164 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1167 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
1169 /* Some OSs don't support saving the high part of 64-bit registers on
1170 context switch. Other OSs don't support saving Altivec registers.
1171 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1172 settings; if the user wants either, the user must explicitly specify
1173 them and we won't interfere with the user's specification. */
1175 enum {
1176 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1177 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT
1178 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1179 | MASK_MFCRF)
1182 rs6000_init_hard_regno_mode_ok ();
1184 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
1185 #ifdef OS_MISSING_POWERPC64
1186 if (OS_MISSING_POWERPC64)
1187 set_masks &= ~MASK_POWERPC64;
1188 #endif
1189 #ifdef OS_MISSING_ALTIVEC
1190 if (OS_MISSING_ALTIVEC)
1191 set_masks &= ~MASK_ALTIVEC;
1192 #endif
1194 /* Don't override by the processor default if given explicitly. */
1195 set_masks &= ~target_flags_explicit;
1197 /* Identify the processor type. */
1198 rs6000_select[0].string = default_cpu;
1199 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
1201 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
1203 ptr = &rs6000_select[i];
1204 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
1206 for (j = 0; j < ptt_size; j++)
1207 if (! strcmp (ptr->string, processor_target_table[j].name))
1209 if (ptr->set_tune_p)
1210 rs6000_cpu = processor_target_table[j].processor;
1212 if (ptr->set_arch_p)
1214 target_flags &= ~set_masks;
1215 target_flags |= (processor_target_table[j].target_enable
1216 & set_masks);
1218 break;
1221 if (j == ptt_size)
1222 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
1226 if (TARGET_E500)
1227 rs6000_isel = 1;
1229 /* If we are optimizing big endian systems for space, use the load/store
1230 multiple and string instructions. */
1231 if (BYTES_BIG_ENDIAN && optimize_size)
1232 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
1234 /* Don't allow -mmultiple or -mstring on little endian systems
1235 unless the cpu is a 750, because the hardware doesn't support the
1236 instructions used in little endian mode, and causes an alignment
1237 trap. The 750 does not cause an alignment trap (except when the
1238 target is unaligned). */
1240 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
1242 if (TARGET_MULTIPLE)
1244 target_flags &= ~MASK_MULTIPLE;
1245 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
1246 warning (0, "-mmultiple is not supported on little endian systems");
1249 if (TARGET_STRING)
1251 target_flags &= ~MASK_STRING;
1252 if ((target_flags_explicit & MASK_STRING) != 0)
1253 warning (0, "-mstring is not supported on little endian systems");
1257 /* Set debug flags */
1258 if (rs6000_debug_name)
1260 if (! strcmp (rs6000_debug_name, "all"))
1261 rs6000_debug_stack = rs6000_debug_arg = 1;
1262 else if (! strcmp (rs6000_debug_name, "stack"))
1263 rs6000_debug_stack = 1;
1264 else if (! strcmp (rs6000_debug_name, "arg"))
1265 rs6000_debug_arg = 1;
1266 else
1267 error ("unknown -mdebug-%s switch", rs6000_debug_name);
1270 if (rs6000_traceback_name)
1272 if (! strncmp (rs6000_traceback_name, "full", 4))
1273 rs6000_traceback = traceback_full;
1274 else if (! strncmp (rs6000_traceback_name, "part", 4))
1275 rs6000_traceback = traceback_part;
1276 else if (! strncmp (rs6000_traceback_name, "no", 2))
1277 rs6000_traceback = traceback_none;
1278 else
1279 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1280 rs6000_traceback_name);
1283 if (!rs6000_explicit_options.long_double)
1284 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1286 /* Set Altivec ABI as default for powerpc64 linux. */
1287 if (TARGET_ELF && TARGET_64BIT)
1289 rs6000_altivec_abi = 1;
1290 TARGET_ALTIVEC_VRSAVE = 1;
1293 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1294 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1296 rs6000_darwin64_abi = 1;
1297 #if TARGET_MACHO
1298 darwin_one_byte_bool = 1;
1299 #endif
1300 /* Default to natural alignment, for better performance. */
1301 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
1304 /* Handle -mtls-size option. */
1305 rs6000_parse_tls_size_option ();
1307 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1308 SUBTARGET_OVERRIDE_OPTIONS;
1309 #endif
1310 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1311 SUBSUBTARGET_OVERRIDE_OPTIONS;
1312 #endif
1313 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1314 SUB3TARGET_OVERRIDE_OPTIONS;
1315 #endif
1317 if (TARGET_E500)
1319 if (TARGET_ALTIVEC)
1320 error ("AltiVec and E500 instructions cannot coexist");
1322 /* The e500 does not have string instructions, and we set
1323 MASK_STRING above when optimizing for size. */
1324 if ((target_flags & MASK_STRING) != 0)
1325 target_flags = target_flags & ~MASK_STRING;
1327 else if (rs6000_select[1].string != NULL)
1329 /* For the powerpc-eabispe configuration, we set all these by
1330 default, so let's unset them if we manually set another
1331 CPU that is not the E500. */
1332 if (!rs6000_explicit_options.abi)
1333 rs6000_spe_abi = 0;
1334 if (!rs6000_explicit_options.spe)
1335 rs6000_spe = 0;
1336 if (!rs6000_explicit_options.float_gprs)
1337 rs6000_float_gprs = 0;
1338 if (!rs6000_explicit_options.isel)
1339 rs6000_isel = 0;
1340 if (!rs6000_explicit_options.long_double)
1341 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1344 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
1345 && rs6000_cpu != PROCESSOR_POWER5);
1346 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
1347 || rs6000_cpu == PROCESSOR_POWER5);
1349 rs6000_sched_restricted_insns_priority
1350 = (rs6000_sched_groups ? 1 : 0);
1352 /* Handle -msched-costly-dep option. */
1353 rs6000_sched_costly_dep
1354 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
1356 if (rs6000_sched_costly_dep_str)
1358 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
1359 rs6000_sched_costly_dep = no_dep_costly;
1360 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
1361 rs6000_sched_costly_dep = all_deps_costly;
1362 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
1363 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
1364 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
1365 rs6000_sched_costly_dep = store_to_load_dep_costly;
1366 else
1367 rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
1370 /* Handle -minsert-sched-nops option. */
1371 rs6000_sched_insert_nops
1372 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
1374 if (rs6000_sched_insert_nops_str)
1376 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
1377 rs6000_sched_insert_nops = sched_finish_none;
1378 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
1379 rs6000_sched_insert_nops = sched_finish_pad_groups;
1380 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
1381 rs6000_sched_insert_nops = sched_finish_regroup_exact;
1382 else
1383 rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
1386 #ifdef TARGET_REGNAMES
1387 /* If the user desires alternate register names, copy in the
1388 alternate names now. */
1389 if (TARGET_REGNAMES)
1390 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
1391 #endif
1393 /* Set aix_struct_return last, after the ABI is determined.
1394 If -maix-struct-return or -msvr4-struct-return was explicitly
1395 used, don't override with the ABI default. */
1396 if (!rs6000_explicit_options.aix_struct_ret)
1397 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
1399 if (TARGET_LONG_DOUBLE_128
1400 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
1401 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
1403 /* Allocate an alias set for register saves & restores from stack. */
1404 rs6000_sr_alias_set = new_alias_set ();
1406 if (TARGET_TOC)
1407 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
1409 /* We can only guarantee the availability of DI pseudo-ops when
1410 assembling for 64-bit targets. */
1411 if (!TARGET_64BIT)
1413 targetm.asm_out.aligned_op.di = NULL;
1414 targetm.asm_out.unaligned_op.di = NULL;
1417 /* Set branch target alignment, if not optimizing for size. */
1418 if (!optimize_size)
1420 if (rs6000_sched_groups)
1422 if (align_functions <= 0)
1423 align_functions = 16;
1424 if (align_jumps <= 0)
1425 align_jumps = 16;
1426 if (align_loops <= 0)
1427 align_loops = 16;
1429 if (align_jumps_max_skip <= 0)
1430 align_jumps_max_skip = 15;
1431 if (align_loops_max_skip <= 0)
1432 align_loops_max_skip = 15;
1435 /* Arrange to save and restore machine status around nested functions. */
1436 init_machine_status = rs6000_init_machine_status;
1438 /* We should always be splitting complex arguments, but we can't break
1439 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1440 if (DEFAULT_ABI != ABI_AIX)
1441 targetm.calls.split_complex_arg = NULL;
1443 /* Initialize rs6000_cost with the appropriate target costs. */
1444 if (optimize_size)
1445 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
1446 else
1447 switch (rs6000_cpu)
1449 case PROCESSOR_RIOS1:
1450 rs6000_cost = &rios1_cost;
1451 break;
1453 case PROCESSOR_RIOS2:
1454 rs6000_cost = &rios2_cost;
1455 break;
1457 case PROCESSOR_RS64A:
1458 rs6000_cost = &rs64a_cost;
1459 break;
1461 case PROCESSOR_MPCCORE:
1462 rs6000_cost = &mpccore_cost;
1463 break;
1465 case PROCESSOR_PPC403:
1466 rs6000_cost = &ppc403_cost;
1467 break;
1469 case PROCESSOR_PPC405:
1470 rs6000_cost = &ppc405_cost;
1471 break;
1473 case PROCESSOR_PPC440:
1474 rs6000_cost = &ppc440_cost;
1475 break;
1477 case PROCESSOR_PPC601:
1478 rs6000_cost = &ppc601_cost;
1479 break;
1481 case PROCESSOR_PPC603:
1482 rs6000_cost = &ppc603_cost;
1483 break;
1485 case PROCESSOR_PPC604:
1486 rs6000_cost = &ppc604_cost;
1487 break;
1489 case PROCESSOR_PPC604e:
1490 rs6000_cost = &ppc604e_cost;
1491 break;
1493 case PROCESSOR_PPC620:
1494 rs6000_cost = &ppc620_cost;
1495 break;
1497 case PROCESSOR_PPC630:
1498 rs6000_cost = &ppc630_cost;
1499 break;
1501 case PROCESSOR_PPC750:
1502 case PROCESSOR_PPC7400:
1503 rs6000_cost = &ppc750_cost;
1504 break;
1506 case PROCESSOR_PPC7450:
1507 rs6000_cost = &ppc7450_cost;
1508 break;
1510 case PROCESSOR_PPC8540:
1511 rs6000_cost = &ppc8540_cost;
1512 break;
1514 case PROCESSOR_POWER4:
1515 case PROCESSOR_POWER5:
1516 rs6000_cost = &power4_cost;
1517 break;
1519 default:
1520 gcc_unreachable ();
1524 /* Implement targetm.vectorize.builtin_mask_for_load. */
1525 static tree
1526 rs6000_builtin_mask_for_load (void)
1528 if (TARGET_ALTIVEC)
1529 return altivec_builtin_mask_for_load;
1530 else
1531 return 0;
1534 /* Handle generic options of the form -mfoo=yes/no.
1535 NAME is the option name.
1536 VALUE is the option value.
1537 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1538 whether the option value is 'yes' or 'no' respectively. */
1539 static void
1540 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
1542 if (value == 0)
1543 return;
1544 else if (!strcmp (value, "yes"))
1545 *flag = 1;
1546 else if (!strcmp (value, "no"))
1547 *flag = 0;
1548 else
1549 error ("unknown -m%s= option specified: '%s'", name, value);
1552 /* Validate and record the size specified with the -mtls-size option. */
1554 static void
1555 rs6000_parse_tls_size_option (void)
1557 if (rs6000_tls_size_string == 0)
1558 return;
1559 else if (strcmp (rs6000_tls_size_string, "16") == 0)
1560 rs6000_tls_size = 16;
1561 else if (strcmp (rs6000_tls_size_string, "32") == 0)
1562 rs6000_tls_size = 32;
1563 else if (strcmp (rs6000_tls_size_string, "64") == 0)
1564 rs6000_tls_size = 64;
1565 else
1566 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
1569 void
1570 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1572 if (DEFAULT_ABI == ABI_DARWIN)
1573 /* The Darwin libraries never set errno, so we might as well
1574 avoid calling them when that's the only reason we would. */
1575 flag_errno_math = 0;
1578 /* Implement TARGET_HANDLE_OPTION. */
1580 static bool
1581 rs6000_handle_option (size_t code, const char *arg, int value)
1583 switch (code)
1585 case OPT_mno_power:
1586 target_flags &= ~(MASK_POWER | MASK_POWER2
1587 | MASK_MULTIPLE | MASK_STRING);
1588 target_flags_explicit |= (MASK_POWER | MASK_POWER2
1589 | MASK_MULTIPLE | MASK_STRING);
1590 break;
1591 case OPT_mno_powerpc:
1592 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
1593 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1594 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
1595 | MASK_PPC_GFXOPT | MASK_POWERPC64);
1596 break;
1597 case OPT_mfull_toc:
1598 target_flags &= ~(MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC
1599 | MASK_NO_SUM_IN_TOC);
1600 target_flags_explicit |= (MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC
1601 | MASK_NO_SUM_IN_TOC);
1602 #ifdef TARGET_USES_SYSV4_OPT
1603 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1604 just the same as -mminimal-toc. */
1605 target_flags |= MASK_MINIMAL_TOC;
1606 target_flags_explicit |= MASK_MINIMAL_TOC;
1607 #endif
1608 break;
1610 #ifdef TARGET_USES_SYSV4_OPT
1611 case OPT_mtoc:
1612 /* Make -mtoc behave like -mminimal-toc. */
1613 target_flags |= MASK_MINIMAL_TOC;
1614 target_flags_explicit |= MASK_MINIMAL_TOC;
1615 break;
1616 #endif
1618 #ifdef TARGET_USES_AIX64_OPT
1619 case OPT_maix64:
1620 #else
1621 case OPT_m64:
1622 #endif
1623 target_flags |= MASK_POWERPC64 | MASK_POWERPC | MASK_PPC_GFXOPT;
1624 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC
1625 | MASK_PPC_GFXOPT;
1626 break;
1628 #ifdef TARGET_USES_AIX64_OPT
1629 case OPT_maix32:
1630 #else
1631 case OPT_m32:
1632 #endif
1633 target_flags &= ~MASK_POWERPC64;
1634 target_flags_explicit |= MASK_POWERPC64;
1635 break;
1637 case OPT_minsert_sched_nops_:
1638 rs6000_sched_insert_nops_str = arg;
1639 break;
1641 case OPT_mminimal_toc:
1642 if (value == 1)
1644 target_flags &= ~(MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC);
1645 target_flags_explicit |= (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC);
1647 break;
1649 case OPT_mpower:
1650 if (value == 1)
1652 target_flags |= (MASK_MULTIPLE | MASK_STRING);
1653 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
1655 break;
1657 case OPT_mpower2:
1658 if (value == 1)
1660 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1661 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1663 break;
1665 case OPT_mpowerpc_gpopt:
1666 case OPT_mpowerpc_gfxopt:
1667 if (value == 1)
1669 target_flags |= MASK_POWERPC;
1670 target_flags_explicit |= MASK_POWERPC;
1672 break;
1674 case OPT_maix_struct_return:
1675 case OPT_msvr4_struct_return:
1676 rs6000_explicit_options.aix_struct_ret = true;
1677 break;
1679 case OPT_mvrsave_:
1680 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
1681 break;
1683 case OPT_misel_:
1684 rs6000_explicit_options.isel = true;
1685 rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
1686 break;
1688 case OPT_mspe_:
1689 rs6000_explicit_options.spe = true;
1690 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
1691 /* No SPE means 64-bit long doubles, even if an E500. */
1692 if (!rs6000_spe)
1693 rs6000_long_double_type_size = 64;
1694 break;
1696 case OPT_mdebug_:
1697 rs6000_debug_name = arg;
1698 break;
1700 #ifdef TARGET_USES_SYSV4_OPT
1701 case OPT_mcall_:
1702 rs6000_abi_name = arg;
1703 break;
1705 case OPT_msdata_:
1706 rs6000_sdata_name = arg;
1707 break;
1709 case OPT_mtls_size_:
1710 rs6000_tls_size_string = arg;
1711 break;
1713 case OPT_mrelocatable:
1714 if (value == 1)
1716 target_flags |= MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC;
1717 target_flags_explicit |= MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC;
1719 break;
1721 case OPT_mrelocatable_lib:
1722 if (value == 1)
1724 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC
1725 | MASK_NO_FP_IN_TOC;
1726 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC
1727 | MASK_NO_FP_IN_TOC;
1729 else
1731 target_flags &= ~MASK_RELOCATABLE;
1732 target_flags_explicit |= MASK_RELOCATABLE;
1734 break;
1735 #endif
1737 case OPT_mabi_:
1738 rs6000_explicit_options.abi = true;
1739 if (!strcmp (arg, "altivec"))
1741 rs6000_altivec_abi = 1;
1742 rs6000_spe_abi = 0;
1744 else if (! strcmp (arg, "no-altivec"))
1745 rs6000_altivec_abi = 0;
1746 else if (! strcmp (arg, "spe"))
1748 rs6000_spe_abi = 1;
1749 rs6000_altivec_abi = 0;
1750 if (!TARGET_SPE_ABI)
1751 error ("not configured for ABI: '%s'", arg);
1753 else if (! strcmp (arg, "no-spe"))
1754 rs6000_spe_abi = 0;
1756 /* These are here for testing during development only, do not
1757 document in the manual please. */
1758 else if (! strcmp (arg, "d64"))
1760 rs6000_darwin64_abi = 1;
1761 warning (0, "Using darwin64 ABI");
1763 else if (! strcmp (arg, "d32"))
1765 rs6000_darwin64_abi = 0;
1766 warning (0, "Using old darwin ABI");
1769 else
1771 error ("unknown ABI specified: '%s'", arg);
1772 return false;
1774 break;
1776 case OPT_mcpu_:
1777 rs6000_select[1].string = arg;
1778 break;
1780 case OPT_mtune_:
1781 rs6000_select[2].string = arg;
1782 break;
1784 case OPT_mtraceback_:
1785 rs6000_traceback_name = arg;
1786 break;
1788 case OPT_mfloat_gprs_:
1789 rs6000_explicit_options.float_gprs = true;
1790 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
1791 rs6000_float_gprs = 1;
1792 else if (! strcmp (arg, "double"))
1793 rs6000_float_gprs = 2;
1794 else if (! strcmp (arg, "no"))
1795 rs6000_float_gprs = 0;
1796 else
1798 error ("invalid option for -mfloat-gprs: '%s'", arg);
1799 return false;
1801 break;
1803 case OPT_mlong_double_:
1804 rs6000_explicit_options.long_double = true;
1805 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1806 if (value != 64 && value != 128)
1808 error ("Unknown switch -mlong-double-%s", arg);
1809 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1810 return false;
1812 else
1813 rs6000_long_double_type_size = value;
1814 break;
1816 case OPT_msched_costly_dep_:
1817 rs6000_sched_costly_dep_str = arg;
1818 break;
1820 case OPT_malign_:
1821 rs6000_explicit_options.alignment = true;
1822 if (! strcmp (arg, "power"))
1824 /* On 64-bit Darwin, power alignment is ABI-incompatible with
1825 some C library functions, so warn about it. The flag may be
1826 useful for performance studies from time to time though, so
1827 don't disable it entirely. */
1828 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1829 warning (0, "-malign-power is not supported for 64-bit Darwin;"
1830 " it is incompatible with the installed C and C++ libraries");
1831 rs6000_alignment_flags = MASK_ALIGN_POWER;
1833 else if (! strcmp (arg, "natural"))
1834 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
1835 else
1837 error ("unknown -malign-XXXXX option specified: '%s'", arg);
1838 return false;
1840 break;
1842 return true;
1845 /* Do anything needed at the start of the asm file. */
1847 static void
1848 rs6000_file_start (void)
1850 size_t i;
1851 char buffer[80];
1852 const char *start = buffer;
1853 struct rs6000_cpu_select *ptr;
1854 const char *default_cpu = TARGET_CPU_DEFAULT;
1855 FILE *file = asm_out_file;
1857 default_file_start ();
1859 #ifdef TARGET_BI_ARCH
1860 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
1861 default_cpu = 0;
1862 #endif
1864 if (flag_verbose_asm)
1866 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
1867 rs6000_select[0].string = default_cpu;
1869 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
1871 ptr = &rs6000_select[i];
1872 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
1874 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
1875 start = "";
1879 if (PPC405_ERRATUM77)
1881 fprintf (file, "%s PPC405CR_ERRATUM77", start);
1882 start = "";
1885 #ifdef USING_ELFOS_H
1886 switch (rs6000_sdata)
1888 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
1889 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
1890 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
1891 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
1894 if (rs6000_sdata && g_switch_value)
1896 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
1897 g_switch_value);
1898 start = "";
1900 #endif
1902 if (*start == '\0')
1903 putc ('\n', file);
1906 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
1908 toc_section ();
1909 text_section ();
1914 /* Return nonzero if this function is known to have a null epilogue. */
1917 direct_return (void)
1919 if (reload_completed)
1921 rs6000_stack_t *info = rs6000_stack_info ();
1923 if (info->first_gp_reg_save == 32
1924 && info->first_fp_reg_save == 64
1925 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
1926 && ! info->lr_save_p
1927 && ! info->cr_save_p
1928 && info->vrsave_mask == 0
1929 && ! info->push_p)
1930 return 1;
1933 return 0;
1936 /* Return the number of instructions it takes to form a constant in an
1937 integer register. */
1940 num_insns_constant_wide (HOST_WIDE_INT value)
1942 /* signed constant loadable with {cal|addi} */
1943 if (CONST_OK_FOR_LETTER_P (value, 'I'))
1944 return 1;
1946 /* constant loadable with {cau|addis} */
1947 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
1948 return 1;
1950 #if HOST_BITS_PER_WIDE_INT == 64
1951 else if (TARGET_POWERPC64)
1953 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1954 HOST_WIDE_INT high = value >> 31;
1956 if (high == 0 || high == -1)
1957 return 2;
1959 high >>= 1;
1961 if (low == 0)
1962 return num_insns_constant_wide (high) + 1;
1963 else
1964 return (num_insns_constant_wide (high)
1965 + num_insns_constant_wide (low) + 1);
1967 #endif
1969 else
1970 return 2;
1974 num_insns_constant (rtx op, enum machine_mode mode)
1976 HOST_WIDE_INT low, high;
1978 switch (GET_CODE (op))
1980 case CONST_INT:
1981 #if HOST_BITS_PER_WIDE_INT == 64
1982 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1983 && mask64_operand (op, mode))
1984 return 2;
1985 else
1986 #endif
1987 return num_insns_constant_wide (INTVAL (op));
1989 case CONST_DOUBLE:
1990 if (mode == SFmode)
1992 long l;
1993 REAL_VALUE_TYPE rv;
1995 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1996 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
1997 return num_insns_constant_wide ((HOST_WIDE_INT) l);
2000 if (mode == VOIDmode || mode == DImode)
2002 high = CONST_DOUBLE_HIGH (op);
2003 low = CONST_DOUBLE_LOW (op);
2005 else
2007 long l[2];
2008 REAL_VALUE_TYPE rv;
2010 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2011 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
2012 high = l[WORDS_BIG_ENDIAN == 0];
2013 low = l[WORDS_BIG_ENDIAN != 0];
2016 if (TARGET_32BIT)
2017 return (num_insns_constant_wide (low)
2018 + num_insns_constant_wide (high));
2019 else
2021 if ((high == 0 && low >= 0)
2022 || (high == -1 && low < 0))
2023 return num_insns_constant_wide (low);
2025 else if (mask64_operand (op, mode))
2026 return 2;
2028 else if (low == 0)
2029 return num_insns_constant_wide (high) + 1;
2031 else
2032 return (num_insns_constant_wide (high)
2033 + num_insns_constant_wide (low) + 1);
2036 default:
2037 gcc_unreachable ();
2041 /* Returns the constant for the splat instruction, if exists. */
2044 easy_vector_splat_const (int cst, enum machine_mode mode)
2046 switch (mode)
2048 case V4SImode:
2049 if (EASY_VECTOR_15 (cst)
2050 || EASY_VECTOR_15_ADD_SELF (cst))
2051 return cst;
2052 if ((cst & 0xffff) != ((cst >> 16) & 0xffff))
2053 break;
2054 cst = cst >> 16;
2055 /* Fall thru */
2057 case V8HImode:
2058 if (EASY_VECTOR_15 (cst)
2059 || EASY_VECTOR_15_ADD_SELF (cst))
2060 return cst;
2061 if ((cst & 0xff) != ((cst >> 8) & 0xff))
2062 break;
2063 cst = cst >> 8;
2064 /* Fall thru */
2066 case V16QImode:
2067 if (EASY_VECTOR_15 (cst)
2068 || EASY_VECTOR_15_ADD_SELF (cst))
2069 return cst;
2070 default:
2071 break;
2073 return 0;
2076 /* Return nonzero if all elements of a vector have the same value. */
2079 easy_vector_same (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2081 int units, i, cst;
2083 units = CONST_VECTOR_NUNITS (op);
2085 cst = INTVAL (CONST_VECTOR_ELT (op, 0));
2086 for (i = 1; i < units; ++i)
2087 if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst)
2088 break;
2089 if (i == units && easy_vector_splat_const (cst, mode))
2090 return 1;
2091 return 0;
2094 /* Generate easy_vector_constant out of a easy_vector_constant_add_self. */
2097 gen_easy_vector_constant_add_self (rtx op)
2099 int i, units;
2100 rtvec v;
2101 units = GET_MODE_NUNITS (GET_MODE (op));
2102 v = rtvec_alloc (units);
2104 for (i = 0; i < units; i++)
2105 RTVEC_ELT (v, i) =
2106 GEN_INT (INTVAL (CONST_VECTOR_ELT (op, i)) >> 1);
2107 return gen_rtx_raw_CONST_VECTOR (GET_MODE (op), v);
2110 const char *
2111 output_vec_const_move (rtx *operands)
2113 int cst, cst2;
2114 enum machine_mode mode;
2115 rtx dest, vec;
2117 dest = operands[0];
2118 vec = operands[1];
2120 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
2121 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
2122 mode = GET_MODE (dest);
2124 if (TARGET_ALTIVEC)
2126 if (zero_constant (vec, mode))
2127 return "vxor %0,%0,%0";
2129 gcc_assert (easy_vector_constant (vec, mode));
2131 operands[1] = GEN_INT (cst);
2132 switch (mode)
2134 case V4SImode:
2135 if (EASY_VECTOR_15 (cst))
2137 operands[1] = GEN_INT (cst);
2138 return "vspltisw %0,%1";
2140 else if (EASY_VECTOR_15_ADD_SELF (cst))
2141 return "#";
2142 cst = cst >> 16;
2143 /* Fall thru */
2145 case V8HImode:
2146 if (EASY_VECTOR_15 (cst))
2148 operands[1] = GEN_INT (cst);
2149 return "vspltish %0,%1";
2151 else if (EASY_VECTOR_15_ADD_SELF (cst))
2152 return "#";
2153 cst = cst >> 8;
2154 /* Fall thru */
2156 case V16QImode:
2157 if (EASY_VECTOR_15 (cst))
2159 operands[1] = GEN_INT (cst);
2160 return "vspltisb %0,%1";
2162 else if (EASY_VECTOR_15_ADD_SELF (cst))
2163 return "#";
2165 default:
2166 gcc_unreachable ();
2170 gcc_assert (TARGET_SPE);
2172 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2173 pattern of V1DI, V4HI, and V2SF.
2175 FIXME: We should probably return # and add post reload
2176 splitters for these, but this way is so easy ;-). */
2177 operands[1] = GEN_INT (cst);
2178 operands[2] = GEN_INT (cst2);
2179 if (cst == cst2)
2180 return "li %0,%1\n\tevmergelo %0,%0,%0";
2181 else
2182 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2185 /* Initialize vector TARGET to VALS. */
2187 void
2188 rs6000_expand_vector_init (rtx target, rtx vals)
2190 enum machine_mode mode = GET_MODE (target);
2191 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2192 int n_elts = GET_MODE_NUNITS (mode);
2193 int n_var = 0, one_var = -1;
2194 bool all_same = true, all_const_zero = true;
2195 rtx x, mem;
2196 int i;
2198 for (i = 0; i < n_elts; ++i)
2200 x = XVECEXP (vals, 0, i);
2201 if (!CONSTANT_P (x))
2202 ++n_var, one_var = i;
2203 else if (x != CONST0_RTX (inner_mode))
2204 all_const_zero = false;
2206 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
2207 all_same = false;
2210 if (n_var == 0)
2212 if (mode != V4SFmode && all_const_zero)
2214 /* Zero register. */
2215 emit_insn (gen_rtx_SET (VOIDmode, target,
2216 gen_rtx_XOR (mode, target, target)));
2217 return;
2219 else if (mode != V4SFmode && easy_vector_same (vals, mode))
2221 /* Splat immediate. */
2222 x = gen_rtx_VEC_DUPLICATE (mode, CONST_VECTOR_ELT (vals, 0));
2223 emit_insn (gen_rtx_SET (VOIDmode, target, x));
2224 return;
2226 else if (all_same)
2227 ; /* Splat vector element. */
2228 else
2230 /* Load from constant pool. */
2231 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
2232 return;
2236 /* Store value to stack temp. Load vector element. Splat. */
2237 if (all_same)
2239 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2240 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
2241 XVECEXP (vals, 0, 0));
2242 x = gen_rtx_UNSPEC (VOIDmode,
2243 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2244 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2245 gen_rtvec (2,
2246 gen_rtx_SET (VOIDmode,
2247 target, mem),
2248 x)));
2249 x = gen_rtx_VEC_SELECT (inner_mode, target,
2250 gen_rtx_PARALLEL (VOIDmode,
2251 gen_rtvec (1, const0_rtx)));
2252 emit_insn (gen_rtx_SET (VOIDmode, target,
2253 gen_rtx_VEC_DUPLICATE (mode, x)));
2254 return;
2257 /* One field is non-constant. Load constant then overwrite
2258 varying field. */
2259 if (n_var == 1)
2261 rtx copy = copy_rtx (vals);
2263 /* Load constant part of vector, substititute neighboring value for
2264 varying element. */
2265 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
2266 rs6000_expand_vector_init (target, copy);
2268 /* Insert variable. */
2269 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
2270 return;
2273 /* Construct the vector in memory one field at a time
2274 and load the whole vector. */
2275 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2276 for (i = 0; i < n_elts; i++)
2277 emit_move_insn (adjust_address_nv (mem, inner_mode,
2278 i * GET_MODE_SIZE (inner_mode)),
2279 XVECEXP (vals, 0, i));
2280 emit_move_insn (target, mem);
2283 /* Set field ELT of TARGET to VAL. */
2285 void
2286 rs6000_expand_vector_set (rtx target, rtx val, int elt)
2288 enum machine_mode mode = GET_MODE (target);
2289 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2290 rtx reg = gen_reg_rtx (mode);
2291 rtx mask, mem, x;
2292 int width = GET_MODE_SIZE (inner_mode);
2293 int i;
2295 /* Load single variable value. */
2296 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2297 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
2298 x = gen_rtx_UNSPEC (VOIDmode,
2299 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2300 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2301 gen_rtvec (2,
2302 gen_rtx_SET (VOIDmode,
2303 reg, mem),
2304 x)));
2306 /* Linear sequence. */
2307 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
2308 for (i = 0; i < 16; ++i)
2309 XVECEXP (mask, 0, i) = GEN_INT (i);
2311 /* Set permute mask to insert element into target. */
2312 for (i = 0; i < width; ++i)
2313 XVECEXP (mask, 0, elt*width + i)
2314 = GEN_INT (i + 0x10);
2315 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
2316 x = gen_rtx_UNSPEC (mode,
2317 gen_rtvec (3, target, reg,
2318 force_reg (V16QImode, x)),
2319 UNSPEC_VPERM);
2320 emit_insn (gen_rtx_SET (VOIDmode, target, x));
2323 /* Extract field ELT from VEC into TARGET. */
2325 void
2326 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
2328 enum machine_mode mode = GET_MODE (vec);
2329 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2330 rtx mem, x;
2332 /* Allocate mode-sized buffer. */
2333 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2335 /* Add offset to field within buffer matching vector element. */
2336 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
2338 /* Store single field into mode-sized buffer. */
2339 x = gen_rtx_UNSPEC (VOIDmode,
2340 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
2341 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2342 gen_rtvec (2,
2343 gen_rtx_SET (VOIDmode,
2344 mem, vec),
2345 x)));
2346 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
2349 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2350 implement ANDing by the mask IN. */
2351 void
2352 build_mask64_2_operands (rtx in, rtx *out)
2354 #if HOST_BITS_PER_WIDE_INT >= 64
2355 unsigned HOST_WIDE_INT c, lsb, m1, m2;
2356 int shift;
2358 gcc_assert (GET_CODE (in) == CONST_INT);
2360 c = INTVAL (in);
2361 if (c & 1)
2363 /* Assume c initially something like 0x00fff000000fffff. The idea
2364 is to rotate the word so that the middle ^^^^^^ group of zeros
2365 is at the MS end and can be cleared with an rldicl mask. We then
2366 rotate back and clear off the MS ^^ group of zeros with a
2367 second rldicl. */
2368 c = ~c; /* c == 0xff000ffffff00000 */
2369 lsb = c & -c; /* lsb == 0x0000000000100000 */
2370 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
2371 c = ~c; /* c == 0x00fff000000fffff */
2372 c &= -lsb; /* c == 0x00fff00000000000 */
2373 lsb = c & -c; /* lsb == 0x0000100000000000 */
2374 c = ~c; /* c == 0xff000fffffffffff */
2375 c &= -lsb; /* c == 0xff00000000000000 */
2376 shift = 0;
2377 while ((lsb >>= 1) != 0)
2378 shift++; /* shift == 44 on exit from loop */
2379 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
2380 m1 = ~m1; /* m1 == 0x000000ffffffffff */
2381 m2 = ~c; /* m2 == 0x00ffffffffffffff */
2383 else
2385 /* Assume c initially something like 0xff000f0000000000. The idea
2386 is to rotate the word so that the ^^^ middle group of zeros
2387 is at the LS end and can be cleared with an rldicr mask. We then
2388 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2389 a second rldicr. */
2390 lsb = c & -c; /* lsb == 0x0000010000000000 */
2391 m2 = -lsb; /* m2 == 0xffffff0000000000 */
2392 c = ~c; /* c == 0x00fff0ffffffffff */
2393 c &= -lsb; /* c == 0x00fff00000000000 */
2394 lsb = c & -c; /* lsb == 0x0000100000000000 */
2395 c = ~c; /* c == 0xff000fffffffffff */
2396 c &= -lsb; /* c == 0xff00000000000000 */
2397 shift = 0;
2398 while ((lsb >>= 1) != 0)
2399 shift++; /* shift == 44 on exit from loop */
2400 m1 = ~c; /* m1 == 0x00ffffffffffffff */
2401 m1 >>= shift; /* m1 == 0x0000000000000fff */
2402 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
2405 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2406 masks will be all 1's. We are guaranteed more than one transition. */
2407 out[0] = GEN_INT (64 - shift);
2408 out[1] = GEN_INT (m1);
2409 out[2] = GEN_INT (shift);
2410 out[3] = GEN_INT (m2);
2411 #else
2412 (void)in;
2413 (void)out;
2414 gcc_unreachable ();
2415 #endif
2418 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2420 bool
2421 invalid_e500_subreg (rtx op, enum machine_mode mode)
2423 /* Reject (subreg:SI (reg:DF)). */
2424 if (GET_CODE (op) == SUBREG
2425 && mode == SImode
2426 && REG_P (SUBREG_REG (op))
2427 && GET_MODE (SUBREG_REG (op)) == DFmode)
2428 return true;
2430 /* Reject (subreg:DF (reg:DI)). */
2431 if (GET_CODE (op) == SUBREG
2432 && mode == DFmode
2433 && REG_P (SUBREG_REG (op))
2434 && GET_MODE (SUBREG_REG (op)) == DImode)
2435 return true;
2437 return false;
2440 /* Darwin, AIX increases natural record alignment to doubleword if the first
2441 field is an FP double while the FP fields remain word aligned. */
2443 unsigned int
2444 rs6000_special_round_type_align (tree type, int computed, int specified)
2446 tree field = TYPE_FIELDS (type);
2448 /* Skip all non field decls */
2449 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
2450 field = TREE_CHAIN (field);
2452 if (field == NULL || field == type || DECL_MODE (field) != DFmode)
2453 return MAX (computed, specified);
2455 return MAX (MAX (computed, specified), 64);
2458 /* Return 1 for an operand in small memory on V.4/eabi. */
2461 small_data_operand (rtx op ATTRIBUTE_UNUSED,
2462 enum machine_mode mode ATTRIBUTE_UNUSED)
2464 #if TARGET_ELF
2465 rtx sym_ref;
2467 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
2468 return 0;
2470 if (DEFAULT_ABI != ABI_V4)
2471 return 0;
2473 if (GET_CODE (op) == SYMBOL_REF)
2474 sym_ref = op;
2476 else if (GET_CODE (op) != CONST
2477 || GET_CODE (XEXP (op, 0)) != PLUS
2478 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2479 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
2480 return 0;
2482 else
2484 rtx sum = XEXP (op, 0);
2485 HOST_WIDE_INT summand;
2487 /* We have to be careful here, because it is the referenced address
2488 that must be 32k from _SDA_BASE_, not just the symbol. */
2489 summand = INTVAL (XEXP (sum, 1));
2490 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
2491 return 0;
2493 sym_ref = XEXP (sum, 0);
2496 return SYMBOL_REF_SMALL_P (sym_ref);
2497 #else
2498 return 0;
2499 #endif
2502 /* Return true if either operand is a general purpose register. */
2504 bool
2505 gpr_or_gpr_p (rtx op0, rtx op1)
2507 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
2508 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
2512 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2514 static int
2515 constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
2517 switch (GET_CODE (op))
2519 case SYMBOL_REF:
2520 if (RS6000_SYMBOL_REF_TLS_P (op))
2521 return 0;
2522 else if (CONSTANT_POOL_ADDRESS_P (op))
2524 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2526 *have_sym = 1;
2527 return 1;
2529 else
2530 return 0;
2532 else if (! strcmp (XSTR (op, 0), toc_label_name))
2534 *have_toc = 1;
2535 return 1;
2537 else
2538 return 0;
2539 case PLUS:
2540 case MINUS:
2541 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2542 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
2543 case CONST:
2544 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
2545 case CONST_INT:
2546 return 1;
2547 default:
2548 return 0;
2552 static bool
2553 constant_pool_expr_p (rtx op)
2555 int have_sym = 0;
2556 int have_toc = 0;
2557 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2560 bool
2561 toc_relative_expr_p (rtx op)
2563 int have_sym = 0;
2564 int have_toc = 0;
2565 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2568 bool
2569 legitimate_constant_pool_address_p (rtx x)
2571 return (TARGET_TOC
2572 && GET_CODE (x) == PLUS
2573 && GET_CODE (XEXP (x, 0)) == REG
2574 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
2575 && constant_pool_expr_p (XEXP (x, 1)));
2578 bool
2579 rs6000_legitimate_small_data_p (enum machine_mode mode, rtx x)
2581 return (DEFAULT_ABI == ABI_V4
2582 && !flag_pic && !TARGET_TOC
2583 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
2584 && small_data_operand (x, mode));
2587 /* SPE offset addressing is limited to 5-bits worth of double words. */
2588 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2590 bool
2591 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
2593 unsigned HOST_WIDE_INT offset, extra;
2595 if (GET_CODE (x) != PLUS)
2596 return false;
2597 if (GET_CODE (XEXP (x, 0)) != REG)
2598 return false;
2599 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2600 return false;
2601 if (legitimate_constant_pool_address_p (x))
2602 return true;
2603 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2604 return false;
2606 offset = INTVAL (XEXP (x, 1));
2607 extra = 0;
2608 switch (mode)
2610 case V16QImode:
2611 case V8HImode:
2612 case V4SFmode:
2613 case V4SImode:
2614 /* AltiVec vector modes. Only reg+reg addressing is valid and
2615 constant offset zero should not occur due to canonicalization.
2616 Allow any offset when not strict before reload. */
2617 return !strict;
2619 case V4HImode:
2620 case V2SImode:
2621 case V1DImode:
2622 case V2SFmode:
2623 /* SPE vector modes. */
2624 return SPE_CONST_OFFSET_OK (offset);
2626 case DFmode:
2627 if (TARGET_E500_DOUBLE)
2628 return SPE_CONST_OFFSET_OK (offset);
2630 case DImode:
2631 /* On e500v2, we may have:
2633 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
2635 Which gets addressed with evldd instructions. */
2636 if (TARGET_E500_DOUBLE)
2637 return SPE_CONST_OFFSET_OK (offset);
2639 if (mode == DFmode || !TARGET_POWERPC64)
2640 extra = 4;
2641 else if (offset & 3)
2642 return false;
2643 break;
2645 case TFmode:
2646 case TImode:
2647 if (mode == TFmode || !TARGET_POWERPC64)
2648 extra = 12;
2649 else if (offset & 3)
2650 return false;
2651 else
2652 extra = 8;
2653 break;
2655 default:
2656 break;
2659 offset += 0x8000;
2660 return (offset < 0x10000) && (offset + extra < 0x10000);
2663 static bool
2664 legitimate_indexed_address_p (rtx x, int strict)
2666 rtx op0, op1;
2668 if (GET_CODE (x) != PLUS)
2669 return false;
2671 op0 = XEXP (x, 0);
2672 op1 = XEXP (x, 1);
2674 if (!REG_P (op0) || !REG_P (op1))
2675 return false;
2677 return ((INT_REG_OK_FOR_BASE_P (op0, strict)
2678 && INT_REG_OK_FOR_INDEX_P (op1, strict))
2679 || (INT_REG_OK_FOR_BASE_P (op1, strict)
2680 && INT_REG_OK_FOR_INDEX_P (op0, strict)));
2683 inline bool
2684 legitimate_indirect_address_p (rtx x, int strict)
2686 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
2689 bool
2690 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
2692 if (!TARGET_MACHO || !flag_pic
2693 || mode != SImode || GET_CODE (x) != MEM)
2694 return false;
2695 x = XEXP (x, 0);
2697 if (GET_CODE (x) != LO_SUM)
2698 return false;
2699 if (GET_CODE (XEXP (x, 0)) != REG)
2700 return false;
2701 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
2702 return false;
2703 x = XEXP (x, 1);
2705 return CONSTANT_P (x);
2708 static bool
2709 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
2711 if (GET_CODE (x) != LO_SUM)
2712 return false;
2713 if (GET_CODE (XEXP (x, 0)) != REG)
2714 return false;
2715 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2716 return false;
2717 /* Restrict addressing for DI because of our SUBREG hackery. */
2718 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
2719 return false;
2720 x = XEXP (x, 1);
2722 if (TARGET_ELF || TARGET_MACHO)
2724 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
2725 return false;
2726 if (TARGET_TOC)
2727 return false;
2728 if (GET_MODE_NUNITS (mode) != 1)
2729 return false;
2730 if (GET_MODE_BITSIZE (mode) > 64
2731 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
2732 && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode)))
2733 return false;
2735 return CONSTANT_P (x);
2738 return false;
2742 /* Try machine-dependent ways of modifying an illegitimate address
2743 to be legitimate. If we find one, return the new, valid address.
2744 This is used from only one place: `memory_address' in explow.c.
2746 OLDX is the address as it was before break_out_memory_refs was
2747 called. In some cases it is useful to look at this to decide what
2748 needs to be done.
2750 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
2752 It is always safe for this function to do nothing. It exists to
2753 recognize opportunities to optimize the output.
2755 On RS/6000, first check for the sum of a register with a constant
2756 integer that is out of range. If so, generate code to add the
2757 constant with the low-order 16 bits masked to the register and force
2758 this result into another register (this can be done with `cau').
2759 Then generate an address of REG+(CONST&0xffff), allowing for the
2760 possibility of bit 16 being a one.
2762 Then check for the sum of a register and something not constant, try to
2763 load the other things into a register and return the sum. */
2766 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
2767 enum machine_mode mode)
2769 if (GET_CODE (x) == SYMBOL_REF)
2771 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
2772 if (model != 0)
2773 return rs6000_legitimize_tls_address (x, model);
2776 if (GET_CODE (x) == PLUS
2777 && GET_CODE (XEXP (x, 0)) == REG
2778 && GET_CODE (XEXP (x, 1)) == CONST_INT
2779 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2781 HOST_WIDE_INT high_int, low_int;
2782 rtx sum;
2783 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2784 high_int = INTVAL (XEXP (x, 1)) - low_int;
2785 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2786 GEN_INT (high_int)), 0);
2787 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2789 else if (GET_CODE (x) == PLUS
2790 && GET_CODE (XEXP (x, 0)) == REG
2791 && GET_CODE (XEXP (x, 1)) != CONST_INT
2792 && GET_MODE_NUNITS (mode) == 1
2793 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2794 || TARGET_POWERPC64
2795 || (((mode != DImode && mode != DFmode) || TARGET_E500_DOUBLE)
2796 && mode != TFmode))
2797 && (TARGET_POWERPC64 || mode != DImode)
2798 && mode != TImode)
2800 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2801 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2803 else if (ALTIVEC_VECTOR_MODE (mode))
2805 rtx reg;
2807 /* Make sure both operands are registers. */
2808 if (GET_CODE (x) == PLUS)
2809 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
2810 force_reg (Pmode, XEXP (x, 1)));
2812 reg = force_reg (Pmode, x);
2813 return reg;
2815 else if (SPE_VECTOR_MODE (mode)
2816 || (TARGET_E500_DOUBLE && (mode == DFmode
2817 || mode == DImode)))
2819 if (mode == DImode)
2820 return NULL_RTX;
2821 /* We accept [reg + reg] and [reg + OFFSET]. */
2823 if (GET_CODE (x) == PLUS)
2825 rtx op1 = XEXP (x, 0);
2826 rtx op2 = XEXP (x, 1);
2828 op1 = force_reg (Pmode, op1);
2830 if (GET_CODE (op2) != REG
2831 && (GET_CODE (op2) != CONST_INT
2832 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2833 op2 = force_reg (Pmode, op2);
2835 return gen_rtx_PLUS (Pmode, op1, op2);
2838 return force_reg (Pmode, x);
2840 else if (TARGET_ELF
2841 && TARGET_32BIT
2842 && TARGET_NO_TOC
2843 && ! flag_pic
2844 && GET_CODE (x) != CONST_INT
2845 && GET_CODE (x) != CONST_DOUBLE
2846 && CONSTANT_P (x)
2847 && GET_MODE_NUNITS (mode) == 1
2848 && (GET_MODE_BITSIZE (mode) <= 32
2849 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
2851 rtx reg = gen_reg_rtx (Pmode);
2852 emit_insn (gen_elf_high (reg, x));
2853 return gen_rtx_LO_SUM (Pmode, reg, x);
2855 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2856 && ! flag_pic
2857 #if TARGET_MACHO
2858 && ! MACHO_DYNAMIC_NO_PIC_P
2859 #endif
2860 && GET_CODE (x) != CONST_INT
2861 && GET_CODE (x) != CONST_DOUBLE
2862 && CONSTANT_P (x)
2863 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
2864 && mode != DImode
2865 && mode != TImode)
2867 rtx reg = gen_reg_rtx (Pmode);
2868 emit_insn (gen_macho_high (reg, x));
2869 return gen_rtx_LO_SUM (Pmode, reg, x);
2871 else if (TARGET_TOC
2872 && constant_pool_expr_p (x)
2873 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
2875 return create_TOC_reference (x);
2877 else
2878 return NULL_RTX;
2881 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
2882 We need to emit DTP-relative relocations. */
2884 static void
2885 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
2887 switch (size)
2889 case 4:
2890 fputs ("\t.long\t", file);
2891 break;
2892 case 8:
2893 fputs (DOUBLE_INT_ASM_OP, file);
2894 break;
2895 default:
2896 gcc_unreachable ();
2898 output_addr_const (file, x);
2899 fputs ("@dtprel+0x8000", file);
2902 /* Construct the SYMBOL_REF for the tls_get_addr function. */
2904 static GTY(()) rtx rs6000_tls_symbol;
2905 static rtx
2906 rs6000_tls_get_addr (void)
2908 if (!rs6000_tls_symbol)
2909 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
2911 return rs6000_tls_symbol;
2914 /* Construct the SYMBOL_REF for TLS GOT references. */
2916 static GTY(()) rtx rs6000_got_symbol;
2917 static rtx
2918 rs6000_got_sym (void)
2920 if (!rs6000_got_symbol)
2922 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2923 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
2924 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
2927 return rs6000_got_symbol;
2930 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2931 this (thread-local) address. */
2933 static rtx
2934 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
2936 rtx dest, insn;
2938 dest = gen_reg_rtx (Pmode);
2939 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
2941 rtx tlsreg;
2943 if (TARGET_64BIT)
2945 tlsreg = gen_rtx_REG (Pmode, 13);
2946 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
2948 else
2950 tlsreg = gen_rtx_REG (Pmode, 2);
2951 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
2953 emit_insn (insn);
2955 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
2957 rtx tlsreg, tmp;
2959 tmp = gen_reg_rtx (Pmode);
2960 if (TARGET_64BIT)
2962 tlsreg = gen_rtx_REG (Pmode, 13);
2963 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
2965 else
2967 tlsreg = gen_rtx_REG (Pmode, 2);
2968 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
2970 emit_insn (insn);
2971 if (TARGET_64BIT)
2972 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
2973 else
2974 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
2975 emit_insn (insn);
2977 else
2979 rtx r3, got, tga, tmp1, tmp2, eqv;
2981 if (TARGET_64BIT)
2982 got = gen_rtx_REG (Pmode, TOC_REGISTER);
2983 else
2985 if (flag_pic == 1)
2986 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
2987 else
2989 rtx gsym = rs6000_got_sym ();
2990 got = gen_reg_rtx (Pmode);
2991 if (flag_pic == 0)
2992 rs6000_emit_move (got, gsym, Pmode);
2993 else
2995 rtx tempLR, tmp3, mem;
2996 rtx first, last;
2998 tempLR = gen_reg_rtx (Pmode);
2999 tmp1 = gen_reg_rtx (Pmode);
3000 tmp2 = gen_reg_rtx (Pmode);
3001 tmp3 = gen_reg_rtx (Pmode);
3002 mem = gen_const_mem (Pmode, tmp1);
3004 first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, gsym));
3005 emit_move_insn (tmp1, tempLR);
3006 emit_move_insn (tmp2, mem);
3007 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
3008 last = emit_move_insn (got, tmp3);
3009 REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, gsym,
3010 REG_NOTES (last));
3011 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3012 REG_NOTES (first));
3013 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3014 REG_NOTES (last));
3019 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
3021 r3 = gen_rtx_REG (Pmode, 3);
3022 if (TARGET_64BIT)
3023 insn = gen_tls_gd_64 (r3, got, addr);
3024 else
3025 insn = gen_tls_gd_32 (r3, got, addr);
3026 start_sequence ();
3027 emit_insn (insn);
3028 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3029 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3030 insn = emit_call_insn (insn);
3031 CONST_OR_PURE_CALL_P (insn) = 1;
3032 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3033 insn = get_insns ();
3034 end_sequence ();
3035 emit_libcall_block (insn, dest, r3, addr);
3037 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3039 r3 = gen_rtx_REG (Pmode, 3);
3040 if (TARGET_64BIT)
3041 insn = gen_tls_ld_64 (r3, got);
3042 else
3043 insn = gen_tls_ld_32 (r3, got);
3044 start_sequence ();
3045 emit_insn (insn);
3046 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3047 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3048 insn = emit_call_insn (insn);
3049 CONST_OR_PURE_CALL_P (insn) = 1;
3050 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3051 insn = get_insns ();
3052 end_sequence ();
3053 tmp1 = gen_reg_rtx (Pmode);
3054 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3055 UNSPEC_TLSLD);
3056 emit_libcall_block (insn, tmp1, r3, eqv);
3057 if (rs6000_tls_size == 16)
3059 if (TARGET_64BIT)
3060 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3061 else
3062 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3064 else if (rs6000_tls_size == 32)
3066 tmp2 = gen_reg_rtx (Pmode);
3067 if (TARGET_64BIT)
3068 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3069 else
3070 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3071 emit_insn (insn);
3072 if (TARGET_64BIT)
3073 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3074 else
3075 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3077 else
3079 tmp2 = gen_reg_rtx (Pmode);
3080 if (TARGET_64BIT)
3081 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3082 else
3083 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3084 emit_insn (insn);
3085 insn = gen_rtx_SET (Pmode, dest,
3086 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3088 emit_insn (insn);
3090 else
3092 /* IE, or 64 bit offset LE. */
3093 tmp2 = gen_reg_rtx (Pmode);
3094 if (TARGET_64BIT)
3095 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3096 else
3097 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3098 emit_insn (insn);
3099 if (TARGET_64BIT)
3100 insn = gen_tls_tls_64 (dest, tmp2, addr);
3101 else
3102 insn = gen_tls_tls_32 (dest, tmp2, addr);
3103 emit_insn (insn);
3107 return dest;
3110 /* Return 1 if X contains a thread-local symbol. */
3112 bool
3113 rs6000_tls_referenced_p (rtx x)
3115 if (! TARGET_HAVE_TLS)
3116 return false;
3118 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
3121 /* Return 1 if *X is a thread-local symbol. This is the same as
3122 rs6000_tls_symbol_ref except for the type of the unused argument. */
3124 static int
3125 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
3127 return RS6000_SYMBOL_REF_TLS_P (*x);
3130 /* The convention appears to be to define this wherever it is used.
3131 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3132 is now used here. */
3133 #ifndef REG_MODE_OK_FOR_BASE_P
3134 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3135 #endif
3137 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3138 replace the input X, or the original X if no replacement is called for.
3139 The output parameter *WIN is 1 if the calling macro should goto WIN,
3140 0 if it should not.
3142 For RS/6000, we wish to handle large displacements off a base
3143 register by splitting the addend across an addiu/addis and the mem insn.
3144 This cuts number of extra insns needed from 3 to 1.
3146 On Darwin, we use this to generate code for floating point constants.
3147 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3148 The Darwin code is inside #if TARGET_MACHO because only then is
3149 machopic_function_base_name() defined. */
3151 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
3152 int opnum, int type,
3153 int ind_levels ATTRIBUTE_UNUSED, int *win)
3155 /* We must recognize output that we have already generated ourselves. */
3156 if (GET_CODE (x) == PLUS
3157 && GET_CODE (XEXP (x, 0)) == PLUS
3158 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3159 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3160 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3162 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3163 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3164 opnum, (enum reload_type)type);
3165 *win = 1;
3166 return x;
3169 #if TARGET_MACHO
3170 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
3171 && GET_CODE (x) == LO_SUM
3172 && GET_CODE (XEXP (x, 0)) == PLUS
3173 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
3174 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
3175 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
3176 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
3177 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
3178 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
3179 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
3181 /* Result of previous invocation of this function on Darwin
3182 floating point constant. */
3183 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3184 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3185 opnum, (enum reload_type)type);
3186 *win = 1;
3187 return x;
3189 #endif
3191 /* Force ld/std non-word aligned offset into base register by wrapping
3192 in offset 0. */
3193 if (GET_CODE (x) == PLUS
3194 && GET_CODE (XEXP (x, 0)) == REG
3195 && REGNO (XEXP (x, 0)) < 32
3196 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3197 && GET_CODE (XEXP (x, 1)) == CONST_INT
3198 && (INTVAL (XEXP (x, 1)) & 3) != 0
3199 && !ALTIVEC_VECTOR_MODE (mode)
3200 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
3201 && TARGET_POWERPC64)
3203 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
3204 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3205 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3206 opnum, (enum reload_type) type);
3207 *win = 1;
3208 return x;
3211 if (GET_CODE (x) == PLUS
3212 && GET_CODE (XEXP (x, 0)) == REG
3213 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
3214 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3215 && GET_CODE (XEXP (x, 1)) == CONST_INT
3216 && !SPE_VECTOR_MODE (mode)
3217 && !(TARGET_E500_DOUBLE && (mode == DFmode
3218 || mode == DImode))
3219 && !ALTIVEC_VECTOR_MODE (mode))
3221 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3222 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
3223 HOST_WIDE_INT high
3224 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3226 /* Check for 32-bit overflow. */
3227 if (high + low != val)
3229 *win = 0;
3230 return x;
3233 /* Reload the high part into a base reg; leave the low part
3234 in the mem directly. */
3236 x = gen_rtx_PLUS (GET_MODE (x),
3237 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
3238 GEN_INT (high)),
3239 GEN_INT (low));
3241 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3242 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3243 opnum, (enum reload_type)type);
3244 *win = 1;
3245 return x;
3248 #if TARGET_MACHO
3249 if (GET_CODE (x) == SYMBOL_REF
3250 && DEFAULT_ABI == ABI_DARWIN
3251 && !ALTIVEC_VECTOR_MODE (mode)
3252 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
3253 /* Don't do this for TFmode, since the result isn't offsettable.
3254 The same goes for DImode without 64-bit gprs. */
3255 && mode != TFmode
3256 && (mode != DImode || TARGET_POWERPC64))
3258 if (flag_pic)
3260 rtx offset = gen_rtx_CONST (Pmode,
3261 gen_rtx_MINUS (Pmode, x,
3262 machopic_function_base_sym ()));
3263 x = gen_rtx_LO_SUM (GET_MODE (x),
3264 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
3265 gen_rtx_HIGH (Pmode, offset)), offset);
3267 else
3268 x = gen_rtx_LO_SUM (GET_MODE (x),
3269 gen_rtx_HIGH (Pmode, x), x);
3271 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3272 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3273 opnum, (enum reload_type)type);
3274 *win = 1;
3275 return x;
3277 #endif
3279 /* Reload an offset address wrapped by an AND that represents the
3280 masking of the lower bits. Strip the outer AND and let reload
3281 convert the offset address into an indirect address. */
3282 if (TARGET_ALTIVEC
3283 && ALTIVEC_VECTOR_MODE (mode)
3284 && GET_CODE (x) == AND
3285 && GET_CODE (XEXP (x, 0)) == PLUS
3286 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3287 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3288 && GET_CODE (XEXP (x, 1)) == CONST_INT
3289 && INTVAL (XEXP (x, 1)) == -16)
3291 x = XEXP (x, 0);
3292 *win = 1;
3293 return x;
3296 if (TARGET_TOC
3297 && constant_pool_expr_p (x)
3298 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
3300 (x) = create_TOC_reference (x);
3301 *win = 1;
3302 return x;
3304 *win = 0;
3305 return x;
3308 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3309 that is a valid memory address for an instruction.
3310 The MODE argument is the machine mode for the MEM expression
3311 that wants to use this address.
3313 On the RS/6000, there are four valid address: a SYMBOL_REF that
3314 refers to a constant pool entry of an address (or the sum of it
3315 plus a constant), a short (16-bit signed) constant plus a register,
3316 the sum of two registers, or a register indirect, possibly with an
3317 auto-increment. For DFmode and DImode with a constant plus register,
3318 we must ensure that both words are addressable or PowerPC64 with offset
3319 word aligned.
3321 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3322 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3323 adjacent memory cells are accessed by adding word-sized offsets
3324 during assembly output. */
3326 rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
3328 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3329 if (TARGET_ALTIVEC
3330 && ALTIVEC_VECTOR_MODE (mode)
3331 && GET_CODE (x) == AND
3332 && GET_CODE (XEXP (x, 1)) == CONST_INT
3333 && INTVAL (XEXP (x, 1)) == -16)
3334 x = XEXP (x, 0);
3336 if (RS6000_SYMBOL_REF_TLS_P (x))
3337 return 0;
3338 if (legitimate_indirect_address_p (x, reg_ok_strict))
3339 return 1;
3340 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
3341 && !ALTIVEC_VECTOR_MODE (mode)
3342 && !SPE_VECTOR_MODE (mode)
3343 /* Restrict addressing for DI because of our SUBREG hackery. */
3344 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
3345 && TARGET_UPDATE
3346 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
3347 return 1;
3348 if (rs6000_legitimate_small_data_p (mode, x))
3349 return 1;
3350 if (legitimate_constant_pool_address_p (x))
3351 return 1;
3352 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3353 if (! reg_ok_strict
3354 && GET_CODE (x) == PLUS
3355 && GET_CODE (XEXP (x, 0)) == REG
3356 && (XEXP (x, 0) == virtual_stack_vars_rtx
3357 || XEXP (x, 0) == arg_pointer_rtx)
3358 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3359 return 1;
3360 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
3361 return 1;
3362 if (mode != TImode
3363 && mode != TFmode
3364 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3365 || TARGET_POWERPC64
3366 || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
3367 && (TARGET_POWERPC64 || mode != DImode)
3368 && legitimate_indexed_address_p (x, reg_ok_strict))
3369 return 1;
3370 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
3371 return 1;
3372 return 0;
3375 /* Go to LABEL if ADDR (a legitimate address expression)
3376 has an effect that depends on the machine mode it is used for.
3378 On the RS/6000 this is true of all integral offsets (since AltiVec
3379 modes don't allow them) or is a pre-increment or decrement.
3381 ??? Except that due to conceptual problems in offsettable_address_p
3382 we can't really report the problems of integral offsets. So leave
3383 this assuming that the adjustable offset must be valid for the
3384 sub-words of a TFmode operand, which is what we had before. */
3386 bool
3387 rs6000_mode_dependent_address (rtx addr)
3389 switch (GET_CODE (addr))
3391 case PLUS:
3392 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
3394 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
3395 return val + 12 + 0x8000 >= 0x10000;
3397 break;
3399 case LO_SUM:
3400 return true;
3402 case PRE_INC:
3403 case PRE_DEC:
3404 return TARGET_UPDATE;
3406 default:
3407 break;
3410 return false;
3413 /* Return number of consecutive hard regs needed starting at reg REGNO
3414 to hold something of mode MODE.
3415 This is ordinarily the length in words of a value of mode MODE
3416 but can be less for certain modes in special long registers.
3418 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3419 scalar instructions. The upper 32 bits are only available to the
3420 SIMD instructions.
3422 POWER and PowerPC GPRs hold 32 bits worth;
3423 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3426 rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
3428 if (FP_REGNO_P (regno))
3429 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3431 if (TARGET_E500_DOUBLE && mode == DFmode)
3432 return 1;
3434 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
3435 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
3437 if (ALTIVEC_REGNO_P (regno))
3438 return
3439 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
3441 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3444 /* Change register usage conditional on target flags. */
3445 void
3446 rs6000_conditional_register_usage (void)
3448 int i;
3450 /* Set MQ register fixed (already call_used) if not POWER
3451 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3452 be allocated. */
3453 if (! TARGET_POWER)
3454 fixed_regs[64] = 1;
3456 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3457 if (TARGET_64BIT)
3458 fixed_regs[13] = call_used_regs[13]
3459 = call_really_used_regs[13] = 1;
3461 /* Conditionally disable FPRs. */
3462 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
3463 for (i = 32; i < 64; i++)
3464 fixed_regs[i] = call_used_regs[i]
3465 = call_really_used_regs[i] = 1;
3467 /* The TOC register is not killed across calls in a way that is
3468 visible to the compiler. */
3469 if (DEFAULT_ABI == ABI_AIX)
3470 call_really_used_regs[2] = 0;
3472 if (DEFAULT_ABI == ABI_V4
3473 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3474 && flag_pic == 2)
3475 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3477 if (DEFAULT_ABI == ABI_V4
3478 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3479 && flag_pic == 1)
3480 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3481 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3482 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3484 if (DEFAULT_ABI == ABI_DARWIN
3485 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
3486 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3487 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3488 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3490 if (TARGET_TOC && TARGET_MINIMAL_TOC)
3491 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3492 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3494 if (TARGET_ALTIVEC)
3495 global_regs[VSCR_REGNO] = 1;
3497 if (TARGET_SPE)
3499 global_regs[SPEFSCR_REGNO] = 1;
3500 fixed_regs[FIXED_SCRATCH]
3501 = call_used_regs[FIXED_SCRATCH]
3502 = call_really_used_regs[FIXED_SCRATCH] = 1;
3505 if (! TARGET_ALTIVEC)
3507 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
3508 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
3509 call_really_used_regs[VRSAVE_REGNO] = 1;
3512 if (TARGET_ALTIVEC_ABI)
3513 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
3514 call_used_regs[i] = call_really_used_regs[i] = 1;
3517 /* Try to output insns to set TARGET equal to the constant C if it can
3518 be done in less than N insns. Do all computations in MODE.
3519 Returns the place where the output has been placed if it can be
3520 done and the insns have been emitted. If it would take more than N
3521 insns, zero is returned and no insns and emitted. */
3524 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
3525 rtx source, int n ATTRIBUTE_UNUSED)
3527 rtx result, insn, set;
3528 HOST_WIDE_INT c0, c1;
3530 switch (mode)
3532 case QImode:
3533 case HImode:
3534 if (dest == NULL)
3535 dest = gen_reg_rtx (mode);
3536 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
3537 return dest;
3539 case SImode:
3540 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
3542 emit_insn (gen_rtx_SET (VOIDmode, result,
3543 GEN_INT (INTVAL (source)
3544 & (~ (HOST_WIDE_INT) 0xffff))));
3545 emit_insn (gen_rtx_SET (VOIDmode, dest,
3546 gen_rtx_IOR (SImode, result,
3547 GEN_INT (INTVAL (source) & 0xffff))));
3548 result = dest;
3549 break;
3551 case DImode:
3552 switch (GET_CODE (source))
3554 case CONST_INT:
3555 c0 = INTVAL (source);
3556 c1 = -(c0 < 0);
3557 break;
3559 case CONST_DOUBLE:
3560 #if HOST_BITS_PER_WIDE_INT >= 64
3561 c0 = CONST_DOUBLE_LOW (source);
3562 c1 = -(c0 < 0);
3563 #else
3564 c0 = CONST_DOUBLE_LOW (source);
3565 c1 = CONST_DOUBLE_HIGH (source);
3566 #endif
3567 break;
3569 default:
3570 gcc_unreachable ();
3573 result = rs6000_emit_set_long_const (dest, c0, c1);
3574 break;
3576 default:
3577 gcc_unreachable ();
3580 insn = get_last_insn ();
3581 set = single_set (insn);
3582 if (! CONSTANT_P (SET_SRC (set)))
3583 set_unique_reg_note (insn, REG_EQUAL, source);
3585 return result;
3588 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
3589 fall back to a straight forward decomposition. We do this to avoid
3590 exponential run times encountered when looking for longer sequences
3591 with rs6000_emit_set_const. */
3592 static rtx
3593 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
3595 if (!TARGET_POWERPC64)
3597 rtx operand1, operand2;
3599 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
3600 DImode);
3601 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
3602 DImode);
3603 emit_move_insn (operand1, GEN_INT (c1));
3604 emit_move_insn (operand2, GEN_INT (c2));
3606 else
3608 HOST_WIDE_INT ud1, ud2, ud3, ud4;
3610 ud1 = c1 & 0xffff;
3611 ud2 = (c1 & 0xffff0000) >> 16;
3612 #if HOST_BITS_PER_WIDE_INT >= 64
3613 c2 = c1 >> 32;
3614 #endif
3615 ud3 = c2 & 0xffff;
3616 ud4 = (c2 & 0xffff0000) >> 16;
3618 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
3619 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
3621 if (ud1 & 0x8000)
3622 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
3623 else
3624 emit_move_insn (dest, GEN_INT (ud1));
3627 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
3628 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
3630 if (ud2 & 0x8000)
3631 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
3632 - 0x80000000));
3633 else
3634 emit_move_insn (dest, GEN_INT (ud2 << 16));
3635 if (ud1 != 0)
3636 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
3638 else if ((ud4 == 0xffff && (ud3 & 0x8000))
3639 || (ud4 == 0 && ! (ud3 & 0x8000)))
3641 if (ud3 & 0x8000)
3642 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
3643 - 0x80000000));
3644 else
3645 emit_move_insn (dest, GEN_INT (ud3 << 16));
3647 if (ud2 != 0)
3648 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
3649 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
3650 if (ud1 != 0)
3651 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
3653 else
3655 if (ud4 & 0x8000)
3656 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
3657 - 0x80000000));
3658 else
3659 emit_move_insn (dest, GEN_INT (ud4 << 16));
3661 if (ud3 != 0)
3662 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
3664 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
3665 if (ud2 != 0)
3666 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
3667 GEN_INT (ud2 << 16)));
3668 if (ud1 != 0)
3669 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
3672 return dest;
3675 /* Helper for the following. Get rid of [r+r] memory refs
3676 in cases where it won't work (TImode, TFmode). */
3678 static void
3679 rs6000_eliminate_indexed_memrefs (rtx operands[2])
3681 if (GET_CODE (operands[0]) == MEM
3682 && GET_CODE (XEXP (operands[0], 0)) != REG
3683 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
3684 && ! reload_in_progress)
3685 operands[0]
3686 = replace_equiv_address (operands[0],
3687 copy_addr_to_reg (XEXP (operands[0], 0)));
3689 if (GET_CODE (operands[1]) == MEM
3690 && GET_CODE (XEXP (operands[1], 0)) != REG
3691 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
3692 && ! reload_in_progress)
3693 operands[1]
3694 = replace_equiv_address (operands[1],
3695 copy_addr_to_reg (XEXP (operands[1], 0)));
3698 /* Emit a move from SOURCE to DEST in mode MODE. */
3699 void
3700 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
3702 rtx operands[2];
3703 operands[0] = dest;
3704 operands[1] = source;
3706 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
3707 if (GET_CODE (operands[1]) == CONST_DOUBLE
3708 && ! FLOAT_MODE_P (mode)
3709 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
3711 /* FIXME. This should never happen. */
3712 /* Since it seems that it does, do the safe thing and convert
3713 to a CONST_INT. */
3714 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
3716 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
3717 || FLOAT_MODE_P (mode)
3718 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
3719 || CONST_DOUBLE_LOW (operands[1]) < 0)
3720 && (CONST_DOUBLE_HIGH (operands[1]) != -1
3721 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
3723 /* Check if GCC is setting up a block move that will end up using FP
3724 registers as temporaries. We must make sure this is acceptable. */
3725 if (GET_CODE (operands[0]) == MEM
3726 && GET_CODE (operands[1]) == MEM
3727 && mode == DImode
3728 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
3729 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
3730 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
3731 ? 32 : MEM_ALIGN (operands[0])))
3732 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
3733 ? 32
3734 : MEM_ALIGN (operands[1]))))
3735 && ! MEM_VOLATILE_P (operands [0])
3736 && ! MEM_VOLATILE_P (operands [1]))
3738 emit_move_insn (adjust_address (operands[0], SImode, 0),
3739 adjust_address (operands[1], SImode, 0));
3740 emit_move_insn (adjust_address (operands[0], SImode, 4),
3741 adjust_address (operands[1], SImode, 4));
3742 return;
3745 if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
3746 && !gpc_reg_operand (operands[1], mode))
3747 operands[1] = force_reg (mode, operands[1]);
3749 if (mode == SFmode && ! TARGET_POWERPC
3750 && TARGET_HARD_FLOAT && TARGET_FPRS
3751 && GET_CODE (operands[0]) == MEM)
3753 int regnum;
3755 if (reload_in_progress || reload_completed)
3756 regnum = true_regnum (operands[1]);
3757 else if (GET_CODE (operands[1]) == REG)
3758 regnum = REGNO (operands[1]);
3759 else
3760 regnum = -1;
3762 /* If operands[1] is a register, on POWER it may have
3763 double-precision data in it, so truncate it to single
3764 precision. */
3765 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
3767 rtx newreg;
3768 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
3769 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
3770 operands[1] = newreg;
3774 /* Recognize the case where operand[1] is a reference to thread-local
3775 data and load its address to a register. */
3776 if (rs6000_tls_referenced_p (operands[1]))
3778 enum tls_model model;
3779 rtx tmp = operands[1];
3780 rtx addend = NULL;
3782 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
3784 addend = XEXP (XEXP (tmp, 0), 1);
3785 tmp = XEXP (XEXP (tmp, 0), 0);
3788 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
3789 model = SYMBOL_REF_TLS_MODEL (tmp);
3790 gcc_assert (model != 0);
3792 tmp = rs6000_legitimize_tls_address (tmp, model);
3793 if (addend)
3795 tmp = gen_rtx_PLUS (mode, tmp, addend);
3796 tmp = force_operand (tmp, operands[0]);
3798 operands[1] = tmp;
3801 /* Handle the case where reload calls us with an invalid address. */
3802 if (reload_in_progress && mode == Pmode
3803 && (! general_operand (operands[1], mode)
3804 || ! nonimmediate_operand (operands[0], mode)))
3805 goto emit_set;
3807 /* 128-bit constant floating-point values on Darwin should really be
3808 loaded as two parts. */
3809 if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
3810 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
3811 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
3813 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
3814 know how to get a DFmode SUBREG of a TFmode. */
3815 rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
3816 simplify_gen_subreg (DImode, operands[1], mode, 0),
3817 DImode);
3818 rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
3819 GET_MODE_SIZE (DImode)),
3820 simplify_gen_subreg (DImode, operands[1], mode,
3821 GET_MODE_SIZE (DImode)),
3822 DImode);
3823 return;
3826 /* FIXME: In the long term, this switch statement should go away
3827 and be replaced by a sequence of tests based on things like
3828 mode == Pmode. */
3829 switch (mode)
3831 case HImode:
3832 case QImode:
3833 if (CONSTANT_P (operands[1])
3834 && GET_CODE (operands[1]) != CONST_INT)
3835 operands[1] = force_const_mem (mode, operands[1]);
3836 break;
3838 case TFmode:
3839 rs6000_eliminate_indexed_memrefs (operands);
3840 /* fall through */
3842 case DFmode:
3843 case SFmode:
3844 if (CONSTANT_P (operands[1])
3845 && ! easy_fp_constant (operands[1], mode))
3846 operands[1] = force_const_mem (mode, operands[1]);
3847 break;
3849 case V16QImode:
3850 case V8HImode:
3851 case V4SFmode:
3852 case V4SImode:
3853 case V4HImode:
3854 case V2SFmode:
3855 case V2SImode:
3856 case V1DImode:
3857 if (CONSTANT_P (operands[1])
3858 && !easy_vector_constant (operands[1], mode))
3859 operands[1] = force_const_mem (mode, operands[1]);
3860 break;
3862 case SImode:
3863 case DImode:
3864 /* Use default pattern for address of ELF small data */
3865 if (TARGET_ELF
3866 && mode == Pmode
3867 && DEFAULT_ABI == ABI_V4
3868 && (GET_CODE (operands[1]) == SYMBOL_REF
3869 || GET_CODE (operands[1]) == CONST)
3870 && small_data_operand (operands[1], mode))
3872 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3873 return;
3876 if (DEFAULT_ABI == ABI_V4
3877 && mode == Pmode && mode == SImode
3878 && flag_pic == 1 && got_operand (operands[1], mode))
3880 emit_insn (gen_movsi_got (operands[0], operands[1]));
3881 return;
3884 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
3885 && TARGET_NO_TOC
3886 && ! flag_pic
3887 && mode == Pmode
3888 && CONSTANT_P (operands[1])
3889 && GET_CODE (operands[1]) != HIGH
3890 && GET_CODE (operands[1]) != CONST_INT)
3892 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
3894 /* If this is a function address on -mcall-aixdesc,
3895 convert it to the address of the descriptor. */
3896 if (DEFAULT_ABI == ABI_AIX
3897 && GET_CODE (operands[1]) == SYMBOL_REF
3898 && XSTR (operands[1], 0)[0] == '.')
3900 const char *name = XSTR (operands[1], 0);
3901 rtx new_ref;
3902 while (*name == '.')
3903 name++;
3904 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
3905 CONSTANT_POOL_ADDRESS_P (new_ref)
3906 = CONSTANT_POOL_ADDRESS_P (operands[1]);
3907 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
3908 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
3909 SYMBOL_REF_DECL (new_ref) = SYMBOL_REF_DECL (operands[1]);
3910 operands[1] = new_ref;
3913 if (DEFAULT_ABI == ABI_DARWIN)
3915 #if TARGET_MACHO
3916 if (MACHO_DYNAMIC_NO_PIC_P)
3918 /* Take care of any required data indirection. */
3919 operands[1] = rs6000_machopic_legitimize_pic_address (
3920 operands[1], mode, operands[0]);
3921 if (operands[0] != operands[1])
3922 emit_insn (gen_rtx_SET (VOIDmode,
3923 operands[0], operands[1]));
3924 return;
3926 #endif
3927 emit_insn (gen_macho_high (target, operands[1]));
3928 emit_insn (gen_macho_low (operands[0], target, operands[1]));
3929 return;
3932 emit_insn (gen_elf_high (target, operands[1]));
3933 emit_insn (gen_elf_low (operands[0], target, operands[1]));
3934 return;
3937 /* If this is a SYMBOL_REF that refers to a constant pool entry,
3938 and we have put it in the TOC, we just need to make a TOC-relative
3939 reference to it. */
3940 if (TARGET_TOC
3941 && GET_CODE (operands[1]) == SYMBOL_REF
3942 && constant_pool_expr_p (operands[1])
3943 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
3944 get_pool_mode (operands[1])))
3946 operands[1] = create_TOC_reference (operands[1]);
3948 else if (mode == Pmode
3949 && CONSTANT_P (operands[1])
3950 && ((GET_CODE (operands[1]) != CONST_INT
3951 && ! easy_fp_constant (operands[1], mode))
3952 || (GET_CODE (operands[1]) == CONST_INT
3953 && num_insns_constant (operands[1], mode) > 2)
3954 || (GET_CODE (operands[0]) == REG
3955 && FP_REGNO_P (REGNO (operands[0]))))
3956 && GET_CODE (operands[1]) != HIGH
3957 && ! legitimate_constant_pool_address_p (operands[1])
3958 && ! toc_relative_expr_p (operands[1]))
3960 /* Emit a USE operation so that the constant isn't deleted if
3961 expensive optimizations are turned on because nobody
3962 references it. This should only be done for operands that
3963 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
3964 This should not be done for operands that contain LABEL_REFs.
3965 For now, we just handle the obvious case. */
3966 if (GET_CODE (operands[1]) != LABEL_REF)
3967 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
3969 #if TARGET_MACHO
3970 /* Darwin uses a special PIC legitimizer. */
3971 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
3973 operands[1] =
3974 rs6000_machopic_legitimize_pic_address (operands[1], mode,
3975 operands[0]);
3976 if (operands[0] != operands[1])
3977 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3978 return;
3980 #endif
3982 /* If we are to limit the number of things we put in the TOC and
3983 this is a symbol plus a constant we can add in one insn,
3984 just put the symbol in the TOC and add the constant. Don't do
3985 this if reload is in progress. */
3986 if (GET_CODE (operands[1]) == CONST
3987 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
3988 && GET_CODE (XEXP (operands[1], 0)) == PLUS
3989 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
3990 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
3991 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
3992 && ! side_effects_p (operands[0]))
3994 rtx sym =
3995 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
3996 rtx other = XEXP (XEXP (operands[1], 0), 1);
3998 sym = force_reg (mode, sym);
3999 if (mode == SImode)
4000 emit_insn (gen_addsi3 (operands[0], sym, other));
4001 else
4002 emit_insn (gen_adddi3 (operands[0], sym, other));
4003 return;
4006 operands[1] = force_const_mem (mode, operands[1]);
4008 if (TARGET_TOC
4009 && constant_pool_expr_p (XEXP (operands[1], 0))
4010 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4011 get_pool_constant (XEXP (operands[1], 0)),
4012 get_pool_mode (XEXP (operands[1], 0))))
4014 operands[1]
4015 = gen_const_mem (mode,
4016 create_TOC_reference (XEXP (operands[1], 0)));
4017 set_mem_alias_set (operands[1], get_TOC_alias_set ());
4020 break;
4022 case TImode:
4023 rs6000_eliminate_indexed_memrefs (operands);
4025 if (TARGET_POWER)
4027 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4028 gen_rtvec (2,
4029 gen_rtx_SET (VOIDmode,
4030 operands[0], operands[1]),
4031 gen_rtx_CLOBBER (VOIDmode,
4032 gen_rtx_SCRATCH (SImode)))));
4033 return;
4035 break;
4037 default:
4038 gcc_unreachable ();
4041 /* Above, we may have called force_const_mem which may have returned
4042 an invalid address. If we can, fix this up; otherwise, reload will
4043 have to deal with it. */
4044 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
4045 operands[1] = validize_mem (operands[1]);
4047 emit_set:
4048 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4051 /* Nonzero if we can use a floating-point register to pass this arg. */
4052 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4053 (GET_MODE_CLASS (MODE) == MODE_FLOAT \
4054 && (CUM)->fregno <= FP_ARG_MAX_REG \
4055 && TARGET_HARD_FLOAT && TARGET_FPRS)
4057 /* Nonzero if we can use an AltiVec register to pass this arg. */
4058 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4059 (ALTIVEC_VECTOR_MODE (MODE) \
4060 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4061 && TARGET_ALTIVEC_ABI \
4062 && (NAMED))
4064 /* Return a nonzero value to say to return the function value in
4065 memory, just as large structures are always returned. TYPE will be
4066 the data type of the value, and FNTYPE will be the type of the
4067 function doing the returning, or @code{NULL} for libcalls.
4069 The AIX ABI for the RS/6000 specifies that all structures are
4070 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4071 specifies that structures <= 8 bytes are returned in r3/r4, but a
4072 draft put them in memory, and GCC used to implement the draft
4073 instead of the final standard. Therefore, aix_struct_return
4074 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4075 compatibility can change DRAFT_V4_STRUCT_RET to override the
4076 default, and -m switches get the final word. See
4077 rs6000_override_options for more details.
4079 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4080 long double support is enabled. These values are returned in memory.
4082 int_size_in_bytes returns -1 for variable size objects, which go in
4083 memory always. The cast to unsigned makes -1 > 8. */
4085 static bool
4086 rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
4088 /* In the darwin64 abi, try to use registers for larger structs
4089 if possible. */
4090 if (rs6000_darwin64_abi
4091 && TREE_CODE (type) == RECORD_TYPE
4092 && int_size_in_bytes (type) > 0)
4094 CUMULATIVE_ARGS valcum;
4095 rtx valret;
4097 valcum.words = 0;
4098 valcum.fregno = FP_ARG_MIN_REG;
4099 valcum.vregno = ALTIVEC_ARG_MIN_REG;
4100 /* Do a trial code generation as if this were going to be passed
4101 as an argument; if any part goes in memory, we return NULL. */
4102 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
4103 if (valret)
4104 return false;
4105 /* Otherwise fall through to more conventional ABI rules. */
4108 if (AGGREGATE_TYPE_P (type)
4109 && (aix_struct_return
4110 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
4111 return true;
4113 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4114 modes only exist for GCC vector types if -maltivec. */
4115 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
4116 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
4117 return false;
4119 /* Return synthetic vectors in memory. */
4120 if (TREE_CODE (type) == VECTOR_TYPE
4121 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
4123 static bool warned_for_return_big_vectors = false;
4124 if (!warned_for_return_big_vectors)
4126 warning (0, "GCC vector returned by reference: "
4127 "non-standard ABI extension with no compatibility guarantee");
4128 warned_for_return_big_vectors = true;
4130 return true;
4133 if (DEFAULT_ABI == ABI_V4 && TYPE_MODE (type) == TFmode)
4134 return true;
4136 return false;
4139 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4140 for a call to a function whose data type is FNTYPE.
4141 For a library call, FNTYPE is 0.
4143 For incoming args we set the number of arguments in the prototype large
4144 so we never return a PARALLEL. */
4146 void
4147 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
4148 rtx libname ATTRIBUTE_UNUSED, int incoming,
4149 int libcall, int n_named_args)
4151 static CUMULATIVE_ARGS zero_cumulative;
4153 *cum = zero_cumulative;
4154 cum->words = 0;
4155 cum->fregno = FP_ARG_MIN_REG;
4156 cum->vregno = ALTIVEC_ARG_MIN_REG;
4157 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
4158 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
4159 ? CALL_LIBCALL : CALL_NORMAL);
4160 cum->sysv_gregno = GP_ARG_MIN_REG;
4161 cum->stdarg = fntype
4162 && (TYPE_ARG_TYPES (fntype) != 0
4163 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4164 != void_type_node));
4166 cum->nargs_prototype = 0;
4167 if (incoming || cum->prototype)
4168 cum->nargs_prototype = n_named_args;
4170 /* Check for a longcall attribute. */
4171 if ((!fntype && rs6000_default_long_calls)
4172 || (fntype
4173 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
4174 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
4175 cum->call_cookie |= CALL_LONG;
4177 if (TARGET_DEBUG_ARG)
4179 fprintf (stderr, "\ninit_cumulative_args:");
4180 if (fntype)
4182 tree ret_type = TREE_TYPE (fntype);
4183 fprintf (stderr, " ret code = %s,",
4184 tree_code_name[ (int)TREE_CODE (ret_type) ]);
4187 if (cum->call_cookie & CALL_LONG)
4188 fprintf (stderr, " longcall,");
4190 fprintf (stderr, " proto = %d, nargs = %d\n",
4191 cum->prototype, cum->nargs_prototype);
4194 if (fntype
4195 && !TARGET_ALTIVEC
4196 && TARGET_ALTIVEC_ABI
4197 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
4199 error ("cannot return value in vector register because"
4200 " altivec instructions are disabled, use -maltivec"
4201 " to enable them");
4205 /* Return true if TYPE must be passed on the stack and not in registers. */
4207 static bool
4208 rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
4210 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
4211 return must_pass_in_stack_var_size (mode, type);
4212 else
4213 return must_pass_in_stack_var_size_or_pad (mode, type);
4216 /* If defined, a C expression which determines whether, and in which
4217 direction, to pad out an argument with extra space. The value
4218 should be of type `enum direction': either `upward' to pad above
4219 the argument, `downward' to pad below, or `none' to inhibit
4220 padding.
4222 For the AIX ABI structs are always stored left shifted in their
4223 argument slot. */
4225 enum direction
4226 function_arg_padding (enum machine_mode mode, tree type)
4228 #ifndef AGGREGATE_PADDING_FIXED
4229 #define AGGREGATE_PADDING_FIXED 0
4230 #endif
4231 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4232 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4233 #endif
4235 if (!AGGREGATE_PADDING_FIXED)
4237 /* GCC used to pass structures of the same size as integer types as
4238 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4239 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4240 passed padded downward, except that -mstrict-align further
4241 muddied the water in that multi-component structures of 2 and 4
4242 bytes in size were passed padded upward.
4244 The following arranges for best compatibility with previous
4245 versions of gcc, but removes the -mstrict-align dependency. */
4246 if (BYTES_BIG_ENDIAN)
4248 HOST_WIDE_INT size = 0;
4250 if (mode == BLKmode)
4252 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
4253 size = int_size_in_bytes (type);
4255 else
4256 size = GET_MODE_SIZE (mode);
4258 if (size == 1 || size == 2 || size == 4)
4259 return downward;
4261 return upward;
4264 if (AGGREGATES_PAD_UPWARD_ALWAYS)
4266 if (type != 0 && AGGREGATE_TYPE_P (type))
4267 return upward;
4270 /* Fall back to the default. */
4271 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
4274 /* If defined, a C expression that gives the alignment boundary, in bits,
4275 of an argument with the specified mode and type. If it is not defined,
4276 PARM_BOUNDARY is used for all arguments.
4278 V.4 wants long longs to be double word aligned.
4279 Doubleword align SPE vectors.
4280 Quadword align Altivec vectors.
4281 Quadword align large synthetic vector types. */
4284 function_arg_boundary (enum machine_mode mode, tree type)
4286 if (DEFAULT_ABI == ABI_V4 && GET_MODE_SIZE (mode) == 8)
4287 return 64;
4288 else if (SPE_VECTOR_MODE (mode)
4289 || (type && TREE_CODE (type) == VECTOR_TYPE
4290 && int_size_in_bytes (type) >= 8
4291 && int_size_in_bytes (type) < 16))
4292 return 64;
4293 else if (ALTIVEC_VECTOR_MODE (mode)
4294 || (type && TREE_CODE (type) == VECTOR_TYPE
4295 && int_size_in_bytes (type) >= 16))
4296 return 128;
4297 else if (rs6000_darwin64_abi && mode == BLKmode
4298 && type && TYPE_ALIGN (type) > 64)
4299 return 128;
4300 else
4301 return PARM_BOUNDARY;
4304 /* For a function parm of MODE and TYPE, return the starting word in
4305 the parameter area. NWORDS of the parameter area are already used. */
4307 static unsigned int
4308 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
4310 unsigned int align;
4311 unsigned int parm_offset;
4313 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
4314 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
4315 return nwords + (-(parm_offset + nwords) & align);
4318 /* Compute the size (in words) of a function argument. */
4320 static unsigned long
4321 rs6000_arg_size (enum machine_mode mode, tree type)
4323 unsigned long size;
4325 if (mode != BLKmode)
4326 size = GET_MODE_SIZE (mode);
4327 else
4328 size = int_size_in_bytes (type);
4330 if (TARGET_32BIT)
4331 return (size + 3) >> 2;
4332 else
4333 return (size + 7) >> 3;
4336 /* Use this to flush pending int fields. */
4338 static void
4339 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
4340 HOST_WIDE_INT bitpos)
4342 unsigned int startbit, endbit;
4343 int intregs, intoffset;
4344 enum machine_mode mode;
4346 if (cum->intoffset == -1)
4347 return;
4349 intoffset = cum->intoffset;
4350 cum->intoffset = -1;
4352 if (intoffset % BITS_PER_WORD != 0)
4354 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4355 MODE_INT, 0);
4356 if (mode == BLKmode)
4358 /* We couldn't find an appropriate mode, which happens,
4359 e.g., in packed structs when there are 3 bytes to load.
4360 Back intoffset back to the beginning of the word in this
4361 case. */
4362 intoffset = intoffset & -BITS_PER_WORD;
4366 startbit = intoffset & -BITS_PER_WORD;
4367 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4368 intregs = (endbit - startbit) / BITS_PER_WORD;
4369 cum->words += intregs;
4372 /* The darwin64 ABI calls for us to recurse down through structs,
4373 looking for elements passed in registers. Unfortunately, we have
4374 to track int register count here also because of misalignments
4375 in powerpc alignment mode. */
4377 static void
4378 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
4379 tree type,
4380 HOST_WIDE_INT startbitpos)
4382 tree f;
4384 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4385 if (TREE_CODE (f) == FIELD_DECL)
4387 HOST_WIDE_INT bitpos = startbitpos;
4388 tree ftype = TREE_TYPE (f);
4389 enum machine_mode mode = TYPE_MODE (ftype);
4391 if (DECL_SIZE (f) != 0
4392 && host_integerp (bit_position (f), 1))
4393 bitpos += int_bit_position (f);
4395 /* ??? FIXME: else assume zero offset. */
4397 if (TREE_CODE (ftype) == RECORD_TYPE)
4398 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
4399 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
4401 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4402 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4403 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
4405 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
4407 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4408 cum->vregno++;
4409 cum->words += 2;
4411 else if (cum->intoffset == -1)
4412 cum->intoffset = bitpos;
4416 /* Update the data in CUM to advance over an argument
4417 of mode MODE and data type TYPE.
4418 (TYPE is null for libcalls where that information may not be available.)
4420 Note that for args passed by reference, function_arg will be called
4421 with MODE and TYPE set to that of the pointer to the arg, not the arg
4422 itself. */
4424 void
4425 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4426 tree type, int named, int depth)
4428 int size;
4430 /* Only tick off an argument if we're not recursing. */
4431 if (depth == 0)
4432 cum->nargs_prototype--;
4434 if (TARGET_ALTIVEC_ABI
4435 && (ALTIVEC_VECTOR_MODE (mode)
4436 || (type && TREE_CODE (type) == VECTOR_TYPE
4437 && int_size_in_bytes (type) == 16)))
4439 bool stack = false;
4441 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
4443 cum->vregno++;
4444 if (!TARGET_ALTIVEC)
4445 error ("cannot pass argument in vector register because"
4446 " altivec instructions are disabled, use -maltivec"
4447 " to enable them");
4449 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4450 even if it is going to be passed in a vector register.
4451 Darwin does the same for variable-argument functions. */
4452 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
4453 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
4454 stack = true;
4456 else
4457 stack = true;
4459 if (stack)
4461 int align;
4463 /* Vector parameters must be 16-byte aligned. This places
4464 them at 2 mod 4 in terms of words in 32-bit mode, since
4465 the parameter save area starts at offset 24 from the
4466 stack. In 64-bit mode, they just have to start on an
4467 even word, since the parameter save area is 16-byte
4468 aligned. Space for GPRs is reserved even if the argument
4469 will be passed in memory. */
4470 if (TARGET_32BIT)
4471 align = (2 - cum->words) & 3;
4472 else
4473 align = cum->words & 1;
4474 cum->words += align + rs6000_arg_size (mode, type);
4476 if (TARGET_DEBUG_ARG)
4478 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
4479 cum->words, align);
4480 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
4481 cum->nargs_prototype, cum->prototype,
4482 GET_MODE_NAME (mode));
4486 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
4487 && !cum->stdarg
4488 && cum->sysv_gregno <= GP_ARG_MAX_REG)
4489 cum->sysv_gregno++;
4491 else if (rs6000_darwin64_abi
4492 && mode == BLKmode
4493 && TREE_CODE (type) == RECORD_TYPE
4494 && (size = int_size_in_bytes (type)) > 0)
4496 /* Variable sized types have size == -1 and are
4497 treated as if consisting entirely of ints.
4498 Pad to 16 byte boundary if needed. */
4499 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4500 && (cum->words % 2) != 0)
4501 cum->words++;
4502 /* For varargs, we can just go up by the size of the struct. */
4503 if (!named)
4504 cum->words += (size + 7) / 8;
4505 else
4507 /* It is tempting to say int register count just goes up by
4508 sizeof(type)/8, but this is wrong in a case such as
4509 { int; double; int; } [powerpc alignment]. We have to
4510 grovel through the fields for these too. */
4511 cum->intoffset = 0;
4512 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
4513 rs6000_darwin64_record_arg_advance_flush (cum,
4514 size * BITS_PER_UNIT);
4517 else if (DEFAULT_ABI == ABI_V4)
4519 if (TARGET_HARD_FLOAT && TARGET_FPRS
4520 && (mode == SFmode || mode == DFmode))
4522 if (cum->fregno <= FP_ARG_V4_MAX_REG)
4523 cum->fregno++;
4524 else
4526 if (mode == DFmode)
4527 cum->words += cum->words & 1;
4528 cum->words += rs6000_arg_size (mode, type);
4531 else
4533 int n_words = rs6000_arg_size (mode, type);
4534 int gregno = cum->sysv_gregno;
4536 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4537 (r7,r8) or (r9,r10). As does any other 2 word item such
4538 as complex int due to a historical mistake. */
4539 if (n_words == 2)
4540 gregno += (1 - gregno) & 1;
4542 /* Multi-reg args are not split between registers and stack. */
4543 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
4545 /* Long long and SPE vectors are aligned on the stack.
4546 So are other 2 word items such as complex int due to
4547 a historical mistake. */
4548 if (n_words == 2)
4549 cum->words += cum->words & 1;
4550 cum->words += n_words;
4553 /* Note: continuing to accumulate gregno past when we've started
4554 spilling to the stack indicates the fact that we've started
4555 spilling to the stack to expand_builtin_saveregs. */
4556 cum->sysv_gregno = gregno + n_words;
4559 if (TARGET_DEBUG_ARG)
4561 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
4562 cum->words, cum->fregno);
4563 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
4564 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
4565 fprintf (stderr, "mode = %4s, named = %d\n",
4566 GET_MODE_NAME (mode), named);
4569 else
4571 int n_words = rs6000_arg_size (mode, type);
4572 int start_words = cum->words;
4573 int align_words = rs6000_parm_start (mode, type, start_words);
4575 cum->words = align_words + n_words;
4577 if (GET_MODE_CLASS (mode) == MODE_FLOAT
4578 && TARGET_HARD_FLOAT && TARGET_FPRS)
4579 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4581 if (TARGET_DEBUG_ARG)
4583 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
4584 cum->words, cum->fregno);
4585 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
4586 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
4587 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
4588 named, align_words - start_words, depth);
4593 static rtx
4594 spe_build_register_parallel (enum machine_mode mode, int gregno)
4596 rtx r1, r3;
4598 switch (mode)
4600 case DFmode:
4601 r1 = gen_rtx_REG (DImode, gregno);
4602 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
4603 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
4605 case DCmode:
4606 r1 = gen_rtx_REG (DImode, gregno);
4607 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
4608 r3 = gen_rtx_REG (DImode, gregno + 2);
4609 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
4610 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
4612 default:
4613 gcc_unreachable ();
4617 /* Determine where to put a SIMD argument on the SPE. */
4618 static rtx
4619 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4620 tree type)
4622 int gregno = cum->sysv_gregno;
4624 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
4625 are passed and returned in a pair of GPRs for ABI compatibility. */
4626 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode))
4628 int n_words = rs6000_arg_size (mode, type);
4630 /* Doubles go in an odd/even register pair (r5/r6, etc). */
4631 if (mode == DFmode)
4632 gregno += (1 - gregno) & 1;
4634 /* Multi-reg args are not split between registers and stack. */
4635 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
4636 return NULL_RTX;
4638 return spe_build_register_parallel (mode, gregno);
4640 if (cum->stdarg)
4642 int n_words = rs6000_arg_size (mode, type);
4644 /* SPE vectors are put in odd registers. */
4645 if (n_words == 2 && (gregno & 1) == 0)
4646 gregno += 1;
4648 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
4650 rtx r1, r2;
4651 enum machine_mode m = SImode;
4653 r1 = gen_rtx_REG (m, gregno);
4654 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
4655 r2 = gen_rtx_REG (m, gregno + 1);
4656 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
4657 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
4659 else
4660 return NULL_RTX;
4662 else
4664 if (gregno <= GP_ARG_MAX_REG)
4665 return gen_rtx_REG (mode, gregno);
4666 else
4667 return NULL_RTX;
4671 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
4672 structure between cum->intoffset and bitpos to integer registers. */
4674 static void
4675 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
4676 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
4678 enum machine_mode mode;
4679 unsigned int regno;
4680 unsigned int startbit, endbit;
4681 int this_regno, intregs, intoffset;
4682 rtx reg;
4684 if (cum->intoffset == -1)
4685 return;
4687 intoffset = cum->intoffset;
4688 cum->intoffset = -1;
4690 /* If this is the trailing part of a word, try to only load that
4691 much into the register. Otherwise load the whole register. Note
4692 that in the latter case we may pick up unwanted bits. It's not a
4693 problem at the moment but may wish to revisit. */
4695 if (intoffset % BITS_PER_WORD != 0)
4697 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4698 MODE_INT, 0);
4699 if (mode == BLKmode)
4701 /* We couldn't find an appropriate mode, which happens,
4702 e.g., in packed structs when there are 3 bytes to load.
4703 Back intoffset back to the beginning of the word in this
4704 case. */
4705 intoffset = intoffset & -BITS_PER_WORD;
4706 mode = word_mode;
4709 else
4710 mode = word_mode;
4712 startbit = intoffset & -BITS_PER_WORD;
4713 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4714 intregs = (endbit - startbit) / BITS_PER_WORD;
4715 this_regno = cum->words + intoffset / BITS_PER_WORD;
4717 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
4718 cum->use_stack = 1;
4720 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
4721 if (intregs <= 0)
4722 return;
4724 intoffset /= BITS_PER_UNIT;
4727 regno = GP_ARG_MIN_REG + this_regno;
4728 reg = gen_rtx_REG (mode, regno);
4729 rvec[(*k)++] =
4730 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
4732 this_regno += 1;
4733 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
4734 mode = word_mode;
4735 intregs -= 1;
4737 while (intregs > 0);
4740 /* Recursive workhorse for the following. */
4742 static void
4743 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
4744 HOST_WIDE_INT startbitpos, rtx rvec[],
4745 int *k)
4747 tree f;
4749 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4750 if (TREE_CODE (f) == FIELD_DECL)
4752 HOST_WIDE_INT bitpos = startbitpos;
4753 tree ftype = TREE_TYPE (f);
4754 enum machine_mode mode = TYPE_MODE (ftype);
4756 if (DECL_SIZE (f) != 0
4757 && host_integerp (bit_position (f), 1))
4758 bitpos += int_bit_position (f);
4760 /* ??? FIXME: else assume zero offset. */
4762 if (TREE_CODE (ftype) == RECORD_TYPE)
4763 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
4764 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
4766 #if 0
4767 switch (mode)
4769 case SCmode: mode = SFmode; break;
4770 case DCmode: mode = DFmode; break;
4771 case TCmode: mode = TFmode; break;
4772 default: break;
4774 #endif
4775 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
4776 rvec[(*k)++]
4777 = gen_rtx_EXPR_LIST (VOIDmode,
4778 gen_rtx_REG (mode, cum->fregno++),
4779 GEN_INT (bitpos / BITS_PER_UNIT));
4780 if (mode == TFmode)
4781 cum->fregno++;
4783 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
4785 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
4786 rvec[(*k)++]
4787 = gen_rtx_EXPR_LIST (VOIDmode,
4788 gen_rtx_REG (mode, cum->vregno++),
4789 GEN_INT (bitpos / BITS_PER_UNIT));
4791 else if (cum->intoffset == -1)
4792 cum->intoffset = bitpos;
4796 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
4797 the register(s) to be used for each field and subfield of a struct
4798 being passed by value, along with the offset of where the
4799 register's value may be found in the block. FP fields go in FP
4800 register, vector fields go in vector registers, and everything
4801 else goes in int registers, packed as in memory.
4803 This code is also used for function return values. RETVAL indicates
4804 whether this is the case.
4806 Much of this is taken from the SPARC V9 port, which has a similar
4807 calling convention. */
4809 static rtx
4810 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, tree type,
4811 int named, bool retval)
4813 rtx rvec[FIRST_PSEUDO_REGISTER];
4814 int k = 1, kbase = 1;
4815 HOST_WIDE_INT typesize = int_size_in_bytes (type);
4816 /* This is a copy; modifications are not visible to our caller. */
4817 CUMULATIVE_ARGS copy_cum = *orig_cum;
4818 CUMULATIVE_ARGS *cum = &copy_cum;
4820 /* Pad to 16 byte boundary if needed. */
4821 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4822 && (cum->words % 2) != 0)
4823 cum->words++;
4825 cum->intoffset = 0;
4826 cum->use_stack = 0;
4827 cum->named = named;
4829 /* Put entries into rvec[] for individual FP and vector fields, and
4830 for the chunks of memory that go in int regs. Note we start at
4831 element 1; 0 is reserved for an indication of using memory, and
4832 may or may not be filled in below. */
4833 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
4834 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
4836 /* If any part of the struct went on the stack put all of it there.
4837 This hack is because the generic code for
4838 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
4839 parts of the struct are not at the beginning. */
4840 if (cum->use_stack)
4842 if (retval)
4843 return NULL_RTX; /* doesn't go in registers at all */
4844 kbase = 0;
4845 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
4847 if (k > 1 || cum->use_stack)
4848 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
4849 else
4850 return NULL_RTX;
4853 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
4855 static rtx
4856 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
4858 int n_units;
4859 int i, k;
4860 rtx rvec[GP_ARG_NUM_REG + 1];
4862 if (align_words >= GP_ARG_NUM_REG)
4863 return NULL_RTX;
4865 n_units = rs6000_arg_size (mode, type);
4867 /* Optimize the simple case where the arg fits in one gpr, except in
4868 the case of BLKmode due to assign_parms assuming that registers are
4869 BITS_PER_WORD wide. */
4870 if (n_units == 0
4871 || (n_units == 1 && mode != BLKmode))
4872 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
4874 k = 0;
4875 if (align_words + n_units > GP_ARG_NUM_REG)
4876 /* Not all of the arg fits in gprs. Say that it goes in memory too,
4877 using a magic NULL_RTX component.
4878 FIXME: This is not strictly correct. Only some of the arg
4879 belongs in memory, not all of it. However, there isn't any way
4880 to do this currently, apart from building rtx descriptions for
4881 the pieces of memory we want stored. Due to bugs in the generic
4882 code we can't use the normal function_arg_partial_nregs scheme
4883 with the PARALLEL arg description we emit here.
4884 In any case, the code to store the whole arg to memory is often
4885 more efficient than code to store pieces, and we know that space
4886 is available in the right place for the whole arg. */
4887 /* FIXME: This should be fixed since the conversion to
4888 TARGET_ARG_PARTIAL_BYTES. */
4889 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
4891 i = 0;
4894 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
4895 rtx off = GEN_INT (i++ * 4);
4896 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
4898 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
4900 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
4903 /* Determine where to put an argument to a function.
4904 Value is zero to push the argument on the stack,
4905 or a hard register in which to store the argument.
4907 MODE is the argument's machine mode.
4908 TYPE is the data type of the argument (as a tree).
4909 This is null for libcalls where that information may
4910 not be available.
4911 CUM is a variable of type CUMULATIVE_ARGS which gives info about
4912 the preceding args and about the function being called. It is
4913 not modified in this routine.
4914 NAMED is nonzero if this argument is a named parameter
4915 (otherwise it is an extra parameter matching an ellipsis).
4917 On RS/6000 the first eight words of non-FP are normally in registers
4918 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
4919 Under V.4, the first 8 FP args are in registers.
4921 If this is floating-point and no prototype is specified, we use
4922 both an FP and integer register (or possibly FP reg and stack). Library
4923 functions (when CALL_LIBCALL is set) always have the proper types for args,
4924 so we can pass the FP value just in one register. emit_library_function
4925 doesn't support PARALLEL anyway.
4927 Note that for args passed by reference, function_arg will be called
4928 with MODE and TYPE set to that of the pointer to the arg, not the arg
4929 itself. */
4932 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4933 tree type, int named)
4935 enum rs6000_abi abi = DEFAULT_ABI;
4937 /* Return a marker to indicate whether CR1 needs to set or clear the
4938 bit that V.4 uses to say fp args were passed in registers.
4939 Assume that we don't need the marker for software floating point,
4940 or compiler generated library calls. */
4941 if (mode == VOIDmode)
4943 if (abi == ABI_V4
4944 && (cum->call_cookie & CALL_LIBCALL) == 0
4945 && (cum->stdarg
4946 || (cum->nargs_prototype < 0
4947 && (cum->prototype || TARGET_NO_PROTOTYPE))))
4949 /* For the SPE, we need to crxor CR6 always. */
4950 if (TARGET_SPE_ABI)
4951 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
4952 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
4953 return GEN_INT (cum->call_cookie
4954 | ((cum->fregno == FP_ARG_MIN_REG)
4955 ? CALL_V4_SET_FP_ARGS
4956 : CALL_V4_CLEAR_FP_ARGS));
4959 return GEN_INT (cum->call_cookie);
4962 if (rs6000_darwin64_abi && mode == BLKmode
4963 && TREE_CODE (type) == RECORD_TYPE)
4965 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
4966 if (rslt != NULL_RTX)
4967 return rslt;
4968 /* Else fall through to usual handling. */
4971 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
4972 if (TARGET_64BIT && ! cum->prototype)
4974 /* Vector parameters get passed in vector register
4975 and also in GPRs or memory, in absence of prototype. */
4976 int align_words;
4977 rtx slot;
4978 align_words = (cum->words + 1) & ~1;
4980 if (align_words >= GP_ARG_NUM_REG)
4982 slot = NULL_RTX;
4984 else
4986 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
4988 return gen_rtx_PARALLEL (mode,
4989 gen_rtvec (2,
4990 gen_rtx_EXPR_LIST (VOIDmode,
4991 slot, const0_rtx),
4992 gen_rtx_EXPR_LIST (VOIDmode,
4993 gen_rtx_REG (mode, cum->vregno),
4994 const0_rtx)));
4996 else
4997 return gen_rtx_REG (mode, cum->vregno);
4998 else if (TARGET_ALTIVEC_ABI
4999 && (ALTIVEC_VECTOR_MODE (mode)
5000 || (type && TREE_CODE (type) == VECTOR_TYPE
5001 && int_size_in_bytes (type) == 16)))
5003 if (named || abi == ABI_V4)
5004 return NULL_RTX;
5005 else
5007 /* Vector parameters to varargs functions under AIX or Darwin
5008 get passed in memory and possibly also in GPRs. */
5009 int align, align_words, n_words;
5010 enum machine_mode part_mode;
5012 /* Vector parameters must be 16-byte aligned. This places them at
5013 2 mod 4 in terms of words in 32-bit mode, since the parameter
5014 save area starts at offset 24 from the stack. In 64-bit mode,
5015 they just have to start on an even word, since the parameter
5016 save area is 16-byte aligned. */
5017 if (TARGET_32BIT)
5018 align = (2 - cum->words) & 3;
5019 else
5020 align = cum->words & 1;
5021 align_words = cum->words + align;
5023 /* Out of registers? Memory, then. */
5024 if (align_words >= GP_ARG_NUM_REG)
5025 return NULL_RTX;
5027 if (TARGET_32BIT && TARGET_POWERPC64)
5028 return rs6000_mixed_function_arg (mode, type, align_words);
5030 /* The vector value goes in GPRs. Only the part of the
5031 value in GPRs is reported here. */
5032 part_mode = mode;
5033 n_words = rs6000_arg_size (mode, type);
5034 if (align_words + n_words > GP_ARG_NUM_REG)
5035 /* Fortunately, there are only two possibilities, the value
5036 is either wholly in GPRs or half in GPRs and half not. */
5037 part_mode = DImode;
5039 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
5042 else if (TARGET_SPE_ABI && TARGET_SPE
5043 && (SPE_VECTOR_MODE (mode)
5044 || (TARGET_E500_DOUBLE && (mode == DFmode
5045 || mode == DCmode))))
5046 return rs6000_spe_function_arg (cum, mode, type);
5048 else if (abi == ABI_V4)
5050 if (TARGET_HARD_FLOAT && TARGET_FPRS
5051 && (mode == SFmode || mode == DFmode))
5053 if (cum->fregno <= FP_ARG_V4_MAX_REG)
5054 return gen_rtx_REG (mode, cum->fregno);
5055 else
5056 return NULL_RTX;
5058 else
5060 int n_words = rs6000_arg_size (mode, type);
5061 int gregno = cum->sysv_gregno;
5063 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5064 (r7,r8) or (r9,r10). As does any other 2 word item such
5065 as complex int due to a historical mistake. */
5066 if (n_words == 2)
5067 gregno += (1 - gregno) & 1;
5069 /* Multi-reg args are not split between registers and stack. */
5070 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5071 return NULL_RTX;
5073 if (TARGET_32BIT && TARGET_POWERPC64)
5074 return rs6000_mixed_function_arg (mode, type,
5075 gregno - GP_ARG_MIN_REG);
5076 return gen_rtx_REG (mode, gregno);
5079 else
5081 int align_words = rs6000_parm_start (mode, type, cum->words);
5083 if (USE_FP_FOR_ARG_P (cum, mode, type))
5085 rtx rvec[GP_ARG_NUM_REG + 1];
5086 rtx r;
5087 int k;
5088 bool needs_psave;
5089 enum machine_mode fmode = mode;
5090 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
5092 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
5094 /* Currently, we only ever need one reg here because complex
5095 doubles are split. */
5096 gcc_assert (cum->fregno == FP_ARG_MAX_REG && fmode == TFmode);
5098 /* Long double split over regs and memory. */
5099 fmode = DFmode;
5102 /* Do we also need to pass this arg in the parameter save
5103 area? */
5104 needs_psave = (type
5105 && (cum->nargs_prototype <= 0
5106 || (DEFAULT_ABI == ABI_AIX
5107 && TARGET_XL_COMPAT
5108 && align_words >= GP_ARG_NUM_REG)));
5110 if (!needs_psave && mode == fmode)
5111 return gen_rtx_REG (fmode, cum->fregno);
5113 k = 0;
5114 if (needs_psave)
5116 /* Describe the part that goes in gprs or the stack.
5117 This piece must come first, before the fprs. */
5118 if (align_words < GP_ARG_NUM_REG)
5120 unsigned long n_words = rs6000_arg_size (mode, type);
5122 if (align_words + n_words > GP_ARG_NUM_REG
5123 || (TARGET_32BIT && TARGET_POWERPC64))
5125 /* If this is partially on the stack, then we only
5126 include the portion actually in registers here. */
5127 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
5128 rtx off;
5129 int i=0;
5130 if (align_words + n_words > GP_ARG_NUM_REG
5131 && (TARGET_32BIT && TARGET_POWERPC64))
5132 /* Not all of the arg fits in gprs. Say that it
5133 goes in memory too, using a magic NULL_RTX
5134 component. Also see comment in
5135 rs6000_mixed_function_arg for why the normal
5136 function_arg_partial_nregs scheme doesn't work
5137 in this case. */
5138 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
5139 const0_rtx);
5142 r = gen_rtx_REG (rmode,
5143 GP_ARG_MIN_REG + align_words);
5144 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
5145 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5147 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
5149 else
5151 /* The whole arg fits in gprs. */
5152 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5153 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5156 else
5157 /* It's entirely in memory. */
5158 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5161 /* Describe where this piece goes in the fprs. */
5162 r = gen_rtx_REG (fmode, cum->fregno);
5163 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5165 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
5167 else if (align_words < GP_ARG_NUM_REG)
5169 if (TARGET_32BIT && TARGET_POWERPC64)
5170 return rs6000_mixed_function_arg (mode, type, align_words);
5172 if (mode == BLKmode)
5173 mode = Pmode;
5175 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5177 else
5178 return NULL_RTX;
5182 /* For an arg passed partly in registers and partly in memory, this is
5183 the number of bytes passed in registers. For args passed entirely in
5184 registers or entirely in memory, zero. When an arg is described by a
5185 PARALLEL, perhaps using more than one register type, this function
5186 returns the number of bytes used by the first element of the PARALLEL. */
5188 static int
5189 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5190 tree type, bool named)
5192 int ret = 0;
5193 int align_words;
5195 if (DEFAULT_ABI == ABI_V4)
5196 return 0;
5198 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
5199 && cum->nargs_prototype >= 0)
5200 return 0;
5202 /* In this complicated case we just disable the partial_nregs code. */
5203 if (rs6000_darwin64_abi && mode == BLKmode
5204 && TREE_CODE (type) == RECORD_TYPE
5205 && int_size_in_bytes (type) > 0)
5206 return 0;
5208 align_words = rs6000_parm_start (mode, type, cum->words);
5210 if (USE_FP_FOR_ARG_P (cum, mode, type)
5211 /* If we are passing this arg in the fixed parameter save area
5212 (gprs or memory) as well as fprs, then this function should
5213 return the number of bytes passed in the parameter save area
5214 rather than bytes passed in fprs. */
5215 && !(type
5216 && (cum->nargs_prototype <= 0
5217 || (DEFAULT_ABI == ABI_AIX
5218 && TARGET_XL_COMPAT
5219 && align_words >= GP_ARG_NUM_REG))))
5221 if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) > FP_ARG_MAX_REG + 1)
5222 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
5223 else if (cum->nargs_prototype >= 0)
5224 return 0;
5227 if (align_words < GP_ARG_NUM_REG
5228 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
5229 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
5231 if (ret != 0 && TARGET_DEBUG_ARG)
5232 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
5234 return ret;
5237 /* A C expression that indicates when an argument must be passed by
5238 reference. If nonzero for an argument, a copy of that argument is
5239 made in memory and a pointer to the argument is passed instead of
5240 the argument itself. The pointer is passed in whatever way is
5241 appropriate for passing a pointer to that type.
5243 Under V.4, aggregates and long double are passed by reference.
5245 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5246 reference unless the AltiVec vector extension ABI is in force.
5248 As an extension to all ABIs, variable sized types are passed by
5249 reference. */
5251 static bool
5252 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5253 enum machine_mode mode, tree type,
5254 bool named ATTRIBUTE_UNUSED)
5256 if (DEFAULT_ABI == ABI_V4 && mode == TFmode)
5258 if (TARGET_DEBUG_ARG)
5259 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
5260 return 1;
5263 if (!type)
5264 return 0;
5266 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
5268 if (TARGET_DEBUG_ARG)
5269 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
5270 return 1;
5273 if (int_size_in_bytes (type) < 0)
5275 if (TARGET_DEBUG_ARG)
5276 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
5277 return 1;
5280 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5281 modes only exist for GCC vector types if -maltivec. */
5282 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
5284 if (TARGET_DEBUG_ARG)
5285 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
5286 return 1;
5289 /* Pass synthetic vectors in memory. */
5290 if (TREE_CODE (type) == VECTOR_TYPE
5291 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
5293 static bool warned_for_pass_big_vectors = false;
5294 if (TARGET_DEBUG_ARG)
5295 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
5296 if (!warned_for_pass_big_vectors)
5298 warning (0, "GCC vector passed by reference: "
5299 "non-standard ABI extension with no compatibility guarantee");
5300 warned_for_pass_big_vectors = true;
5302 return 1;
5305 return 0;
5308 static void
5309 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
5311 int i;
5312 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
5314 if (nregs == 0)
5315 return;
5317 for (i = 0; i < nregs; i++)
5319 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
5320 if (reload_completed)
5322 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
5323 tem = NULL_RTX;
5324 else
5325 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
5326 i * GET_MODE_SIZE (reg_mode));
5328 else
5329 tem = replace_equiv_address (tem, XEXP (tem, 0));
5331 gcc_assert (tem);
5333 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
5337 /* Perform any needed actions needed for a function that is receiving a
5338 variable number of arguments.
5340 CUM is as above.
5342 MODE and TYPE are the mode and type of the current parameter.
5344 PRETEND_SIZE is a variable that should be set to the amount of stack
5345 that must be pushed by the prolog to pretend that our caller pushed
5348 Normally, this macro will push all remaining incoming registers on the
5349 stack and set PRETEND_SIZE to the length of the registers pushed. */
5351 static void
5352 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5353 tree type, int *pretend_size ATTRIBUTE_UNUSED,
5354 int no_rtl)
5356 CUMULATIVE_ARGS next_cum;
5357 int reg_size = TARGET_32BIT ? 4 : 8;
5358 rtx save_area = NULL_RTX, mem;
5359 int first_reg_offset, set;
5361 /* Skip the last named argument. */
5362 next_cum = *cum;
5363 function_arg_advance (&next_cum, mode, type, 1, 0);
5365 if (DEFAULT_ABI == ABI_V4)
5367 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
5369 if (! no_rtl)
5371 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
5372 HOST_WIDE_INT offset = 0;
5374 /* Try to optimize the size of the varargs save area.
5375 The ABI requires that ap.reg_save_area is doubleword
5376 aligned, but we don't need to allocate space for all
5377 the bytes, only those to which we actually will save
5378 anything. */
5379 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
5380 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
5381 if (TARGET_HARD_FLOAT && TARGET_FPRS
5382 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5383 && cfun->va_list_fpr_size)
5385 if (gpr_reg_num)
5386 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
5387 * UNITS_PER_FP_WORD;
5388 if (cfun->va_list_fpr_size
5389 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5390 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
5391 else
5392 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5393 * UNITS_PER_FP_WORD;
5395 if (gpr_reg_num)
5397 offset = -((first_reg_offset * reg_size) & ~7);
5398 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
5400 gpr_reg_num = cfun->va_list_gpr_size;
5401 if (reg_size == 4 && (first_reg_offset & 1))
5402 gpr_reg_num++;
5404 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
5406 else if (fpr_size)
5407 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
5408 * UNITS_PER_FP_WORD
5409 - (int) (GP_ARG_NUM_REG * reg_size);
5411 if (gpr_size + fpr_size)
5413 rtx reg_save_area
5414 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
5415 gcc_assert (GET_CODE (reg_save_area) == MEM);
5416 reg_save_area = XEXP (reg_save_area, 0);
5417 if (GET_CODE (reg_save_area) == PLUS)
5419 gcc_assert (XEXP (reg_save_area, 0)
5420 == virtual_stack_vars_rtx);
5421 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
5422 offset += INTVAL (XEXP (reg_save_area, 1));
5424 else
5425 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
5428 cfun->machine->varargs_save_offset = offset;
5429 save_area = plus_constant (virtual_stack_vars_rtx, offset);
5432 else
5434 first_reg_offset = next_cum.words;
5435 save_area = virtual_incoming_args_rtx;
5437 if (targetm.calls.must_pass_in_stack (mode, type))
5438 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
5441 set = get_varargs_alias_set ();
5442 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
5443 && cfun->va_list_gpr_size)
5445 int nregs = GP_ARG_NUM_REG - first_reg_offset;
5447 if (va_list_gpr_counter_field)
5449 /* V4 va_list_gpr_size counts number of registers needed. */
5450 if (nregs > cfun->va_list_gpr_size)
5451 nregs = cfun->va_list_gpr_size;
5453 else
5455 /* char * va_list instead counts number of bytes needed. */
5456 if (nregs > cfun->va_list_gpr_size / reg_size)
5457 nregs = cfun->va_list_gpr_size / reg_size;
5460 mem = gen_rtx_MEM (BLKmode,
5461 plus_constant (save_area,
5462 first_reg_offset * reg_size)),
5463 set_mem_alias_set (mem, set);
5464 set_mem_align (mem, BITS_PER_WORD);
5466 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
5467 nregs);
5470 /* Save FP registers if needed. */
5471 if (DEFAULT_ABI == ABI_V4
5472 && TARGET_HARD_FLOAT && TARGET_FPRS
5473 && ! no_rtl
5474 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5475 && cfun->va_list_fpr_size)
5477 int fregno = next_cum.fregno, nregs;
5478 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
5479 rtx lab = gen_label_rtx ();
5480 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
5481 * UNITS_PER_FP_WORD);
5483 emit_jump_insn
5484 (gen_rtx_SET (VOIDmode,
5485 pc_rtx,
5486 gen_rtx_IF_THEN_ELSE (VOIDmode,
5487 gen_rtx_NE (VOIDmode, cr1,
5488 const0_rtx),
5489 gen_rtx_LABEL_REF (VOIDmode, lab),
5490 pc_rtx)));
5492 for (nregs = 0;
5493 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
5494 fregno++, off += UNITS_PER_FP_WORD, nregs++)
5496 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
5497 set_mem_alias_set (mem, set);
5498 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
5499 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
5502 emit_label (lab);
5506 /* Create the va_list data type. */
5508 static tree
5509 rs6000_build_builtin_va_list (void)
5511 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
5513 /* For AIX, prefer 'char *' because that's what the system
5514 header files like. */
5515 if (DEFAULT_ABI != ABI_V4)
5516 return build_pointer_type (char_type_node);
5518 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5519 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5521 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
5522 unsigned_char_type_node);
5523 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
5524 unsigned_char_type_node);
5525 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
5526 every user file. */
5527 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
5528 short_unsigned_type_node);
5529 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
5530 ptr_type_node);
5531 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
5532 ptr_type_node);
5534 va_list_gpr_counter_field = f_gpr;
5535 va_list_fpr_counter_field = f_fpr;
5537 DECL_FIELD_CONTEXT (f_gpr) = record;
5538 DECL_FIELD_CONTEXT (f_fpr) = record;
5539 DECL_FIELD_CONTEXT (f_res) = record;
5540 DECL_FIELD_CONTEXT (f_ovf) = record;
5541 DECL_FIELD_CONTEXT (f_sav) = record;
5543 TREE_CHAIN (record) = type_decl;
5544 TYPE_NAME (record) = type_decl;
5545 TYPE_FIELDS (record) = f_gpr;
5546 TREE_CHAIN (f_gpr) = f_fpr;
5547 TREE_CHAIN (f_fpr) = f_res;
5548 TREE_CHAIN (f_res) = f_ovf;
5549 TREE_CHAIN (f_ovf) = f_sav;
5551 layout_type (record);
5553 /* The correct type is an array type of one element. */
5554 return build_array_type (record, build_index_type (size_zero_node));
5557 /* Implement va_start. */
5559 void
5560 rs6000_va_start (tree valist, rtx nextarg)
5562 HOST_WIDE_INT words, n_gpr, n_fpr;
5563 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
5564 tree gpr, fpr, ovf, sav, t;
5566 /* Only SVR4 needs something special. */
5567 if (DEFAULT_ABI != ABI_V4)
5569 std_expand_builtin_va_start (valist, nextarg);
5570 return;
5573 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
5574 f_fpr = TREE_CHAIN (f_gpr);
5575 f_res = TREE_CHAIN (f_fpr);
5576 f_ovf = TREE_CHAIN (f_res);
5577 f_sav = TREE_CHAIN (f_ovf);
5579 valist = build_va_arg_indirect_ref (valist);
5580 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
5581 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
5582 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
5583 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
5585 /* Count number of gp and fp argument registers used. */
5586 words = current_function_args_info.words;
5587 n_gpr = MIN (current_function_args_info.sysv_gregno - GP_ARG_MIN_REG,
5588 GP_ARG_NUM_REG);
5589 n_fpr = MIN (current_function_args_info.fregno - FP_ARG_MIN_REG,
5590 FP_ARG_NUM_REG);
5592 if (TARGET_DEBUG_ARG)
5593 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
5594 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
5595 words, n_gpr, n_fpr);
5597 if (cfun->va_list_gpr_size)
5599 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
5600 build_int_cst (NULL_TREE, n_gpr));
5601 TREE_SIDE_EFFECTS (t) = 1;
5602 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5605 if (cfun->va_list_fpr_size)
5607 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
5608 build_int_cst (NULL_TREE, n_fpr));
5609 TREE_SIDE_EFFECTS (t) = 1;
5610 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5613 /* Find the overflow area. */
5614 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
5615 if (words != 0)
5616 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
5617 build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
5618 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
5619 TREE_SIDE_EFFECTS (t) = 1;
5620 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5622 /* If there were no va_arg invocations, don't set up the register
5623 save area. */
5624 if (!cfun->va_list_gpr_size
5625 && !cfun->va_list_fpr_size
5626 && n_gpr < GP_ARG_NUM_REG
5627 && n_fpr < FP_ARG_V4_MAX_REG)
5628 return;
5630 /* Find the register save area. */
5631 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
5632 if (cfun->machine->varargs_save_offset)
5633 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
5634 build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
5635 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
5636 TREE_SIDE_EFFECTS (t) = 1;
5637 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5640 /* Implement va_arg. */
5642 tree
5643 rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
5645 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
5646 tree gpr, fpr, ovf, sav, reg, t, u;
5647 int size, rsize, n_reg, sav_ofs, sav_scale;
5648 tree lab_false, lab_over, addr;
5649 int align;
5650 tree ptrtype = build_pointer_type (type);
5652 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
5654 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
5655 return build_va_arg_indirect_ref (t);
5658 if (DEFAULT_ABI != ABI_V4)
5660 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
5662 tree elem_type = TREE_TYPE (type);
5663 enum machine_mode elem_mode = TYPE_MODE (elem_type);
5664 int elem_size = GET_MODE_SIZE (elem_mode);
5666 if (elem_size < UNITS_PER_WORD)
5668 tree real_part, imag_part;
5669 tree post = NULL_TREE;
5671 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
5672 &post);
5673 /* Copy the value into a temporary, lest the formal temporary
5674 be reused out from under us. */
5675 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
5676 append_to_statement_list (post, pre_p);
5678 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
5679 post_p);
5681 return build (COMPLEX_EXPR, type, real_part, imag_part);
5685 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
5688 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
5689 f_fpr = TREE_CHAIN (f_gpr);
5690 f_res = TREE_CHAIN (f_fpr);
5691 f_ovf = TREE_CHAIN (f_res);
5692 f_sav = TREE_CHAIN (f_ovf);
5694 valist = build_va_arg_indirect_ref (valist);
5695 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
5696 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
5697 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
5698 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
5700 size = int_size_in_bytes (type);
5701 rsize = (size + 3) / 4;
5702 align = 1;
5704 if (TARGET_HARD_FLOAT && TARGET_FPRS
5705 && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode))
5707 /* FP args go in FP registers, if present. */
5708 reg = fpr;
5709 n_reg = 1;
5710 sav_ofs = 8*4;
5711 sav_scale = 8;
5712 if (TYPE_MODE (type) == DFmode)
5713 align = 8;
5715 else
5717 /* Otherwise into GP registers. */
5718 reg = gpr;
5719 n_reg = rsize;
5720 sav_ofs = 0;
5721 sav_scale = 4;
5722 if (n_reg == 2)
5723 align = 8;
5726 /* Pull the value out of the saved registers.... */
5728 lab_over = NULL;
5729 addr = create_tmp_var (ptr_type_node, "addr");
5730 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
5732 /* AltiVec vectors never go in registers when -mabi=altivec. */
5733 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
5734 align = 16;
5735 else
5737 lab_false = create_artificial_label ();
5738 lab_over = create_artificial_label ();
5740 /* Long long and SPE vectors are aligned in the registers.
5741 As are any other 2 gpr item such as complex int due to a
5742 historical mistake. */
5743 u = reg;
5744 if (n_reg == 2)
5746 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
5747 size_int (n_reg - 1));
5748 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
5751 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
5752 t = build2 (GE_EXPR, boolean_type_node, u, t);
5753 u = build1 (GOTO_EXPR, void_type_node, lab_false);
5754 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
5755 gimplify_and_add (t, pre_p);
5757 t = sav;
5758 if (sav_ofs)
5759 t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
5761 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
5762 u = build1 (CONVERT_EXPR, integer_type_node, u);
5763 u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
5764 t = build2 (PLUS_EXPR, ptr_type_node, t, u);
5766 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
5767 gimplify_and_add (t, pre_p);
5769 t = build1 (GOTO_EXPR, void_type_node, lab_over);
5770 gimplify_and_add (t, pre_p);
5772 t = build1 (LABEL_EXPR, void_type_node, lab_false);
5773 append_to_statement_list (t, pre_p);
5775 if (n_reg > 2)
5777 /* Ensure that we don't find any more args in regs.
5778 Alignment has taken care of the n_reg == 2 case. */
5779 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, size_int (8));
5780 gimplify_and_add (t, pre_p);
5784 /* ... otherwise out of the overflow area. */
5786 /* Care for on-stack alignment if needed. */
5787 t = ovf;
5788 if (align != 1)
5790 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
5791 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
5792 build_int_cst (NULL_TREE, -align));
5794 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
5796 u = build2 (MODIFY_EXPR, void_type_node, addr, t);
5797 gimplify_and_add (u, pre_p);
5799 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
5800 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
5801 gimplify_and_add (t, pre_p);
5803 if (lab_over)
5805 t = build1 (LABEL_EXPR, void_type_node, lab_over);
5806 append_to_statement_list (t, pre_p);
5809 addr = fold_convert (ptrtype, addr);
5810 return build_va_arg_indirect_ref (addr);
5813 /* Builtins. */
5815 static void
5816 def_builtin (int mask, const char *name, tree type, int code)
5818 if (mask & target_flags)
5820 if (rs6000_builtin_decls[code])
5821 abort ();
5823 rs6000_builtin_decls[code] =
5824 lang_hooks.builtin_function (name, type, code, BUILT_IN_MD,
5825 NULL, NULL_TREE);
5829 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
5831 static const struct builtin_description bdesc_3arg[] =
5833 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
5834 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
5835 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
5836 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
5837 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
5838 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
5839 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
5840 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
5841 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
5842 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
5843 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
5844 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
5845 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
5846 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
5847 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
5848 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
5849 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
5850 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
5851 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
5852 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
5853 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
5854 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
5855 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
5857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
5858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
5859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
5860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
5861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
5862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
5863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
5864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
5865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
5866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
5867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
5868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
5869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
5870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
5871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
5874 /* DST operations: void foo (void *, const int, const char). */
5876 static const struct builtin_description bdesc_dst[] =
5878 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
5879 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
5880 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
5881 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
5883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
5884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
5885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
5886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
5889 /* Simple binary operations: VECc = foo (VECa, VECb). */
5891 static struct builtin_description bdesc_2arg[] =
5893 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
5894 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
5895 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
5896 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
5897 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
5898 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
5899 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
5900 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
5901 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
5902 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
5903 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
5904 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
5905 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
5906 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
5907 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
5908 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
5909 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
5910 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
5911 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
5912 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
5913 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
5914 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
5915 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
5916 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
5917 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
5918 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
5919 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
5920 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
5921 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
5922 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
5923 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
5924 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
5925 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
5926 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
5927 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
5928 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
5929 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
5930 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
5931 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
5932 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
5933 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
5934 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
5935 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
5936 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
5937 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
5938 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
5939 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
5940 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
5941 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
5942 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
5943 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
5944 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
5945 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
5946 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
5947 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
5948 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
5949 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
5950 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
5951 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
5952 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
5953 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
5954 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
5955 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
5956 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
5957 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
5958 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
5959 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
5960 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
5961 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
5962 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
5963 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
5964 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
5965 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
5966 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
5967 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
5968 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
5969 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
5970 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
5971 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
5972 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
5973 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
5974 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
5975 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
5976 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
5977 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
5978 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
5979 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
5980 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
5981 { MASK_ALTIVEC, CODE_FOR_lshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
5982 { MASK_ALTIVEC, CODE_FOR_lshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
5983 { MASK_ALTIVEC, CODE_FOR_lshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
5984 { MASK_ALTIVEC, CODE_FOR_ashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
5985 { MASK_ALTIVEC, CODE_FOR_ashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
5986 { MASK_ALTIVEC, CODE_FOR_ashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
5987 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
5988 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
5989 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
5990 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
5991 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
5992 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
5993 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
5994 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
5995 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
5996 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
5997 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
5998 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
5999 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
6000 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
6001 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
6002 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
6003 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
6004 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
6005 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
6007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
6008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
6009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
6010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
6011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
6012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
6013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
6014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
6015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
6016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
6017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
6018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
6019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
6020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
6021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
6022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
6023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
6024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
6025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
6026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
6027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
6028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
6029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
6030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
6031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
6032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
6033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
6034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
6035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
6036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
6037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
6038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
6039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
6040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
6041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
6042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
6043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
6044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
6045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
6046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
6047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
6048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
6049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
6050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
6051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
6052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
6053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
6054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
6055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
6056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
6057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
6058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
6059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
6060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
6061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
6062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
6063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
6064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
6065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
6066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
6067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
6068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
6069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
6070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
6071 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
6072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
6073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
6074 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
6075 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
6076 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
6077 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
6078 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
6079 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
6080 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
6081 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
6082 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
6083 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
6084 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
6085 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
6086 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
6087 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
6088 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
6089 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
6090 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
6091 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
6092 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
6093 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
6094 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
6095 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
6096 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
6097 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
6098 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
6099 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
6100 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
6101 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
6102 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
6103 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
6104 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
6105 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
6106 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
6107 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
6108 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
6109 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
6110 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
6111 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
6112 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
6113 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
6114 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
6115 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
6116 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
6117 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
6118 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
6119 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
6120 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
6121 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
6122 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
6123 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
6124 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
6125 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
6126 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
6127 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
6128 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
6129 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
6130 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
6131 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
6132 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
6133 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
6135 /* Place holder, leave as first spe builtin. */
6136 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
6137 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
6138 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
6139 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
6140 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
6141 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
6142 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
6143 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
6144 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
6145 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
6146 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
6147 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
6148 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
6149 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
6150 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
6151 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
6152 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
6153 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
6154 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
6155 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
6156 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
6157 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
6158 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
6159 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
6160 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
6161 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
6162 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
6163 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
6164 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
6165 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
6166 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
6167 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
6168 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
6169 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
6170 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
6171 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
6172 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
6173 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
6174 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
6175 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
6176 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
6177 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
6178 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
6179 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
6180 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
6181 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
6182 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
6183 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
6184 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
6185 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
6186 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
6187 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
6188 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
6189 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
6190 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
6191 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
6192 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
6193 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
6194 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
6195 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
6196 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
6197 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
6198 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
6199 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
6200 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
6201 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
6202 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
6203 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
6204 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
6205 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
6206 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
6207 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
6208 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
6209 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
6210 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
6211 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
6212 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
6213 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
6214 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
6215 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
6216 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
6217 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
6218 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
6219 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
6220 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
6221 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
6222 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
6223 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
6224 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
6225 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
6226 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
6227 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
6228 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
6229 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
6230 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
6231 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
6232 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
6233 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
6234 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
6235 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
6236 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
6237 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
6238 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
6239 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
6240 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
6241 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
6242 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
6243 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
6244 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
6246 /* SPE binary operations expecting a 5-bit unsigned literal. */
6247 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
6249 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
6250 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
6251 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
6252 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
6253 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
6254 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
6255 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
6256 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
6257 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
6258 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
6259 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
6260 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
6261 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
6262 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
6263 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
6264 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
6265 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
6266 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
6267 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
6268 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
6269 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
6270 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
6271 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
6272 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
6273 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
6274 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
6276 /* Place-holder. Leave as last binary SPE builtin. */
6277 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
6280 /* AltiVec predicates. */
6282 struct builtin_description_predicates
6284 const unsigned int mask;
6285 const enum insn_code icode;
6286 const char *opcode;
6287 const char *const name;
6288 const enum rs6000_builtins code;
6291 static const struct builtin_description_predicates bdesc_altivec_preds[] =
6293 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
6294 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
6295 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
6296 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
6297 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
6298 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
6299 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
6300 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
6301 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
6302 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
6303 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
6304 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
6305 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
6307 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
6308 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
6309 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
6312 /* SPE predicates. */
6313 static struct builtin_description bdesc_spe_predicates[] =
6315 /* Place-holder. Leave as first. */
6316 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
6317 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
6318 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
6319 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
6320 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
6321 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
6322 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
6323 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
6324 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
6325 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
6326 /* Place-holder. Leave as last. */
6327 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
6330 /* SPE evsel predicates. */
6331 static struct builtin_description bdesc_spe_evsel[] =
6333 /* Place-holder. Leave as first. */
6334 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
6335 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
6336 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
6337 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
6338 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
6339 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
6340 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
6341 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
6342 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
6343 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
6344 /* Place-holder. Leave as last. */
6345 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
6348 /* ABS* operations. */
6350 static const struct builtin_description bdesc_abs[] =
6352 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
6353 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
6354 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
6355 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
6356 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
6357 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
6358 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
6361 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6362 foo (VECa). */
6364 static struct builtin_description bdesc_1arg[] =
6366 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
6367 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
6368 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
6369 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
6370 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
6371 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
6372 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
6373 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
6374 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
6375 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
6376 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
6377 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
6378 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
6379 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
6380 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
6381 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
6382 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
6384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
6385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
6386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
6387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
6388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
6389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
6390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
6391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
6392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
6393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
6394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
6395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
6396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
6397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
6398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
6399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
6400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
6401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
6402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
6404 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6405 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6406 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
6407 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
6408 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
6409 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
6410 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
6411 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
6412 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
6413 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
6414 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
6415 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
6416 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
6417 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
6418 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
6419 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
6420 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
6421 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
6422 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
6423 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
6424 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
6425 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
6426 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
6427 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
6428 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
6429 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
6430 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
6431 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
6432 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
6433 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
6435 /* Place-holder. Leave as last unary SPE builtin. */
6436 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW }
6439 static rtx
6440 rs6000_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
6442 rtx pat;
6443 tree arg0 = TREE_VALUE (arglist);
6444 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6445 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6446 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6448 if (icode == CODE_FOR_nothing)
6449 /* Builtin not supported on this processor. */
6450 return 0;
6452 /* If we got invalid arguments bail out before generating bad rtl. */
6453 if (arg0 == error_mark_node)
6454 return const0_rtx;
6456 if (icode == CODE_FOR_altivec_vspltisb
6457 || icode == CODE_FOR_altivec_vspltish
6458 || icode == CODE_FOR_altivec_vspltisw
6459 || icode == CODE_FOR_spe_evsplatfi
6460 || icode == CODE_FOR_spe_evsplati)
6462 /* Only allow 5-bit *signed* literals. */
6463 if (GET_CODE (op0) != CONST_INT
6464 || INTVAL (op0) > 15
6465 || INTVAL (op0) < -16)
6467 error ("argument 1 must be a 5-bit signed literal");
6468 return const0_rtx;
6472 if (target == 0
6473 || GET_MODE (target) != tmode
6474 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6475 target = gen_reg_rtx (tmode);
6477 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6478 op0 = copy_to_mode_reg (mode0, op0);
6480 pat = GEN_FCN (icode) (target, op0);
6481 if (! pat)
6482 return 0;
6483 emit_insn (pat);
6485 return target;
6488 static rtx
6489 altivec_expand_abs_builtin (enum insn_code icode, tree arglist, rtx target)
6491 rtx pat, scratch1, scratch2;
6492 tree arg0 = TREE_VALUE (arglist);
6493 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6494 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6495 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6497 /* If we have invalid arguments, bail out before generating bad rtl. */
6498 if (arg0 == error_mark_node)
6499 return const0_rtx;
6501 if (target == 0
6502 || GET_MODE (target) != tmode
6503 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6504 target = gen_reg_rtx (tmode);
6506 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6507 op0 = copy_to_mode_reg (mode0, op0);
6509 scratch1 = gen_reg_rtx (mode0);
6510 scratch2 = gen_reg_rtx (mode0);
6512 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
6513 if (! pat)
6514 return 0;
6515 emit_insn (pat);
6517 return target;
6520 static rtx
6521 rs6000_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
6523 rtx pat;
6524 tree arg0 = TREE_VALUE (arglist);
6525 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6526 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6527 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6528 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6529 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6530 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6532 if (icode == CODE_FOR_nothing)
6533 /* Builtin not supported on this processor. */
6534 return 0;
6536 /* If we got invalid arguments bail out before generating bad rtl. */
6537 if (arg0 == error_mark_node || arg1 == error_mark_node)
6538 return const0_rtx;
6540 if (icode == CODE_FOR_altivec_vcfux
6541 || icode == CODE_FOR_altivec_vcfsx
6542 || icode == CODE_FOR_altivec_vctsxs
6543 || icode == CODE_FOR_altivec_vctuxs
6544 || icode == CODE_FOR_altivec_vspltb
6545 || icode == CODE_FOR_altivec_vsplth
6546 || icode == CODE_FOR_altivec_vspltw
6547 || icode == CODE_FOR_spe_evaddiw
6548 || icode == CODE_FOR_spe_evldd
6549 || icode == CODE_FOR_spe_evldh
6550 || icode == CODE_FOR_spe_evldw
6551 || icode == CODE_FOR_spe_evlhhesplat
6552 || icode == CODE_FOR_spe_evlhhossplat
6553 || icode == CODE_FOR_spe_evlhhousplat
6554 || icode == CODE_FOR_spe_evlwhe
6555 || icode == CODE_FOR_spe_evlwhos
6556 || icode == CODE_FOR_spe_evlwhou
6557 || icode == CODE_FOR_spe_evlwhsplat
6558 || icode == CODE_FOR_spe_evlwwsplat
6559 || icode == CODE_FOR_spe_evrlwi
6560 || icode == CODE_FOR_spe_evslwi
6561 || icode == CODE_FOR_spe_evsrwis
6562 || icode == CODE_FOR_spe_evsubifw
6563 || icode == CODE_FOR_spe_evsrwiu)
6565 /* Only allow 5-bit unsigned literals. */
6566 STRIP_NOPS (arg1);
6567 if (TREE_CODE (arg1) != INTEGER_CST
6568 || TREE_INT_CST_LOW (arg1) & ~0x1f)
6570 error ("argument 2 must be a 5-bit unsigned literal");
6571 return const0_rtx;
6575 if (target == 0
6576 || GET_MODE (target) != tmode
6577 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6578 target = gen_reg_rtx (tmode);
6580 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6581 op0 = copy_to_mode_reg (mode0, op0);
6582 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6583 op1 = copy_to_mode_reg (mode1, op1);
6585 pat = GEN_FCN (icode) (target, op0, op1);
6586 if (! pat)
6587 return 0;
6588 emit_insn (pat);
6590 return target;
6593 static rtx
6594 altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
6595 tree arglist, rtx target)
6597 rtx pat, scratch;
6598 tree cr6_form = TREE_VALUE (arglist);
6599 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
6600 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6601 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6602 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6603 enum machine_mode tmode = SImode;
6604 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6605 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6606 int cr6_form_int;
6608 if (TREE_CODE (cr6_form) != INTEGER_CST)
6610 error ("argument 1 of __builtin_altivec_predicate must be a constant");
6611 return const0_rtx;
6613 else
6614 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
6616 gcc_assert (mode0 == mode1);
6618 /* If we have invalid arguments, bail out before generating bad rtl. */
6619 if (arg0 == error_mark_node || arg1 == error_mark_node)
6620 return const0_rtx;
6622 if (target == 0
6623 || GET_MODE (target) != tmode
6624 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6625 target = gen_reg_rtx (tmode);
6627 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6628 op0 = copy_to_mode_reg (mode0, op0);
6629 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6630 op1 = copy_to_mode_reg (mode1, op1);
6632 scratch = gen_reg_rtx (mode0);
6634 pat = GEN_FCN (icode) (scratch, op0, op1,
6635 gen_rtx_SYMBOL_REF (Pmode, opcode));
6636 if (! pat)
6637 return 0;
6638 emit_insn (pat);
6640 /* The vec_any* and vec_all* predicates use the same opcodes for two
6641 different operations, but the bits in CR6 will be different
6642 depending on what information we want. So we have to play tricks
6643 with CR6 to get the right bits out.
6645 If you think this is disgusting, look at the specs for the
6646 AltiVec predicates. */
6648 switch (cr6_form_int)
6650 case 0:
6651 emit_insn (gen_cr6_test_for_zero (target));
6652 break;
6653 case 1:
6654 emit_insn (gen_cr6_test_for_zero_reverse (target));
6655 break;
6656 case 2:
6657 emit_insn (gen_cr6_test_for_lt (target));
6658 break;
6659 case 3:
6660 emit_insn (gen_cr6_test_for_lt_reverse (target));
6661 break;
6662 default:
6663 error ("argument 1 of __builtin_altivec_predicate is out of range");
6664 break;
6667 return target;
6670 static rtx
6671 altivec_expand_lv_builtin (enum insn_code icode, tree arglist, rtx target)
6673 rtx pat, addr;
6674 tree arg0 = TREE_VALUE (arglist);
6675 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6676 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6677 enum machine_mode mode0 = Pmode;
6678 enum machine_mode mode1 = Pmode;
6679 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6680 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6682 if (icode == CODE_FOR_nothing)
6683 /* Builtin not supported on this processor. */
6684 return 0;
6686 /* If we got invalid arguments bail out before generating bad rtl. */
6687 if (arg0 == error_mark_node || arg1 == error_mark_node)
6688 return const0_rtx;
6690 if (target == 0
6691 || GET_MODE (target) != tmode
6692 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6693 target = gen_reg_rtx (tmode);
6695 op1 = copy_to_mode_reg (mode1, op1);
6697 if (op0 == const0_rtx)
6699 addr = gen_rtx_MEM (tmode, op1);
6701 else
6703 op0 = copy_to_mode_reg (mode0, op0);
6704 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
6707 pat = GEN_FCN (icode) (target, addr);
6709 if (! pat)
6710 return 0;
6711 emit_insn (pat);
6713 return target;
6716 static rtx
6717 spe_expand_stv_builtin (enum insn_code icode, tree arglist)
6719 tree arg0 = TREE_VALUE (arglist);
6720 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6721 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6722 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6723 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6724 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
6725 rtx pat;
6726 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
6727 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
6728 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
6730 /* Invalid arguments. Bail before doing anything stoopid! */
6731 if (arg0 == error_mark_node
6732 || arg1 == error_mark_node
6733 || arg2 == error_mark_node)
6734 return const0_rtx;
6736 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
6737 op0 = copy_to_mode_reg (mode2, op0);
6738 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
6739 op1 = copy_to_mode_reg (mode0, op1);
6740 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
6741 op2 = copy_to_mode_reg (mode1, op2);
6743 pat = GEN_FCN (icode) (op1, op2, op0);
6744 if (pat)
6745 emit_insn (pat);
6746 return NULL_RTX;
6749 static rtx
6750 altivec_expand_stv_builtin (enum insn_code icode, tree arglist)
6752 tree arg0 = TREE_VALUE (arglist);
6753 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6754 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6755 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6756 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6757 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
6758 rtx pat, addr;
6759 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6760 enum machine_mode mode1 = Pmode;
6761 enum machine_mode mode2 = Pmode;
6763 /* Invalid arguments. Bail before doing anything stoopid! */
6764 if (arg0 == error_mark_node
6765 || arg1 == error_mark_node
6766 || arg2 == error_mark_node)
6767 return const0_rtx;
6769 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
6770 op0 = copy_to_mode_reg (tmode, op0);
6772 op2 = copy_to_mode_reg (mode2, op2);
6774 if (op1 == const0_rtx)
6776 addr = gen_rtx_MEM (tmode, op2);
6778 else
6780 op1 = copy_to_mode_reg (mode1, op1);
6781 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
6784 pat = GEN_FCN (icode) (addr, op0);
6785 if (pat)
6786 emit_insn (pat);
6787 return NULL_RTX;
6790 static rtx
6791 rs6000_expand_ternop_builtin (enum insn_code icode, tree arglist, rtx target)
6793 rtx pat;
6794 tree arg0 = TREE_VALUE (arglist);
6795 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6796 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6797 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6798 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6799 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
6800 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6801 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6802 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6803 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
6805 if (icode == CODE_FOR_nothing)
6806 /* Builtin not supported on this processor. */
6807 return 0;
6809 /* If we got invalid arguments bail out before generating bad rtl. */
6810 if (arg0 == error_mark_node
6811 || arg1 == error_mark_node
6812 || arg2 == error_mark_node)
6813 return const0_rtx;
6815 if (icode == CODE_FOR_altivec_vsldoi_v4sf
6816 || icode == CODE_FOR_altivec_vsldoi_v4si
6817 || icode == CODE_FOR_altivec_vsldoi_v8hi
6818 || icode == CODE_FOR_altivec_vsldoi_v16qi)
6820 /* Only allow 4-bit unsigned literals. */
6821 STRIP_NOPS (arg2);
6822 if (TREE_CODE (arg2) != INTEGER_CST
6823 || TREE_INT_CST_LOW (arg2) & ~0xf)
6825 error ("argument 3 must be a 4-bit unsigned literal");
6826 return const0_rtx;
6830 if (target == 0
6831 || GET_MODE (target) != tmode
6832 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6833 target = gen_reg_rtx (tmode);
6835 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6836 op0 = copy_to_mode_reg (mode0, op0);
6837 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6838 op1 = copy_to_mode_reg (mode1, op1);
6839 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
6840 op2 = copy_to_mode_reg (mode2, op2);
6842 pat = GEN_FCN (icode) (target, op0, op1, op2);
6843 if (! pat)
6844 return 0;
6845 emit_insn (pat);
6847 return target;
6850 /* Expand the lvx builtins. */
6851 static rtx
6852 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
6854 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6855 tree arglist = TREE_OPERAND (exp, 1);
6856 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6857 tree arg0;
6858 enum machine_mode tmode, mode0;
6859 rtx pat, op0;
6860 enum insn_code icode;
6862 switch (fcode)
6864 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
6865 icode = CODE_FOR_altivec_lvx_v16qi;
6866 break;
6867 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
6868 icode = CODE_FOR_altivec_lvx_v8hi;
6869 break;
6870 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
6871 icode = CODE_FOR_altivec_lvx_v4si;
6872 break;
6873 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
6874 icode = CODE_FOR_altivec_lvx_v4sf;
6875 break;
6876 default:
6877 *expandedp = false;
6878 return NULL_RTX;
6881 *expandedp = true;
6883 arg0 = TREE_VALUE (arglist);
6884 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6885 tmode = insn_data[icode].operand[0].mode;
6886 mode0 = insn_data[icode].operand[1].mode;
6888 if (target == 0
6889 || GET_MODE (target) != tmode
6890 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6891 target = gen_reg_rtx (tmode);
6893 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6894 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
6896 pat = GEN_FCN (icode) (target, op0);
6897 if (! pat)
6898 return 0;
6899 emit_insn (pat);
6900 return target;
6903 /* Expand the stvx builtins. */
6904 static rtx
6905 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
6906 bool *expandedp)
6908 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6909 tree arglist = TREE_OPERAND (exp, 1);
6910 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6911 tree arg0, arg1;
6912 enum machine_mode mode0, mode1;
6913 rtx pat, op0, op1;
6914 enum insn_code icode;
6916 switch (fcode)
6918 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
6919 icode = CODE_FOR_altivec_stvx_v16qi;
6920 break;
6921 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
6922 icode = CODE_FOR_altivec_stvx_v8hi;
6923 break;
6924 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
6925 icode = CODE_FOR_altivec_stvx_v4si;
6926 break;
6927 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
6928 icode = CODE_FOR_altivec_stvx_v4sf;
6929 break;
6930 default:
6931 *expandedp = false;
6932 return NULL_RTX;
6935 arg0 = TREE_VALUE (arglist);
6936 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6937 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6938 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6939 mode0 = insn_data[icode].operand[0].mode;
6940 mode1 = insn_data[icode].operand[1].mode;
6942 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
6943 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
6944 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
6945 op1 = copy_to_mode_reg (mode1, op1);
6947 pat = GEN_FCN (icode) (op0, op1);
6948 if (pat)
6949 emit_insn (pat);
6951 *expandedp = true;
6952 return NULL_RTX;
6955 /* Expand the dst builtins. */
6956 static rtx
6957 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
6958 bool *expandedp)
6960 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6961 tree arglist = TREE_OPERAND (exp, 1);
6962 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6963 tree arg0, arg1, arg2;
6964 enum machine_mode mode0, mode1, mode2;
6965 rtx pat, op0, op1, op2;
6966 struct builtin_description *d;
6967 size_t i;
6969 *expandedp = false;
6971 /* Handle DST variants. */
6972 d = (struct builtin_description *) bdesc_dst;
6973 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
6974 if (d->code == fcode)
6976 arg0 = TREE_VALUE (arglist);
6977 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6978 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6979 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
6980 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6981 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
6982 mode0 = insn_data[d->icode].operand[0].mode;
6983 mode1 = insn_data[d->icode].operand[1].mode;
6984 mode2 = insn_data[d->icode].operand[2].mode;
6986 /* Invalid arguments, bail out before generating bad rtl. */
6987 if (arg0 == error_mark_node
6988 || arg1 == error_mark_node
6989 || arg2 == error_mark_node)
6990 return const0_rtx;
6992 *expandedp = true;
6993 STRIP_NOPS (arg2);
6994 if (TREE_CODE (arg2) != INTEGER_CST
6995 || TREE_INT_CST_LOW (arg2) & ~0x3)
6997 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
6998 return const0_rtx;
7001 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
7002 op0 = copy_to_mode_reg (Pmode, op0);
7003 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
7004 op1 = copy_to_mode_reg (mode1, op1);
7006 pat = GEN_FCN (d->icode) (op0, op1, op2);
7007 if (pat != 0)
7008 emit_insn (pat);
7010 return NULL_RTX;
7013 return NULL_RTX;
7016 /* Expand vec_init builtin. */
7017 static rtx
7018 altivec_expand_vec_init_builtin (tree type, tree arglist, rtx target)
7020 enum machine_mode tmode = TYPE_MODE (type);
7021 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
7022 int i, n_elt = GET_MODE_NUNITS (tmode);
7023 rtvec v = rtvec_alloc (n_elt);
7025 gcc_assert (VECTOR_MODE_P (tmode));
7027 for (i = 0; i < n_elt; ++i, arglist = TREE_CHAIN (arglist))
7029 rtx x = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
7030 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
7033 gcc_assert (arglist == NULL);
7035 if (!target || !register_operand (target, tmode))
7036 target = gen_reg_rtx (tmode);
7038 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
7039 return target;
7042 /* Return the integer constant in ARG. Constrain it to be in the range
7043 of the subparts of VEC_TYPE; issue an error if not. */
7045 static int
7046 get_element_number (tree vec_type, tree arg)
7048 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
7050 if (!host_integerp (arg, 1)
7051 || (elt = tree_low_cst (arg, 1), elt > max))
7053 error ("selector must be an integer constant in the range 0..%wi", max);
7054 return 0;
7057 return elt;
7060 /* Expand vec_set builtin. */
7061 static rtx
7062 altivec_expand_vec_set_builtin (tree arglist)
7064 enum machine_mode tmode, mode1;
7065 tree arg0, arg1, arg2;
7066 int elt;
7067 rtx op0, op1;
7069 arg0 = TREE_VALUE (arglist);
7070 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7071 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7073 tmode = TYPE_MODE (TREE_TYPE (arg0));
7074 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7075 gcc_assert (VECTOR_MODE_P (tmode));
7077 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
7078 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
7079 elt = get_element_number (TREE_TYPE (arg0), arg2);
7081 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
7082 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
7084 op0 = force_reg (tmode, op0);
7085 op1 = force_reg (mode1, op1);
7087 rs6000_expand_vector_set (op0, op1, elt);
7089 return op0;
7092 /* Expand vec_ext builtin. */
7093 static rtx
7094 altivec_expand_vec_ext_builtin (tree arglist, rtx target)
7096 enum machine_mode tmode, mode0;
7097 tree arg0, arg1;
7098 int elt;
7099 rtx op0;
7101 arg0 = TREE_VALUE (arglist);
7102 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7104 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7105 elt = get_element_number (TREE_TYPE (arg0), arg1);
7107 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7108 mode0 = TYPE_MODE (TREE_TYPE (arg0));
7109 gcc_assert (VECTOR_MODE_P (mode0));
7111 op0 = force_reg (mode0, op0);
7113 if (optimize || !target || !register_operand (target, tmode))
7114 target = gen_reg_rtx (tmode);
7116 rs6000_expand_vector_extract (target, op0, elt);
7118 return target;
7121 /* Expand the builtin in EXP and store the result in TARGET. Store
7122 true in *EXPANDEDP if we found a builtin to expand. */
7123 static rtx
7124 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
7126 struct builtin_description *d;
7127 struct builtin_description_predicates *dp;
7128 size_t i;
7129 enum insn_code icode;
7130 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7131 tree arglist = TREE_OPERAND (exp, 1);
7132 tree arg0;
7133 rtx op0, pat;
7134 enum machine_mode tmode, mode0;
7135 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7137 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7138 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
7140 *expandedp = true;
7141 error ("unresolved overload for Altivec builtin %qF", fndecl);
7142 return const0_rtx;
7145 target = altivec_expand_ld_builtin (exp, target, expandedp);
7146 if (*expandedp)
7147 return target;
7149 target = altivec_expand_st_builtin (exp, target, expandedp);
7150 if (*expandedp)
7151 return target;
7153 target = altivec_expand_dst_builtin (exp, target, expandedp);
7154 if (*expandedp)
7155 return target;
7157 *expandedp = true;
7159 switch (fcode)
7161 case ALTIVEC_BUILTIN_STVX:
7162 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
7163 case ALTIVEC_BUILTIN_STVEBX:
7164 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
7165 case ALTIVEC_BUILTIN_STVEHX:
7166 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
7167 case ALTIVEC_BUILTIN_STVEWX:
7168 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
7169 case ALTIVEC_BUILTIN_STVXL:
7170 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
7172 case ALTIVEC_BUILTIN_MFVSCR:
7173 icode = CODE_FOR_altivec_mfvscr;
7174 tmode = insn_data[icode].operand[0].mode;
7176 if (target == 0
7177 || GET_MODE (target) != tmode
7178 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7179 target = gen_reg_rtx (tmode);
7181 pat = GEN_FCN (icode) (target);
7182 if (! pat)
7183 return 0;
7184 emit_insn (pat);
7185 return target;
7187 case ALTIVEC_BUILTIN_MTVSCR:
7188 icode = CODE_FOR_altivec_mtvscr;
7189 arg0 = TREE_VALUE (arglist);
7190 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7191 mode0 = insn_data[icode].operand[0].mode;
7193 /* If we got invalid arguments bail out before generating bad rtl. */
7194 if (arg0 == error_mark_node)
7195 return const0_rtx;
7197 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7198 op0 = copy_to_mode_reg (mode0, op0);
7200 pat = GEN_FCN (icode) (op0);
7201 if (pat)
7202 emit_insn (pat);
7203 return NULL_RTX;
7205 case ALTIVEC_BUILTIN_DSSALL:
7206 emit_insn (gen_altivec_dssall ());
7207 return NULL_RTX;
7209 case ALTIVEC_BUILTIN_DSS:
7210 icode = CODE_FOR_altivec_dss;
7211 arg0 = TREE_VALUE (arglist);
7212 STRIP_NOPS (arg0);
7213 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7214 mode0 = insn_data[icode].operand[0].mode;
7216 /* If we got invalid arguments bail out before generating bad rtl. */
7217 if (arg0 == error_mark_node)
7218 return const0_rtx;
7220 if (TREE_CODE (arg0) != INTEGER_CST
7221 || TREE_INT_CST_LOW (arg0) & ~0x3)
7223 error ("argument to dss must be a 2-bit unsigned literal");
7224 return const0_rtx;
7227 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7228 op0 = copy_to_mode_reg (mode0, op0);
7230 emit_insn (gen_altivec_dss (op0));
7231 return NULL_RTX;
7233 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
7234 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
7235 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
7236 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
7237 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), arglist, target);
7239 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
7240 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
7241 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
7242 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
7243 return altivec_expand_vec_set_builtin (arglist);
7245 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
7246 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
7247 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
7248 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
7249 return altivec_expand_vec_ext_builtin (arglist, target);
7251 default:
7252 break;
7253 /* Fall through. */
7256 /* Expand abs* operations. */
7257 d = (struct builtin_description *) bdesc_abs;
7258 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
7259 if (d->code == fcode)
7260 return altivec_expand_abs_builtin (d->icode, arglist, target);
7262 /* Expand the AltiVec predicates. */
7263 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
7264 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
7265 if (dp->code == fcode)
7266 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
7267 arglist, target);
7269 /* LV* are funky. We initialized them differently. */
7270 switch (fcode)
7272 case ALTIVEC_BUILTIN_LVSL:
7273 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
7274 arglist, target);
7275 case ALTIVEC_BUILTIN_LVSR:
7276 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
7277 arglist, target);
7278 case ALTIVEC_BUILTIN_LVEBX:
7279 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
7280 arglist, target);
7281 case ALTIVEC_BUILTIN_LVEHX:
7282 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
7283 arglist, target);
7284 case ALTIVEC_BUILTIN_LVEWX:
7285 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
7286 arglist, target);
7287 case ALTIVEC_BUILTIN_LVXL:
7288 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
7289 arglist, target);
7290 case ALTIVEC_BUILTIN_LVX:
7291 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
7292 arglist, target);
7293 default:
7294 break;
7295 /* Fall through. */
7298 *expandedp = false;
7299 return NULL_RTX;
7302 /* Binops that need to be initialized manually, but can be expanded
7303 automagically by rs6000_expand_binop_builtin. */
7304 static struct builtin_description bdesc_2arg_spe[] =
7306 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
7307 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
7308 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
7309 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
7310 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
7311 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
7312 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
7313 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
7314 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
7315 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
7316 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
7317 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
7318 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
7319 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
7320 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
7321 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
7322 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
7323 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
7324 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
7325 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
7326 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
7327 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
7330 /* Expand the builtin in EXP and store the result in TARGET. Store
7331 true in *EXPANDEDP if we found a builtin to expand.
7333 This expands the SPE builtins that are not simple unary and binary
7334 operations. */
7335 static rtx
7336 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
7338 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7339 tree arglist = TREE_OPERAND (exp, 1);
7340 tree arg1, arg0;
7341 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7342 enum insn_code icode;
7343 enum machine_mode tmode, mode0;
7344 rtx pat, op0;
7345 struct builtin_description *d;
7346 size_t i;
7348 *expandedp = true;
7350 /* Syntax check for a 5-bit unsigned immediate. */
7351 switch (fcode)
7353 case SPE_BUILTIN_EVSTDD:
7354 case SPE_BUILTIN_EVSTDH:
7355 case SPE_BUILTIN_EVSTDW:
7356 case SPE_BUILTIN_EVSTWHE:
7357 case SPE_BUILTIN_EVSTWHO:
7358 case SPE_BUILTIN_EVSTWWE:
7359 case SPE_BUILTIN_EVSTWWO:
7360 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7361 if (TREE_CODE (arg1) != INTEGER_CST
7362 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7364 error ("argument 2 must be a 5-bit unsigned literal");
7365 return const0_rtx;
7367 break;
7368 default:
7369 break;
7372 /* The evsplat*i instructions are not quite generic. */
7373 switch (fcode)
7375 case SPE_BUILTIN_EVSPLATFI:
7376 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
7377 arglist, target);
7378 case SPE_BUILTIN_EVSPLATI:
7379 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
7380 arglist, target);
7381 default:
7382 break;
7385 d = (struct builtin_description *) bdesc_2arg_spe;
7386 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
7387 if (d->code == fcode)
7388 return rs6000_expand_binop_builtin (d->icode, arglist, target);
7390 d = (struct builtin_description *) bdesc_spe_predicates;
7391 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
7392 if (d->code == fcode)
7393 return spe_expand_predicate_builtin (d->icode, arglist, target);
7395 d = (struct builtin_description *) bdesc_spe_evsel;
7396 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
7397 if (d->code == fcode)
7398 return spe_expand_evsel_builtin (d->icode, arglist, target);
7400 switch (fcode)
7402 case SPE_BUILTIN_EVSTDDX:
7403 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
7404 case SPE_BUILTIN_EVSTDHX:
7405 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
7406 case SPE_BUILTIN_EVSTDWX:
7407 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
7408 case SPE_BUILTIN_EVSTWHEX:
7409 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
7410 case SPE_BUILTIN_EVSTWHOX:
7411 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
7412 case SPE_BUILTIN_EVSTWWEX:
7413 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
7414 case SPE_BUILTIN_EVSTWWOX:
7415 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
7416 case SPE_BUILTIN_EVSTDD:
7417 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
7418 case SPE_BUILTIN_EVSTDH:
7419 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
7420 case SPE_BUILTIN_EVSTDW:
7421 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
7422 case SPE_BUILTIN_EVSTWHE:
7423 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
7424 case SPE_BUILTIN_EVSTWHO:
7425 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
7426 case SPE_BUILTIN_EVSTWWE:
7427 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
7428 case SPE_BUILTIN_EVSTWWO:
7429 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
7430 case SPE_BUILTIN_MFSPEFSCR:
7431 icode = CODE_FOR_spe_mfspefscr;
7432 tmode = insn_data[icode].operand[0].mode;
7434 if (target == 0
7435 || GET_MODE (target) != tmode
7436 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7437 target = gen_reg_rtx (tmode);
7439 pat = GEN_FCN (icode) (target);
7440 if (! pat)
7441 return 0;
7442 emit_insn (pat);
7443 return target;
7444 case SPE_BUILTIN_MTSPEFSCR:
7445 icode = CODE_FOR_spe_mtspefscr;
7446 arg0 = TREE_VALUE (arglist);
7447 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7448 mode0 = insn_data[icode].operand[0].mode;
7450 if (arg0 == error_mark_node)
7451 return const0_rtx;
7453 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7454 op0 = copy_to_mode_reg (mode0, op0);
7456 pat = GEN_FCN (icode) (op0);
7457 if (pat)
7458 emit_insn (pat);
7459 return NULL_RTX;
7460 default:
7461 break;
7464 *expandedp = false;
7465 return NULL_RTX;
7468 static rtx
7469 spe_expand_predicate_builtin (enum insn_code icode, tree arglist, rtx target)
7471 rtx pat, scratch, tmp;
7472 tree form = TREE_VALUE (arglist);
7473 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
7474 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7475 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7476 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
7477 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7478 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7479 int form_int;
7480 enum rtx_code code;
7482 if (TREE_CODE (form) != INTEGER_CST)
7484 error ("argument 1 of __builtin_spe_predicate must be a constant");
7485 return const0_rtx;
7487 else
7488 form_int = TREE_INT_CST_LOW (form);
7490 gcc_assert (mode0 == mode1);
7492 if (arg0 == error_mark_node || arg1 == error_mark_node)
7493 return const0_rtx;
7495 if (target == 0
7496 || GET_MODE (target) != SImode
7497 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
7498 target = gen_reg_rtx (SImode);
7500 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7501 op0 = copy_to_mode_reg (mode0, op0);
7502 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7503 op1 = copy_to_mode_reg (mode1, op1);
7505 scratch = gen_reg_rtx (CCmode);
7507 pat = GEN_FCN (icode) (scratch, op0, op1);
7508 if (! pat)
7509 return const0_rtx;
7510 emit_insn (pat);
7512 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
7513 _lower_. We use one compare, but look in different bits of the
7514 CR for each variant.
7516 There are 2 elements in each SPE simd type (upper/lower). The CR
7517 bits are set as follows:
7519 BIT0 | BIT 1 | BIT 2 | BIT 3
7520 U | L | (U | L) | (U & L)
7522 So, for an "all" relationship, BIT 3 would be set.
7523 For an "any" relationship, BIT 2 would be set. Etc.
7525 Following traditional nomenclature, these bits map to:
7527 BIT0 | BIT 1 | BIT 2 | BIT 3
7528 LT | GT | EQ | OV
7530 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
7533 switch (form_int)
7535 /* All variant. OV bit. */
7536 case 0:
7537 /* We need to get to the OV bit, which is the ORDERED bit. We
7538 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
7539 that's ugly and will make validate_condition_mode die.
7540 So let's just use another pattern. */
7541 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
7542 return target;
7543 /* Any variant. EQ bit. */
7544 case 1:
7545 code = EQ;
7546 break;
7547 /* Upper variant. LT bit. */
7548 case 2:
7549 code = LT;
7550 break;
7551 /* Lower variant. GT bit. */
7552 case 3:
7553 code = GT;
7554 break;
7555 default:
7556 error ("argument 1 of __builtin_spe_predicate is out of range");
7557 return const0_rtx;
7560 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
7561 emit_move_insn (target, tmp);
7563 return target;
7566 /* The evsel builtins look like this:
7568 e = __builtin_spe_evsel_OP (a, b, c, d);
7570 and work like this:
7572 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
7573 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
7576 static rtx
7577 spe_expand_evsel_builtin (enum insn_code icode, tree arglist, rtx target)
7579 rtx pat, scratch;
7580 tree arg0 = TREE_VALUE (arglist);
7581 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7582 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7583 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
7584 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
7585 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
7586 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
7587 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
7588 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7589 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7591 gcc_assert (mode0 == mode1);
7593 if (arg0 == error_mark_node || arg1 == error_mark_node
7594 || arg2 == error_mark_node || arg3 == error_mark_node)
7595 return const0_rtx;
7597 if (target == 0
7598 || GET_MODE (target) != mode0
7599 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
7600 target = gen_reg_rtx (mode0);
7602 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7603 op0 = copy_to_mode_reg (mode0, op0);
7604 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7605 op1 = copy_to_mode_reg (mode0, op1);
7606 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7607 op2 = copy_to_mode_reg (mode0, op2);
7608 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
7609 op3 = copy_to_mode_reg (mode0, op3);
7611 /* Generate the compare. */
7612 scratch = gen_reg_rtx (CCmode);
7613 pat = GEN_FCN (icode) (scratch, op0, op1);
7614 if (! pat)
7615 return const0_rtx;
7616 emit_insn (pat);
7618 if (mode0 == V2SImode)
7619 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
7620 else
7621 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
7623 return target;
7626 /* Expand an expression EXP that calls a built-in function,
7627 with result going to TARGET if that's convenient
7628 (and in mode MODE if that's convenient).
7629 SUBTARGET may be used as the target for computing one of EXP's operands.
7630 IGNORE is nonzero if the value is to be ignored. */
7632 static rtx
7633 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
7634 enum machine_mode mode ATTRIBUTE_UNUSED,
7635 int ignore ATTRIBUTE_UNUSED)
7637 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7638 tree arglist = TREE_OPERAND (exp, 1);
7639 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7640 struct builtin_description *d;
7641 size_t i;
7642 rtx ret;
7643 bool success;
7645 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
7646 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
7648 int icode = (int) CODE_FOR_altivec_lvsr;
7649 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7650 enum machine_mode mode = insn_data[icode].operand[1].mode;
7651 tree arg;
7652 rtx op, addr, pat;
7654 gcc_assert (TARGET_ALTIVEC);
7656 arg = TREE_VALUE (arglist);
7657 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
7658 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
7659 addr = memory_address (mode, op);
7660 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
7661 op = addr;
7662 else
7664 /* For the load case need to negate the address. */
7665 op = gen_reg_rtx (GET_MODE (addr));
7666 emit_insn (gen_rtx_SET (VOIDmode, op,
7667 gen_rtx_NEG (GET_MODE (addr), addr)));
7669 op = gen_rtx_MEM (mode, op);
7671 if (target == 0
7672 || GET_MODE (target) != tmode
7673 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7674 target = gen_reg_rtx (tmode);
7676 /*pat = gen_altivec_lvsr (target, op);*/
7677 pat = GEN_FCN (icode) (target, op);
7678 if (!pat)
7679 return 0;
7680 emit_insn (pat);
7682 return target;
7685 if (TARGET_ALTIVEC)
7687 ret = altivec_expand_builtin (exp, target, &success);
7689 if (success)
7690 return ret;
7692 if (TARGET_SPE)
7694 ret = spe_expand_builtin (exp, target, &success);
7696 if (success)
7697 return ret;
7700 gcc_assert (TARGET_ALTIVEC || TARGET_SPE);
7702 /* Handle simple unary operations. */
7703 d = (struct builtin_description *) bdesc_1arg;
7704 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
7705 if (d->code == fcode)
7706 return rs6000_expand_unop_builtin (d->icode, arglist, target);
7708 /* Handle simple binary operations. */
7709 d = (struct builtin_description *) bdesc_2arg;
7710 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
7711 if (d->code == fcode)
7712 return rs6000_expand_binop_builtin (d->icode, arglist, target);
7714 /* Handle simple ternary operations. */
7715 d = (struct builtin_description *) bdesc_3arg;
7716 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
7717 if (d->code == fcode)
7718 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
7720 gcc_unreachable ();
7723 static tree
7724 build_opaque_vector_type (tree node, int nunits)
7726 node = copy_node (node);
7727 TYPE_MAIN_VARIANT (node) = node;
7728 return build_vector_type (node, nunits);
7731 static void
7732 rs6000_init_builtins (void)
7734 V2SI_type_node = build_vector_type (intSI_type_node, 2);
7735 V2SF_type_node = build_vector_type (float_type_node, 2);
7736 V4HI_type_node = build_vector_type (intHI_type_node, 4);
7737 V4SI_type_node = build_vector_type (intSI_type_node, 4);
7738 V4SF_type_node = build_vector_type (float_type_node, 4);
7739 V8HI_type_node = build_vector_type (intHI_type_node, 8);
7740 V16QI_type_node = build_vector_type (intQI_type_node, 16);
7742 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
7743 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
7744 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
7746 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
7747 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
7748 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
7749 opaque_V4SI_type_node = copy_node (V4SI_type_node);
7751 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
7752 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
7753 'vector unsigned short'. */
7755 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
7756 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
7757 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
7758 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
7760 long_integer_type_internal_node = long_integer_type_node;
7761 long_unsigned_type_internal_node = long_unsigned_type_node;
7762 intQI_type_internal_node = intQI_type_node;
7763 uintQI_type_internal_node = unsigned_intQI_type_node;
7764 intHI_type_internal_node = intHI_type_node;
7765 uintHI_type_internal_node = unsigned_intHI_type_node;
7766 intSI_type_internal_node = intSI_type_node;
7767 uintSI_type_internal_node = unsigned_intSI_type_node;
7768 float_type_internal_node = float_type_node;
7769 void_type_internal_node = void_type_node;
7771 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7772 get_identifier ("__bool char"),
7773 bool_char_type_node));
7774 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7775 get_identifier ("__bool short"),
7776 bool_short_type_node));
7777 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7778 get_identifier ("__bool int"),
7779 bool_int_type_node));
7780 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7781 get_identifier ("__pixel"),
7782 pixel_type_node));
7784 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
7785 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
7786 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
7787 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
7789 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7790 get_identifier ("__vector unsigned char"),
7791 unsigned_V16QI_type_node));
7792 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7793 get_identifier ("__vector signed char"),
7794 V16QI_type_node));
7795 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7796 get_identifier ("__vector __bool char"),
7797 bool_V16QI_type_node));
7799 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7800 get_identifier ("__vector unsigned short"),
7801 unsigned_V8HI_type_node));
7802 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7803 get_identifier ("__vector signed short"),
7804 V8HI_type_node));
7805 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7806 get_identifier ("__vector __bool short"),
7807 bool_V8HI_type_node));
7809 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7810 get_identifier ("__vector unsigned int"),
7811 unsigned_V4SI_type_node));
7812 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7813 get_identifier ("__vector signed int"),
7814 V4SI_type_node));
7815 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7816 get_identifier ("__vector __bool int"),
7817 bool_V4SI_type_node));
7819 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7820 get_identifier ("__vector float"),
7821 V4SF_type_node));
7822 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7823 get_identifier ("__vector __pixel"),
7824 pixel_V8HI_type_node));
7826 if (TARGET_SPE)
7827 spe_init_builtins ();
7828 if (TARGET_ALTIVEC)
7829 altivec_init_builtins ();
7830 if (TARGET_ALTIVEC || TARGET_SPE)
7831 rs6000_common_init_builtins ();
7834 /* Search through a set of builtins and enable the mask bits.
7835 DESC is an array of builtins.
7836 SIZE is the total number of builtins.
7837 START is the builtin enum at which to start.
7838 END is the builtin enum at which to end. */
7839 static void
7840 enable_mask_for_builtins (struct builtin_description *desc, int size,
7841 enum rs6000_builtins start,
7842 enum rs6000_builtins end)
7844 int i;
7846 for (i = 0; i < size; ++i)
7847 if (desc[i].code == start)
7848 break;
7850 if (i == size)
7851 return;
7853 for (; i < size; ++i)
7855 /* Flip all the bits on. */
7856 desc[i].mask = target_flags;
7857 if (desc[i].code == end)
7858 break;
7862 static void
7863 spe_init_builtins (void)
7865 tree endlink = void_list_node;
7866 tree puint_type_node = build_pointer_type (unsigned_type_node);
7867 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
7868 struct builtin_description *d;
7869 size_t i;
7871 tree v2si_ftype_4_v2si
7872 = build_function_type
7873 (opaque_V2SI_type_node,
7874 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7875 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7876 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7877 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7878 endlink)))));
7880 tree v2sf_ftype_4_v2sf
7881 = build_function_type
7882 (opaque_V2SF_type_node,
7883 tree_cons (NULL_TREE, opaque_V2SF_type_node,
7884 tree_cons (NULL_TREE, opaque_V2SF_type_node,
7885 tree_cons (NULL_TREE, opaque_V2SF_type_node,
7886 tree_cons (NULL_TREE, opaque_V2SF_type_node,
7887 endlink)))));
7889 tree int_ftype_int_v2si_v2si
7890 = build_function_type
7891 (integer_type_node,
7892 tree_cons (NULL_TREE, integer_type_node,
7893 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7894 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7895 endlink))));
7897 tree int_ftype_int_v2sf_v2sf
7898 = build_function_type
7899 (integer_type_node,
7900 tree_cons (NULL_TREE, integer_type_node,
7901 tree_cons (NULL_TREE, opaque_V2SF_type_node,
7902 tree_cons (NULL_TREE, opaque_V2SF_type_node,
7903 endlink))));
7905 tree void_ftype_v2si_puint_int
7906 = build_function_type (void_type_node,
7907 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7908 tree_cons (NULL_TREE, puint_type_node,
7909 tree_cons (NULL_TREE,
7910 integer_type_node,
7911 endlink))));
7913 tree void_ftype_v2si_puint_char
7914 = build_function_type (void_type_node,
7915 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7916 tree_cons (NULL_TREE, puint_type_node,
7917 tree_cons (NULL_TREE,
7918 char_type_node,
7919 endlink))));
7921 tree void_ftype_v2si_pv2si_int
7922 = build_function_type (void_type_node,
7923 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7924 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
7925 tree_cons (NULL_TREE,
7926 integer_type_node,
7927 endlink))));
7929 tree void_ftype_v2si_pv2si_char
7930 = build_function_type (void_type_node,
7931 tree_cons (NULL_TREE, opaque_V2SI_type_node,
7932 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
7933 tree_cons (NULL_TREE,
7934 char_type_node,
7935 endlink))));
7937 tree void_ftype_int
7938 = build_function_type (void_type_node,
7939 tree_cons (NULL_TREE, integer_type_node, endlink));
7941 tree int_ftype_void
7942 = build_function_type (integer_type_node, endlink);
7944 tree v2si_ftype_pv2si_int
7945 = build_function_type (opaque_V2SI_type_node,
7946 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
7947 tree_cons (NULL_TREE, integer_type_node,
7948 endlink)));
7950 tree v2si_ftype_puint_int
7951 = build_function_type (opaque_V2SI_type_node,
7952 tree_cons (NULL_TREE, puint_type_node,
7953 tree_cons (NULL_TREE, integer_type_node,
7954 endlink)));
7956 tree v2si_ftype_pushort_int
7957 = build_function_type (opaque_V2SI_type_node,
7958 tree_cons (NULL_TREE, pushort_type_node,
7959 tree_cons (NULL_TREE, integer_type_node,
7960 endlink)));
7962 tree v2si_ftype_signed_char
7963 = build_function_type (opaque_V2SI_type_node,
7964 tree_cons (NULL_TREE, signed_char_type_node,
7965 endlink));
7967 /* The initialization of the simple binary and unary builtins is
7968 done in rs6000_common_init_builtins, but we have to enable the
7969 mask bits here manually because we have run out of `target_flags'
7970 bits. We really need to redesign this mask business. */
7972 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
7973 ARRAY_SIZE (bdesc_2arg),
7974 SPE_BUILTIN_EVADDW,
7975 SPE_BUILTIN_EVXOR);
7976 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
7977 ARRAY_SIZE (bdesc_1arg),
7978 SPE_BUILTIN_EVABS,
7979 SPE_BUILTIN_EVSUBFUSIAAW);
7980 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
7981 ARRAY_SIZE (bdesc_spe_predicates),
7982 SPE_BUILTIN_EVCMPEQ,
7983 SPE_BUILTIN_EVFSTSTLT);
7984 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
7985 ARRAY_SIZE (bdesc_spe_evsel),
7986 SPE_BUILTIN_EVSEL_CMPGTS,
7987 SPE_BUILTIN_EVSEL_FSTSTEQ);
7989 (*lang_hooks.decls.pushdecl)
7990 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
7991 opaque_V2SI_type_node));
7993 /* Initialize irregular SPE builtins. */
7995 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
7996 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
7997 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
7998 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
7999 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
8000 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
8001 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
8002 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
8003 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
8004 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
8005 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
8006 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
8007 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
8008 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
8009 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
8010 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
8011 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
8012 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
8014 /* Loads. */
8015 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
8016 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
8017 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
8018 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
8019 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
8020 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
8021 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
8022 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
8023 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
8024 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
8025 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
8026 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
8027 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
8028 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
8029 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
8030 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
8031 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
8032 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
8033 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
8034 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
8035 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
8036 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
8038 /* Predicates. */
8039 d = (struct builtin_description *) bdesc_spe_predicates;
8040 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
8042 tree type;
8044 switch (insn_data[d->icode].operand[1].mode)
8046 case V2SImode:
8047 type = int_ftype_int_v2si_v2si;
8048 break;
8049 case V2SFmode:
8050 type = int_ftype_int_v2sf_v2sf;
8051 break;
8052 default:
8053 gcc_unreachable ();
8056 def_builtin (d->mask, d->name, type, d->code);
8059 /* Evsel predicates. */
8060 d = (struct builtin_description *) bdesc_spe_evsel;
8061 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
8063 tree type;
8065 switch (insn_data[d->icode].operand[1].mode)
8067 case V2SImode:
8068 type = v2si_ftype_4_v2si;
8069 break;
8070 case V2SFmode:
8071 type = v2sf_ftype_4_v2sf;
8072 break;
8073 default:
8074 gcc_unreachable ();
8077 def_builtin (d->mask, d->name, type, d->code);
8081 static void
8082 altivec_init_builtins (void)
8084 struct builtin_description *d;
8085 struct builtin_description_predicates *dp;
8086 size_t i;
8087 tree ftype;
8089 tree pfloat_type_node = build_pointer_type (float_type_node);
8090 tree pint_type_node = build_pointer_type (integer_type_node);
8091 tree pshort_type_node = build_pointer_type (short_integer_type_node);
8092 tree pchar_type_node = build_pointer_type (char_type_node);
8094 tree pvoid_type_node = build_pointer_type (void_type_node);
8096 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
8097 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
8098 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
8099 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
8101 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
8103 tree int_ftype_opaque
8104 = build_function_type_list (integer_type_node,
8105 opaque_V4SI_type_node, NULL_TREE);
8107 tree opaque_ftype_opaque_int
8108 = build_function_type_list (opaque_V4SI_type_node,
8109 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
8110 tree opaque_ftype_opaque_opaque_int
8111 = build_function_type_list (opaque_V4SI_type_node,
8112 opaque_V4SI_type_node, opaque_V4SI_type_node,
8113 integer_type_node, NULL_TREE);
8114 tree int_ftype_int_opaque_opaque
8115 = build_function_type_list (integer_type_node,
8116 integer_type_node, opaque_V4SI_type_node,
8117 opaque_V4SI_type_node, NULL_TREE);
8118 tree int_ftype_int_v4si_v4si
8119 = build_function_type_list (integer_type_node,
8120 integer_type_node, V4SI_type_node,
8121 V4SI_type_node, NULL_TREE);
8122 tree v4sf_ftype_pcfloat
8123 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
8124 tree void_ftype_pfloat_v4sf
8125 = build_function_type_list (void_type_node,
8126 pfloat_type_node, V4SF_type_node, NULL_TREE);
8127 tree v4si_ftype_pcint
8128 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
8129 tree void_ftype_pint_v4si
8130 = build_function_type_list (void_type_node,
8131 pint_type_node, V4SI_type_node, NULL_TREE);
8132 tree v8hi_ftype_pcshort
8133 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
8134 tree void_ftype_pshort_v8hi
8135 = build_function_type_list (void_type_node,
8136 pshort_type_node, V8HI_type_node, NULL_TREE);
8137 tree v16qi_ftype_pcchar
8138 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
8139 tree void_ftype_pchar_v16qi
8140 = build_function_type_list (void_type_node,
8141 pchar_type_node, V16QI_type_node, NULL_TREE);
8142 tree void_ftype_v4si
8143 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
8144 tree v8hi_ftype_void
8145 = build_function_type (V8HI_type_node, void_list_node);
8146 tree void_ftype_void
8147 = build_function_type (void_type_node, void_list_node);
8148 tree void_ftype_int
8149 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
8151 tree opaque_ftype_long_pcvoid
8152 = build_function_type_list (opaque_V4SI_type_node,
8153 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8154 tree v16qi_ftype_long_pcvoid
8155 = build_function_type_list (V16QI_type_node,
8156 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8157 tree v8hi_ftype_long_pcvoid
8158 = build_function_type_list (V8HI_type_node,
8159 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8160 tree v4si_ftype_long_pcvoid
8161 = build_function_type_list (V4SI_type_node,
8162 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8164 tree void_ftype_opaque_long_pvoid
8165 = build_function_type_list (void_type_node,
8166 opaque_V4SI_type_node, long_integer_type_node,
8167 pvoid_type_node, NULL_TREE);
8168 tree void_ftype_v4si_long_pvoid
8169 = build_function_type_list (void_type_node,
8170 V4SI_type_node, long_integer_type_node,
8171 pvoid_type_node, NULL_TREE);
8172 tree void_ftype_v16qi_long_pvoid
8173 = build_function_type_list (void_type_node,
8174 V16QI_type_node, long_integer_type_node,
8175 pvoid_type_node, NULL_TREE);
8176 tree void_ftype_v8hi_long_pvoid
8177 = build_function_type_list (void_type_node,
8178 V8HI_type_node, long_integer_type_node,
8179 pvoid_type_node, NULL_TREE);
8180 tree int_ftype_int_v8hi_v8hi
8181 = build_function_type_list (integer_type_node,
8182 integer_type_node, V8HI_type_node,
8183 V8HI_type_node, NULL_TREE);
8184 tree int_ftype_int_v16qi_v16qi
8185 = build_function_type_list (integer_type_node,
8186 integer_type_node, V16QI_type_node,
8187 V16QI_type_node, NULL_TREE);
8188 tree int_ftype_int_v4sf_v4sf
8189 = build_function_type_list (integer_type_node,
8190 integer_type_node, V4SF_type_node,
8191 V4SF_type_node, NULL_TREE);
8192 tree v4si_ftype_v4si
8193 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
8194 tree v8hi_ftype_v8hi
8195 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
8196 tree v16qi_ftype_v16qi
8197 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
8198 tree v4sf_ftype_v4sf
8199 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8200 tree void_ftype_pcvoid_int_int
8201 = build_function_type_list (void_type_node,
8202 pcvoid_type_node, integer_type_node,
8203 integer_type_node, NULL_TREE);
8205 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
8206 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
8207 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
8208 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
8209 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
8210 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
8211 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
8212 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
8213 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
8214 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
8215 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
8216 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
8217 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
8218 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
8219 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
8220 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
8221 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
8222 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
8223 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
8224 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
8225 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
8226 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
8227 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
8228 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
8229 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
8230 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
8231 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
8232 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
8233 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
8234 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
8235 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
8236 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
8237 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
8238 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
8239 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
8240 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
8241 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
8242 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
8243 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
8244 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
8245 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
8246 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
8247 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
8248 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
8249 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
8250 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
8252 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
8254 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
8255 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
8256 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
8257 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
8258 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
8259 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
8260 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
8261 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
8262 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
8263 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
8265 /* Add the DST variants. */
8266 d = (struct builtin_description *) bdesc_dst;
8267 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8268 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
8270 /* Initialize the predicates. */
8271 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
8272 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
8274 enum machine_mode mode1;
8275 tree type;
8276 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8277 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8279 if (is_overloaded)
8280 mode1 = VOIDmode;
8281 else
8282 mode1 = insn_data[dp->icode].operand[1].mode;
8284 switch (mode1)
8286 case VOIDmode:
8287 type = int_ftype_int_opaque_opaque;
8288 break;
8289 case V4SImode:
8290 type = int_ftype_int_v4si_v4si;
8291 break;
8292 case V8HImode:
8293 type = int_ftype_int_v8hi_v8hi;
8294 break;
8295 case V16QImode:
8296 type = int_ftype_int_v16qi_v16qi;
8297 break;
8298 case V4SFmode:
8299 type = int_ftype_int_v4sf_v4sf;
8300 break;
8301 default:
8302 gcc_unreachable ();
8305 def_builtin (dp->mask, dp->name, type, dp->code);
8308 /* Initialize the abs* operators. */
8309 d = (struct builtin_description *) bdesc_abs;
8310 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
8312 enum machine_mode mode0;
8313 tree type;
8315 mode0 = insn_data[d->icode].operand[0].mode;
8317 switch (mode0)
8319 case V4SImode:
8320 type = v4si_ftype_v4si;
8321 break;
8322 case V8HImode:
8323 type = v8hi_ftype_v8hi;
8324 break;
8325 case V16QImode:
8326 type = v16qi_ftype_v16qi;
8327 break;
8328 case V4SFmode:
8329 type = v4sf_ftype_v4sf;
8330 break;
8331 default:
8332 gcc_unreachable ();
8335 def_builtin (d->mask, d->name, type, d->code);
8338 if (TARGET_ALTIVEC)
8340 tree decl;
8342 /* Initialize target builtin that implements
8343 targetm.vectorize.builtin_mask_for_load. */
8345 decl = lang_hooks.builtin_function ("__builtin_altivec_mask_for_load",
8346 v16qi_ftype_long_pcvoid,
8347 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
8348 BUILT_IN_MD, NULL,
8349 tree_cons (get_identifier ("const"),
8350 NULL_TREE, NULL_TREE));
8351 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8352 altivec_builtin_mask_for_load = decl;
8355 /* Access to the vec_init patterns. */
8356 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
8357 integer_type_node, integer_type_node,
8358 integer_type_node, NULL_TREE);
8359 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
8360 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
8362 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
8363 short_integer_type_node,
8364 short_integer_type_node,
8365 short_integer_type_node,
8366 short_integer_type_node,
8367 short_integer_type_node,
8368 short_integer_type_node,
8369 short_integer_type_node, NULL_TREE);
8370 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
8371 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
8373 ftype = build_function_type_list (V16QI_type_node, char_type_node,
8374 char_type_node, char_type_node,
8375 char_type_node, char_type_node,
8376 char_type_node, char_type_node,
8377 char_type_node, char_type_node,
8378 char_type_node, char_type_node,
8379 char_type_node, char_type_node,
8380 char_type_node, char_type_node,
8381 char_type_node, NULL_TREE);
8382 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
8383 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
8385 ftype = build_function_type_list (V4SF_type_node, float_type_node,
8386 float_type_node, float_type_node,
8387 float_type_node, NULL_TREE);
8388 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
8389 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
8391 /* Access to the vec_set patterns. */
8392 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
8393 intSI_type_node,
8394 integer_type_node, NULL_TREE);
8395 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
8396 ALTIVEC_BUILTIN_VEC_SET_V4SI);
8398 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
8399 intHI_type_node,
8400 integer_type_node, NULL_TREE);
8401 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
8402 ALTIVEC_BUILTIN_VEC_SET_V8HI);
8404 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
8405 intQI_type_node,
8406 integer_type_node, NULL_TREE);
8407 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
8408 ALTIVEC_BUILTIN_VEC_SET_V16QI);
8410 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
8411 float_type_node,
8412 integer_type_node, NULL_TREE);
8413 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
8414 ALTIVEC_BUILTIN_VEC_SET_V4SF);
8416 /* Access to the vec_extract patterns. */
8417 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
8418 integer_type_node, NULL_TREE);
8419 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
8420 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
8422 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
8423 integer_type_node, NULL_TREE);
8424 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
8425 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
8427 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
8428 integer_type_node, NULL_TREE);
8429 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
8430 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
8432 ftype = build_function_type_list (float_type_node, V4SF_type_node,
8433 integer_type_node, NULL_TREE);
8434 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
8435 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
8438 static void
8439 rs6000_common_init_builtins (void)
8441 struct builtin_description *d;
8442 size_t i;
8444 tree v4sf_ftype_v4sf_v4sf_v16qi
8445 = build_function_type_list (V4SF_type_node,
8446 V4SF_type_node, V4SF_type_node,
8447 V16QI_type_node, NULL_TREE);
8448 tree v4si_ftype_v4si_v4si_v16qi
8449 = build_function_type_list (V4SI_type_node,
8450 V4SI_type_node, V4SI_type_node,
8451 V16QI_type_node, NULL_TREE);
8452 tree v8hi_ftype_v8hi_v8hi_v16qi
8453 = build_function_type_list (V8HI_type_node,
8454 V8HI_type_node, V8HI_type_node,
8455 V16QI_type_node, NULL_TREE);
8456 tree v16qi_ftype_v16qi_v16qi_v16qi
8457 = build_function_type_list (V16QI_type_node,
8458 V16QI_type_node, V16QI_type_node,
8459 V16QI_type_node, NULL_TREE);
8460 tree v4si_ftype_int
8461 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
8462 tree v8hi_ftype_int
8463 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
8464 tree v16qi_ftype_int
8465 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
8466 tree v8hi_ftype_v16qi
8467 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
8468 tree v4sf_ftype_v4sf
8469 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8471 tree v2si_ftype_v2si_v2si
8472 = build_function_type_list (opaque_V2SI_type_node,
8473 opaque_V2SI_type_node,
8474 opaque_V2SI_type_node, NULL_TREE);
8476 tree v2sf_ftype_v2sf_v2sf
8477 = build_function_type_list (opaque_V2SF_type_node,
8478 opaque_V2SF_type_node,
8479 opaque_V2SF_type_node, NULL_TREE);
8481 tree v2si_ftype_int_int
8482 = build_function_type_list (opaque_V2SI_type_node,
8483 integer_type_node, integer_type_node,
8484 NULL_TREE);
8486 tree opaque_ftype_opaque
8487 = build_function_type_list (opaque_V4SI_type_node,
8488 opaque_V4SI_type_node, NULL_TREE);
8490 tree v2si_ftype_v2si
8491 = build_function_type_list (opaque_V2SI_type_node,
8492 opaque_V2SI_type_node, NULL_TREE);
8494 tree v2sf_ftype_v2sf
8495 = build_function_type_list (opaque_V2SF_type_node,
8496 opaque_V2SF_type_node, NULL_TREE);
8498 tree v2sf_ftype_v2si
8499 = build_function_type_list (opaque_V2SF_type_node,
8500 opaque_V2SI_type_node, NULL_TREE);
8502 tree v2si_ftype_v2sf
8503 = build_function_type_list (opaque_V2SI_type_node,
8504 opaque_V2SF_type_node, NULL_TREE);
8506 tree v2si_ftype_v2si_char
8507 = build_function_type_list (opaque_V2SI_type_node,
8508 opaque_V2SI_type_node,
8509 char_type_node, NULL_TREE);
8511 tree v2si_ftype_int_char
8512 = build_function_type_list (opaque_V2SI_type_node,
8513 integer_type_node, char_type_node, NULL_TREE);
8515 tree v2si_ftype_char
8516 = build_function_type_list (opaque_V2SI_type_node,
8517 char_type_node, NULL_TREE);
8519 tree int_ftype_int_int
8520 = build_function_type_list (integer_type_node,
8521 integer_type_node, integer_type_node,
8522 NULL_TREE);
8524 tree opaque_ftype_opaque_opaque
8525 = build_function_type_list (opaque_V4SI_type_node,
8526 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
8527 tree v4si_ftype_v4si_v4si
8528 = build_function_type_list (V4SI_type_node,
8529 V4SI_type_node, V4SI_type_node, NULL_TREE);
8530 tree v4sf_ftype_v4si_int
8531 = build_function_type_list (V4SF_type_node,
8532 V4SI_type_node, integer_type_node, NULL_TREE);
8533 tree v4si_ftype_v4sf_int
8534 = build_function_type_list (V4SI_type_node,
8535 V4SF_type_node, integer_type_node, NULL_TREE);
8536 tree v4si_ftype_v4si_int
8537 = build_function_type_list (V4SI_type_node,
8538 V4SI_type_node, integer_type_node, NULL_TREE);
8539 tree v8hi_ftype_v8hi_int
8540 = build_function_type_list (V8HI_type_node,
8541 V8HI_type_node, integer_type_node, NULL_TREE);
8542 tree v16qi_ftype_v16qi_int
8543 = build_function_type_list (V16QI_type_node,
8544 V16QI_type_node, integer_type_node, NULL_TREE);
8545 tree v16qi_ftype_v16qi_v16qi_int
8546 = build_function_type_list (V16QI_type_node,
8547 V16QI_type_node, V16QI_type_node,
8548 integer_type_node, NULL_TREE);
8549 tree v8hi_ftype_v8hi_v8hi_int
8550 = build_function_type_list (V8HI_type_node,
8551 V8HI_type_node, V8HI_type_node,
8552 integer_type_node, NULL_TREE);
8553 tree v4si_ftype_v4si_v4si_int
8554 = build_function_type_list (V4SI_type_node,
8555 V4SI_type_node, V4SI_type_node,
8556 integer_type_node, NULL_TREE);
8557 tree v4sf_ftype_v4sf_v4sf_int
8558 = build_function_type_list (V4SF_type_node,
8559 V4SF_type_node, V4SF_type_node,
8560 integer_type_node, NULL_TREE);
8561 tree v4sf_ftype_v4sf_v4sf
8562 = build_function_type_list (V4SF_type_node,
8563 V4SF_type_node, V4SF_type_node, NULL_TREE);
8564 tree opaque_ftype_opaque_opaque_opaque
8565 = build_function_type_list (opaque_V4SI_type_node,
8566 opaque_V4SI_type_node, opaque_V4SI_type_node,
8567 opaque_V4SI_type_node, NULL_TREE);
8568 tree v4sf_ftype_v4sf_v4sf_v4si
8569 = build_function_type_list (V4SF_type_node,
8570 V4SF_type_node, V4SF_type_node,
8571 V4SI_type_node, NULL_TREE);
8572 tree v4sf_ftype_v4sf_v4sf_v4sf
8573 = build_function_type_list (V4SF_type_node,
8574 V4SF_type_node, V4SF_type_node,
8575 V4SF_type_node, NULL_TREE);
8576 tree v4si_ftype_v4si_v4si_v4si
8577 = build_function_type_list (V4SI_type_node,
8578 V4SI_type_node, V4SI_type_node,
8579 V4SI_type_node, NULL_TREE);
8580 tree v8hi_ftype_v8hi_v8hi
8581 = build_function_type_list (V8HI_type_node,
8582 V8HI_type_node, V8HI_type_node, NULL_TREE);
8583 tree v8hi_ftype_v8hi_v8hi_v8hi
8584 = build_function_type_list (V8HI_type_node,
8585 V8HI_type_node, V8HI_type_node,
8586 V8HI_type_node, NULL_TREE);
8587 tree v4si_ftype_v8hi_v8hi_v4si
8588 = build_function_type_list (V4SI_type_node,
8589 V8HI_type_node, V8HI_type_node,
8590 V4SI_type_node, NULL_TREE);
8591 tree v4si_ftype_v16qi_v16qi_v4si
8592 = build_function_type_list (V4SI_type_node,
8593 V16QI_type_node, V16QI_type_node,
8594 V4SI_type_node, NULL_TREE);
8595 tree v16qi_ftype_v16qi_v16qi
8596 = build_function_type_list (V16QI_type_node,
8597 V16QI_type_node, V16QI_type_node, NULL_TREE);
8598 tree v4si_ftype_v4sf_v4sf
8599 = build_function_type_list (V4SI_type_node,
8600 V4SF_type_node, V4SF_type_node, NULL_TREE);
8601 tree v8hi_ftype_v16qi_v16qi
8602 = build_function_type_list (V8HI_type_node,
8603 V16QI_type_node, V16QI_type_node, NULL_TREE);
8604 tree v4si_ftype_v8hi_v8hi
8605 = build_function_type_list (V4SI_type_node,
8606 V8HI_type_node, V8HI_type_node, NULL_TREE);
8607 tree v8hi_ftype_v4si_v4si
8608 = build_function_type_list (V8HI_type_node,
8609 V4SI_type_node, V4SI_type_node, NULL_TREE);
8610 tree v16qi_ftype_v8hi_v8hi
8611 = build_function_type_list (V16QI_type_node,
8612 V8HI_type_node, V8HI_type_node, NULL_TREE);
8613 tree v4si_ftype_v16qi_v4si
8614 = build_function_type_list (V4SI_type_node,
8615 V16QI_type_node, V4SI_type_node, NULL_TREE);
8616 tree v4si_ftype_v16qi_v16qi
8617 = build_function_type_list (V4SI_type_node,
8618 V16QI_type_node, V16QI_type_node, NULL_TREE);
8619 tree v4si_ftype_v8hi_v4si
8620 = build_function_type_list (V4SI_type_node,
8621 V8HI_type_node, V4SI_type_node, NULL_TREE);
8622 tree v4si_ftype_v8hi
8623 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
8624 tree int_ftype_v4si_v4si
8625 = build_function_type_list (integer_type_node,
8626 V4SI_type_node, V4SI_type_node, NULL_TREE);
8627 tree int_ftype_v4sf_v4sf
8628 = build_function_type_list (integer_type_node,
8629 V4SF_type_node, V4SF_type_node, NULL_TREE);
8630 tree int_ftype_v16qi_v16qi
8631 = build_function_type_list (integer_type_node,
8632 V16QI_type_node, V16QI_type_node, NULL_TREE);
8633 tree int_ftype_v8hi_v8hi
8634 = build_function_type_list (integer_type_node,
8635 V8HI_type_node, V8HI_type_node, NULL_TREE);
8637 /* Add the simple ternary operators. */
8638 d = (struct builtin_description *) bdesc_3arg;
8639 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
8641 enum machine_mode mode0, mode1, mode2, mode3;
8642 tree type;
8643 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8644 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8646 if (is_overloaded)
8648 mode0 = VOIDmode;
8649 mode1 = VOIDmode;
8650 mode2 = VOIDmode;
8651 mode3 = VOIDmode;
8653 else
8655 if (d->name == 0 || d->icode == CODE_FOR_nothing)
8656 continue;
8658 mode0 = insn_data[d->icode].operand[0].mode;
8659 mode1 = insn_data[d->icode].operand[1].mode;
8660 mode2 = insn_data[d->icode].operand[2].mode;
8661 mode3 = insn_data[d->icode].operand[3].mode;
8664 /* When all four are of the same mode. */
8665 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
8667 switch (mode0)
8669 case VOIDmode:
8670 type = opaque_ftype_opaque_opaque_opaque;
8671 break;
8672 case V4SImode:
8673 type = v4si_ftype_v4si_v4si_v4si;
8674 break;
8675 case V4SFmode:
8676 type = v4sf_ftype_v4sf_v4sf_v4sf;
8677 break;
8678 case V8HImode:
8679 type = v8hi_ftype_v8hi_v8hi_v8hi;
8680 break;
8681 case V16QImode:
8682 type = v16qi_ftype_v16qi_v16qi_v16qi;
8683 break;
8684 default:
8685 gcc_unreachable ();
8688 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
8690 switch (mode0)
8692 case V4SImode:
8693 type = v4si_ftype_v4si_v4si_v16qi;
8694 break;
8695 case V4SFmode:
8696 type = v4sf_ftype_v4sf_v4sf_v16qi;
8697 break;
8698 case V8HImode:
8699 type = v8hi_ftype_v8hi_v8hi_v16qi;
8700 break;
8701 case V16QImode:
8702 type = v16qi_ftype_v16qi_v16qi_v16qi;
8703 break;
8704 default:
8705 gcc_unreachable ();
8708 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
8709 && mode3 == V4SImode)
8710 type = v4si_ftype_v16qi_v16qi_v4si;
8711 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
8712 && mode3 == V4SImode)
8713 type = v4si_ftype_v8hi_v8hi_v4si;
8714 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
8715 && mode3 == V4SImode)
8716 type = v4sf_ftype_v4sf_v4sf_v4si;
8718 /* vchar, vchar, vchar, 4 bit literal. */
8719 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
8720 && mode3 == QImode)
8721 type = v16qi_ftype_v16qi_v16qi_int;
8723 /* vshort, vshort, vshort, 4 bit literal. */
8724 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
8725 && mode3 == QImode)
8726 type = v8hi_ftype_v8hi_v8hi_int;
8728 /* vint, vint, vint, 4 bit literal. */
8729 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
8730 && mode3 == QImode)
8731 type = v4si_ftype_v4si_v4si_int;
8733 /* vfloat, vfloat, vfloat, 4 bit literal. */
8734 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
8735 && mode3 == QImode)
8736 type = v4sf_ftype_v4sf_v4sf_int;
8738 else
8739 gcc_unreachable ();
8741 def_builtin (d->mask, d->name, type, d->code);
8744 /* Add the simple binary operators. */
8745 d = (struct builtin_description *) bdesc_2arg;
8746 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
8748 enum machine_mode mode0, mode1, mode2;
8749 tree type;
8750 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8751 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8753 if (is_overloaded)
8755 mode0 = VOIDmode;
8756 mode1 = VOIDmode;
8757 mode2 = VOIDmode;
8759 else
8761 if (d->name == 0 || d->icode == CODE_FOR_nothing)
8762 continue;
8764 mode0 = insn_data[d->icode].operand[0].mode;
8765 mode1 = insn_data[d->icode].operand[1].mode;
8766 mode2 = insn_data[d->icode].operand[2].mode;
8769 /* When all three operands are of the same mode. */
8770 if (mode0 == mode1 && mode1 == mode2)
8772 switch (mode0)
8774 case VOIDmode:
8775 type = opaque_ftype_opaque_opaque;
8776 break;
8777 case V4SFmode:
8778 type = v4sf_ftype_v4sf_v4sf;
8779 break;
8780 case V4SImode:
8781 type = v4si_ftype_v4si_v4si;
8782 break;
8783 case V16QImode:
8784 type = v16qi_ftype_v16qi_v16qi;
8785 break;
8786 case V8HImode:
8787 type = v8hi_ftype_v8hi_v8hi;
8788 break;
8789 case V2SImode:
8790 type = v2si_ftype_v2si_v2si;
8791 break;
8792 case V2SFmode:
8793 type = v2sf_ftype_v2sf_v2sf;
8794 break;
8795 case SImode:
8796 type = int_ftype_int_int;
8797 break;
8798 default:
8799 gcc_unreachable ();
8803 /* A few other combos we really don't want to do manually. */
8805 /* vint, vfloat, vfloat. */
8806 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
8807 type = v4si_ftype_v4sf_v4sf;
8809 /* vshort, vchar, vchar. */
8810 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
8811 type = v8hi_ftype_v16qi_v16qi;
8813 /* vint, vshort, vshort. */
8814 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
8815 type = v4si_ftype_v8hi_v8hi;
8817 /* vshort, vint, vint. */
8818 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
8819 type = v8hi_ftype_v4si_v4si;
8821 /* vchar, vshort, vshort. */
8822 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
8823 type = v16qi_ftype_v8hi_v8hi;
8825 /* vint, vchar, vint. */
8826 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
8827 type = v4si_ftype_v16qi_v4si;
8829 /* vint, vchar, vchar. */
8830 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
8831 type = v4si_ftype_v16qi_v16qi;
8833 /* vint, vshort, vint. */
8834 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
8835 type = v4si_ftype_v8hi_v4si;
8837 /* vint, vint, 5 bit literal. */
8838 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
8839 type = v4si_ftype_v4si_int;
8841 /* vshort, vshort, 5 bit literal. */
8842 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
8843 type = v8hi_ftype_v8hi_int;
8845 /* vchar, vchar, 5 bit literal. */
8846 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
8847 type = v16qi_ftype_v16qi_int;
8849 /* vfloat, vint, 5 bit literal. */
8850 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
8851 type = v4sf_ftype_v4si_int;
8853 /* vint, vfloat, 5 bit literal. */
8854 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
8855 type = v4si_ftype_v4sf_int;
8857 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
8858 type = v2si_ftype_int_int;
8860 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
8861 type = v2si_ftype_v2si_char;
8863 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
8864 type = v2si_ftype_int_char;
8866 else
8868 /* int, x, x. */
8869 gcc_assert (mode0 == SImode);
8870 switch (mode1)
8872 case V4SImode:
8873 type = int_ftype_v4si_v4si;
8874 break;
8875 case V4SFmode:
8876 type = int_ftype_v4sf_v4sf;
8877 break;
8878 case V16QImode:
8879 type = int_ftype_v16qi_v16qi;
8880 break;
8881 case V8HImode:
8882 type = int_ftype_v8hi_v8hi;
8883 break;
8884 default:
8885 gcc_unreachable ();
8889 def_builtin (d->mask, d->name, type, d->code);
8892 /* Add the simple unary operators. */
8893 d = (struct builtin_description *) bdesc_1arg;
8894 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
8896 enum machine_mode mode0, mode1;
8897 tree type;
8898 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8899 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
8901 if (is_overloaded)
8903 mode0 = VOIDmode;
8904 mode1 = VOIDmode;
8906 else
8908 if (d->name == 0 || d->icode == CODE_FOR_nothing)
8909 continue;
8911 mode0 = insn_data[d->icode].operand[0].mode;
8912 mode1 = insn_data[d->icode].operand[1].mode;
8915 if (mode0 == V4SImode && mode1 == QImode)
8916 type = v4si_ftype_int;
8917 else if (mode0 == V8HImode && mode1 == QImode)
8918 type = v8hi_ftype_int;
8919 else if (mode0 == V16QImode && mode1 == QImode)
8920 type = v16qi_ftype_int;
8921 else if (mode0 == VOIDmode && mode1 == VOIDmode)
8922 type = opaque_ftype_opaque;
8923 else if (mode0 == V4SFmode && mode1 == V4SFmode)
8924 type = v4sf_ftype_v4sf;
8925 else if (mode0 == V8HImode && mode1 == V16QImode)
8926 type = v8hi_ftype_v16qi;
8927 else if (mode0 == V4SImode && mode1 == V8HImode)
8928 type = v4si_ftype_v8hi;
8929 else if (mode0 == V2SImode && mode1 == V2SImode)
8930 type = v2si_ftype_v2si;
8931 else if (mode0 == V2SFmode && mode1 == V2SFmode)
8932 type = v2sf_ftype_v2sf;
8933 else if (mode0 == V2SFmode && mode1 == V2SImode)
8934 type = v2sf_ftype_v2si;
8935 else if (mode0 == V2SImode && mode1 == V2SFmode)
8936 type = v2si_ftype_v2sf;
8937 else if (mode0 == V2SImode && mode1 == QImode)
8938 type = v2si_ftype_char;
8939 else
8940 gcc_unreachable ();
8942 def_builtin (d->mask, d->name, type, d->code);
8946 static void
8947 rs6000_init_libfuncs (void)
8949 if (!TARGET_HARD_FLOAT)
8950 return;
8952 if (DEFAULT_ABI != ABI_V4)
8954 if (TARGET_XCOFF && ! TARGET_POWER2 && ! TARGET_POWERPC)
8956 /* AIX library routines for float->int conversion. */
8957 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
8958 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
8959 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
8960 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
8963 /* AIX/Darwin/64-bit Linux quad floating point routines. */
8964 if (!TARGET_XL_COMPAT)
8966 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
8967 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
8968 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
8969 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
8971 else
8973 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
8974 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
8975 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
8976 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
8979 else
8981 /* 32-bit SVR4 quad floating point routines. */
8983 set_optab_libfunc (add_optab, TFmode, "_q_add");
8984 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
8985 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
8986 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
8987 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
8988 if (TARGET_PPC_GPOPT || TARGET_POWER2)
8989 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
8991 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
8992 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
8993 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
8994 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
8995 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
8996 set_optab_libfunc (le_optab, TFmode, "_q_fle");
8998 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
8999 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
9000 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
9001 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
9002 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
9003 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
9004 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
9009 /* Expand a block clear operation, and return 1 if successful. Return 0
9010 if we should let the compiler generate normal code.
9012 operands[0] is the destination
9013 operands[1] is the length
9014 operands[3] is the alignment */
9017 expand_block_clear (rtx operands[])
9019 rtx orig_dest = operands[0];
9020 rtx bytes_rtx = operands[1];
9021 rtx align_rtx = operands[3];
9022 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
9023 HOST_WIDE_INT align;
9024 HOST_WIDE_INT bytes;
9025 int offset;
9026 int clear_bytes;
9027 int clear_step;
9029 /* If this is not a fixed size move, just call memcpy */
9030 if (! constp)
9031 return 0;
9033 /* This must be a fixed size alignment */
9034 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9035 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9037 /* Anything to clear? */
9038 bytes = INTVAL (bytes_rtx);
9039 if (bytes <= 0)
9040 return 1;
9042 /* Use the builtin memset after a point, to avoid huge code bloat.
9043 When optimize_size, avoid any significant code bloat; calling
9044 memset is about 4 instructions, so allow for one instruction to
9045 load zero and three to do clearing. */
9046 if (TARGET_ALTIVEC && align >= 128)
9047 clear_step = 16;
9048 else if (TARGET_POWERPC64 && align >= 32)
9049 clear_step = 8;
9050 else
9051 clear_step = 4;
9053 if (optimize_size && bytes > 3 * clear_step)
9054 return 0;
9055 if (! optimize_size && bytes > 8 * clear_step)
9056 return 0;
9058 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
9060 enum machine_mode mode = BLKmode;
9061 rtx dest;
9063 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
9065 clear_bytes = 16;
9066 mode = V4SImode;
9068 else if (bytes >= 8 && TARGET_POWERPC64
9069 /* 64-bit loads and stores require word-aligned
9070 displacements. */
9071 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9073 clear_bytes = 8;
9074 mode = DImode;
9076 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9077 { /* move 4 bytes */
9078 clear_bytes = 4;
9079 mode = SImode;
9081 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9082 { /* move 2 bytes */
9083 clear_bytes = 2;
9084 mode = HImode;
9086 else /* move 1 byte at a time */
9088 clear_bytes = 1;
9089 mode = QImode;
9092 dest = adjust_address (orig_dest, mode, offset);
9094 emit_move_insn (dest, CONST0_RTX (mode));
9097 return 1;
9101 /* Expand a block move operation, and return 1 if successful. Return 0
9102 if we should let the compiler generate normal code.
9104 operands[0] is the destination
9105 operands[1] is the source
9106 operands[2] is the length
9107 operands[3] is the alignment */
9109 #define MAX_MOVE_REG 4
9112 expand_block_move (rtx operands[])
9114 rtx orig_dest = operands[0];
9115 rtx orig_src = operands[1];
9116 rtx bytes_rtx = operands[2];
9117 rtx align_rtx = operands[3];
9118 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
9119 int align;
9120 int bytes;
9121 int offset;
9122 int move_bytes;
9123 rtx stores[MAX_MOVE_REG];
9124 int num_reg = 0;
9126 /* If this is not a fixed size move, just call memcpy */
9127 if (! constp)
9128 return 0;
9130 /* This must be a fixed size alignment */
9131 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
9132 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9134 /* Anything to move? */
9135 bytes = INTVAL (bytes_rtx);
9136 if (bytes <= 0)
9137 return 1;
9139 /* store_one_arg depends on expand_block_move to handle at least the size of
9140 reg_parm_stack_space. */
9141 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
9142 return 0;
9144 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
9146 union {
9147 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
9148 rtx (*mov) (rtx, rtx);
9149 } gen_func;
9150 enum machine_mode mode = BLKmode;
9151 rtx src, dest;
9153 /* Altivec first, since it will be faster than a string move
9154 when it applies, and usually not significantly larger. */
9155 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
9157 move_bytes = 16;
9158 mode = V4SImode;
9159 gen_func.mov = gen_movv4si;
9161 else if (TARGET_STRING
9162 && bytes > 24 /* move up to 32 bytes at a time */
9163 && ! fixed_regs[5]
9164 && ! fixed_regs[6]
9165 && ! fixed_regs[7]
9166 && ! fixed_regs[8]
9167 && ! fixed_regs[9]
9168 && ! fixed_regs[10]
9169 && ! fixed_regs[11]
9170 && ! fixed_regs[12])
9172 move_bytes = (bytes > 32) ? 32 : bytes;
9173 gen_func.movmemsi = gen_movmemsi_8reg;
9175 else if (TARGET_STRING
9176 && bytes > 16 /* move up to 24 bytes at a time */
9177 && ! fixed_regs[5]
9178 && ! fixed_regs[6]
9179 && ! fixed_regs[7]
9180 && ! fixed_regs[8]
9181 && ! fixed_regs[9]
9182 && ! fixed_regs[10])
9184 move_bytes = (bytes > 24) ? 24 : bytes;
9185 gen_func.movmemsi = gen_movmemsi_6reg;
9187 else if (TARGET_STRING
9188 && bytes > 8 /* move up to 16 bytes at a time */
9189 && ! fixed_regs[5]
9190 && ! fixed_regs[6]
9191 && ! fixed_regs[7]
9192 && ! fixed_regs[8])
9194 move_bytes = (bytes > 16) ? 16 : bytes;
9195 gen_func.movmemsi = gen_movmemsi_4reg;
9197 else if (bytes >= 8 && TARGET_POWERPC64
9198 /* 64-bit loads and stores require word-aligned
9199 displacements. */
9200 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
9202 move_bytes = 8;
9203 mode = DImode;
9204 gen_func.mov = gen_movdi;
9206 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
9207 { /* move up to 8 bytes at a time */
9208 move_bytes = (bytes > 8) ? 8 : bytes;
9209 gen_func.movmemsi = gen_movmemsi_2reg;
9211 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
9212 { /* move 4 bytes */
9213 move_bytes = 4;
9214 mode = SImode;
9215 gen_func.mov = gen_movsi;
9217 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
9218 { /* move 2 bytes */
9219 move_bytes = 2;
9220 mode = HImode;
9221 gen_func.mov = gen_movhi;
9223 else if (TARGET_STRING && bytes > 1)
9224 { /* move up to 4 bytes at a time */
9225 move_bytes = (bytes > 4) ? 4 : bytes;
9226 gen_func.movmemsi = gen_movmemsi_1reg;
9228 else /* move 1 byte at a time */
9230 move_bytes = 1;
9231 mode = QImode;
9232 gen_func.mov = gen_movqi;
9235 src = adjust_address (orig_src, mode, offset);
9236 dest = adjust_address (orig_dest, mode, offset);
9238 if (mode != BLKmode)
9240 rtx tmp_reg = gen_reg_rtx (mode);
9242 emit_insn ((*gen_func.mov) (tmp_reg, src));
9243 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
9246 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
9248 int i;
9249 for (i = 0; i < num_reg; i++)
9250 emit_insn (stores[i]);
9251 num_reg = 0;
9254 if (mode == BLKmode)
9256 /* Move the address into scratch registers. The movmemsi
9257 patterns require zero offset. */
9258 if (!REG_P (XEXP (src, 0)))
9260 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
9261 src = replace_equiv_address (src, src_reg);
9263 set_mem_size (src, GEN_INT (move_bytes));
9265 if (!REG_P (XEXP (dest, 0)))
9267 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
9268 dest = replace_equiv_address (dest, dest_reg);
9270 set_mem_size (dest, GEN_INT (move_bytes));
9272 emit_insn ((*gen_func.movmemsi) (dest, src,
9273 GEN_INT (move_bytes & 31),
9274 align_rtx));
9278 return 1;
9282 /* Return a string to perform a load_multiple operation.
9283 operands[0] is the vector.
9284 operands[1] is the source address.
9285 operands[2] is the first destination register. */
9287 const char *
9288 rs6000_output_load_multiple (rtx operands[3])
9290 /* We have to handle the case where the pseudo used to contain the address
9291 is assigned to one of the output registers. */
9292 int i, j;
9293 int words = XVECLEN (operands[0], 0);
9294 rtx xop[10];
9296 if (XVECLEN (operands[0], 0) == 1)
9297 return "{l|lwz} %2,0(%1)";
9299 for (i = 0; i < words; i++)
9300 if (refers_to_regno_p (REGNO (operands[2]) + i,
9301 REGNO (operands[2]) + i + 1, operands[1], 0))
9303 if (i == words-1)
9305 xop[0] = GEN_INT (4 * (words-1));
9306 xop[1] = operands[1];
9307 xop[2] = operands[2];
9308 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
9309 return "";
9311 else if (i == 0)
9313 xop[0] = GEN_INT (4 * (words-1));
9314 xop[1] = operands[1];
9315 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
9316 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);
9317 return "";
9319 else
9321 for (j = 0; j < words; j++)
9322 if (j != i)
9324 xop[0] = GEN_INT (j * 4);
9325 xop[1] = operands[1];
9326 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
9327 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
9329 xop[0] = GEN_INT (i * 4);
9330 xop[1] = operands[1];
9331 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
9332 return "";
9336 return "{lsi|lswi} %2,%1,%N0";
9340 /* A validation routine: say whether CODE, a condition code, and MODE
9341 match. The other alternatives either don't make sense or should
9342 never be generated. */
9344 void
9345 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
9347 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
9348 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
9349 && GET_MODE_CLASS (mode) == MODE_CC);
9351 /* These don't make sense. */
9352 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
9353 || mode != CCUNSmode);
9355 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
9356 || mode == CCUNSmode);
9358 gcc_assert (mode == CCFPmode
9359 || (code != ORDERED && code != UNORDERED
9360 && code != UNEQ && code != LTGT
9361 && code != UNGT && code != UNLT
9362 && code != UNGE && code != UNLE));
9364 /* These should never be generated except for
9365 flag_finite_math_only. */
9366 gcc_assert (mode != CCFPmode
9367 || flag_finite_math_only
9368 || (code != LE && code != GE
9369 && code != UNEQ && code != LTGT
9370 && code != UNGT && code != UNLT));
9372 /* These are invalid; the information is not there. */
9373 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
9377 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9378 mask required to convert the result of a rotate insn into a shift
9379 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9382 includes_lshift_p (rtx shiftop, rtx andop)
9384 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9386 shift_mask <<= INTVAL (shiftop);
9388 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9391 /* Similar, but for right shift. */
9394 includes_rshift_p (rtx shiftop, rtx andop)
9396 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9398 shift_mask >>= INTVAL (shiftop);
9400 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9403 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9404 to perform a left shift. It must have exactly SHIFTOP least
9405 significant 0's, then one or more 1's, then zero or more 0's. */
9408 includes_rldic_lshift_p (rtx shiftop, rtx andop)
9410 if (GET_CODE (andop) == CONST_INT)
9412 HOST_WIDE_INT c, lsb, shift_mask;
9414 c = INTVAL (andop);
9415 if (c == 0 || c == ~0)
9416 return 0;
9418 shift_mask = ~0;
9419 shift_mask <<= INTVAL (shiftop);
9421 /* Find the least significant one bit. */
9422 lsb = c & -c;
9424 /* It must coincide with the LSB of the shift mask. */
9425 if (-lsb != shift_mask)
9426 return 0;
9428 /* Invert to look for the next transition (if any). */
9429 c = ~c;
9431 /* Remove the low group of ones (originally low group of zeros). */
9432 c &= -lsb;
9434 /* Again find the lsb, and check we have all 1's above. */
9435 lsb = c & -c;
9436 return c == -lsb;
9438 else if (GET_CODE (andop) == CONST_DOUBLE
9439 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9441 HOST_WIDE_INT low, high, lsb;
9442 HOST_WIDE_INT shift_mask_low, shift_mask_high;
9444 low = CONST_DOUBLE_LOW (andop);
9445 if (HOST_BITS_PER_WIDE_INT < 64)
9446 high = CONST_DOUBLE_HIGH (andop);
9448 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
9449 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
9450 return 0;
9452 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9454 shift_mask_high = ~0;
9455 if (INTVAL (shiftop) > 32)
9456 shift_mask_high <<= INTVAL (shiftop) - 32;
9458 lsb = high & -high;
9460 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
9461 return 0;
9463 high = ~high;
9464 high &= -lsb;
9466 lsb = high & -high;
9467 return high == -lsb;
9470 shift_mask_low = ~0;
9471 shift_mask_low <<= INTVAL (shiftop);
9473 lsb = low & -low;
9475 if (-lsb != shift_mask_low)
9476 return 0;
9478 if (HOST_BITS_PER_WIDE_INT < 64)
9479 high = ~high;
9480 low = ~low;
9481 low &= -lsb;
9483 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9485 lsb = high & -high;
9486 return high == -lsb;
9489 lsb = low & -low;
9490 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
9492 else
9493 return 0;
9496 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
9497 to perform a left shift. It must have SHIFTOP or more least
9498 significant 0's, with the remainder of the word 1's. */
9501 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
9503 if (GET_CODE (andop) == CONST_INT)
9505 HOST_WIDE_INT c, lsb, shift_mask;
9507 shift_mask = ~0;
9508 shift_mask <<= INTVAL (shiftop);
9509 c = INTVAL (andop);
9511 /* Find the least significant one bit. */
9512 lsb = c & -c;
9514 /* It must be covered by the shift mask.
9515 This test also rejects c == 0. */
9516 if ((lsb & shift_mask) == 0)
9517 return 0;
9519 /* Check we have all 1's above the transition, and reject all 1's. */
9520 return c == -lsb && lsb != 1;
9522 else if (GET_CODE (andop) == CONST_DOUBLE
9523 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9525 HOST_WIDE_INT low, lsb, shift_mask_low;
9527 low = CONST_DOUBLE_LOW (andop);
9529 if (HOST_BITS_PER_WIDE_INT < 64)
9531 HOST_WIDE_INT high, shift_mask_high;
9533 high = CONST_DOUBLE_HIGH (andop);
9535 if (low == 0)
9537 shift_mask_high = ~0;
9538 if (INTVAL (shiftop) > 32)
9539 shift_mask_high <<= INTVAL (shiftop) - 32;
9541 lsb = high & -high;
9543 if ((lsb & shift_mask_high) == 0)
9544 return 0;
9546 return high == -lsb;
9548 if (high != ~0)
9549 return 0;
9552 shift_mask_low = ~0;
9553 shift_mask_low <<= INTVAL (shiftop);
9555 lsb = low & -low;
9557 if ((lsb & shift_mask_low) == 0)
9558 return 0;
9560 return low == -lsb && lsb != 1;
9562 else
9563 return 0;
9566 /* Return 1 if operands will generate a valid arguments to rlwimi
9567 instruction for insert with right shift in 64-bit mode. The mask may
9568 not start on the first bit or stop on the last bit because wrap-around
9569 effects of instruction do not correspond to semantics of RTL insn. */
9572 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
9574 if (INTVAL (startop) < 64
9575 && INTVAL (startop) > 32
9576 && (INTVAL (sizeop) + INTVAL (startop) < 64)
9577 && (INTVAL (sizeop) + INTVAL (startop) > 33)
9578 && (INTVAL (sizeop) + INTVAL (startop) + INTVAL (shiftop) < 96)
9579 && (INTVAL (sizeop) + INTVAL (startop) + INTVAL (shiftop) >= 64)
9580 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
9581 return 1;
9583 return 0;
9586 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
9587 for lfq and stfq insns iff the registers are hard registers. */
9590 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
9592 /* We might have been passed a SUBREG. */
9593 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
9594 return 0;
9596 /* We might have been passed non floating point registers. */
9597 if (!FP_REGNO_P (REGNO (reg1))
9598 || !FP_REGNO_P (REGNO (reg2)))
9599 return 0;
9601 return (REGNO (reg1) == REGNO (reg2) - 1);
9604 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
9605 addr1 and addr2 must be in consecutive memory locations
9606 (addr2 == addr1 + 8). */
9609 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
9611 rtx addr1, addr2;
9612 unsigned int reg1, reg2;
9613 int offset1, offset2;
9615 /* The mems cannot be volatile. */
9616 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
9617 return 0;
9619 addr1 = XEXP (mem1, 0);
9620 addr2 = XEXP (mem2, 0);
9622 /* Extract an offset (if used) from the first addr. */
9623 if (GET_CODE (addr1) == PLUS)
9625 /* If not a REG, return zero. */
9626 if (GET_CODE (XEXP (addr1, 0)) != REG)
9627 return 0;
9628 else
9630 reg1 = REGNO (XEXP (addr1, 0));
9631 /* The offset must be constant! */
9632 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
9633 return 0;
9634 offset1 = INTVAL (XEXP (addr1, 1));
9637 else if (GET_CODE (addr1) != REG)
9638 return 0;
9639 else
9641 reg1 = REGNO (addr1);
9642 /* This was a simple (mem (reg)) expression. Offset is 0. */
9643 offset1 = 0;
9646 /* And now for the second addr. */
9647 if (GET_CODE (addr2) == PLUS)
9649 /* If not a REG, return zero. */
9650 if (GET_CODE (XEXP (addr2, 0)) != REG)
9651 return 0;
9652 else
9654 reg2 = REGNO (XEXP (addr2, 0));
9655 /* The offset must be constant. */
9656 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
9657 return 0;
9658 offset2 = INTVAL (XEXP (addr2, 1));
9661 else if (GET_CODE (addr2) != REG)
9662 return 0;
9663 else
9665 reg2 = REGNO (addr2);
9666 /* This was a simple (mem (reg)) expression. Offset is 0. */
9667 offset2 = 0;
9670 /* Both of these must have the same base register. */
9671 if (reg1 != reg2)
9672 return 0;
9674 /* The offset for the second addr must be 8 more than the first addr. */
9675 if (offset2 != offset1 + 8)
9676 return 0;
9678 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
9679 instructions. */
9680 return 1;
9683 /* Return the register class of a scratch register needed to copy IN into
9684 or out of a register in CLASS in MODE. If it can be done directly,
9685 NO_REGS is returned. */
9687 enum reg_class
9688 secondary_reload_class (enum reg_class class,
9689 enum machine_mode mode ATTRIBUTE_UNUSED,
9690 rtx in)
9692 int regno;
9694 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
9695 #if TARGET_MACHO
9696 && MACHOPIC_INDIRECT
9697 #endif
9700 /* We cannot copy a symbolic operand directly into anything
9701 other than BASE_REGS for TARGET_ELF. So indicate that a
9702 register from BASE_REGS is needed as an intermediate
9703 register.
9705 On Darwin, pic addresses require a load from memory, which
9706 needs a base register. */
9707 if (class != BASE_REGS
9708 && (GET_CODE (in) == SYMBOL_REF
9709 || GET_CODE (in) == HIGH
9710 || GET_CODE (in) == LABEL_REF
9711 || GET_CODE (in) == CONST))
9712 return BASE_REGS;
9715 if (GET_CODE (in) == REG)
9717 regno = REGNO (in);
9718 if (regno >= FIRST_PSEUDO_REGISTER)
9720 regno = true_regnum (in);
9721 if (regno >= FIRST_PSEUDO_REGISTER)
9722 regno = -1;
9725 else if (GET_CODE (in) == SUBREG)
9727 regno = true_regnum (in);
9728 if (regno >= FIRST_PSEUDO_REGISTER)
9729 regno = -1;
9731 else
9732 regno = -1;
9734 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
9735 into anything. */
9736 if (class == GENERAL_REGS || class == BASE_REGS
9737 || (regno >= 0 && INT_REGNO_P (regno)))
9738 return NO_REGS;
9740 /* Constants, memory, and FP registers can go into FP registers. */
9741 if ((regno == -1 || FP_REGNO_P (regno))
9742 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
9743 return NO_REGS;
9745 /* Memory, and AltiVec registers can go into AltiVec registers. */
9746 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
9747 && class == ALTIVEC_REGS)
9748 return NO_REGS;
9750 /* We can copy among the CR registers. */
9751 if ((class == CR_REGS || class == CR0_REGS)
9752 && regno >= 0 && CR_REGNO_P (regno))
9753 return NO_REGS;
9755 /* Otherwise, we need GENERAL_REGS. */
9756 return GENERAL_REGS;
9759 /* Given a comparison operation, return the bit number in CCR to test. We
9760 know this is a valid comparison.
9762 SCC_P is 1 if this is for an scc. That means that %D will have been
9763 used instead of %C, so the bits will be in different places.
9765 Return -1 if OP isn't a valid comparison for some reason. */
9768 ccr_bit (rtx op, int scc_p)
9770 enum rtx_code code = GET_CODE (op);
9771 enum machine_mode cc_mode;
9772 int cc_regnum;
9773 int base_bit;
9774 rtx reg;
9776 if (!COMPARISON_P (op))
9777 return -1;
9779 reg = XEXP (op, 0);
9781 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
9783 cc_mode = GET_MODE (reg);
9784 cc_regnum = REGNO (reg);
9785 base_bit = 4 * (cc_regnum - CR0_REGNO);
9787 validate_condition_mode (code, cc_mode);
9789 /* When generating a sCOND operation, only positive conditions are
9790 allowed. */
9791 gcc_assert (!scc_p
9792 || code == EQ || code == GT || code == LT || code == UNORDERED
9793 || code == GTU || code == LTU);
9795 switch (code)
9797 case NE:
9798 return scc_p ? base_bit + 3 : base_bit + 2;
9799 case EQ:
9800 return base_bit + 2;
9801 case GT: case GTU: case UNLE:
9802 return base_bit + 1;
9803 case LT: case LTU: case UNGE:
9804 return base_bit;
9805 case ORDERED: case UNORDERED:
9806 return base_bit + 3;
9808 case GE: case GEU:
9809 /* If scc, we will have done a cror to put the bit in the
9810 unordered position. So test that bit. For integer, this is ! LT
9811 unless this is an scc insn. */
9812 return scc_p ? base_bit + 3 : base_bit;
9814 case LE: case LEU:
9815 return scc_p ? base_bit + 3 : base_bit + 1;
9817 default:
9818 gcc_unreachable ();
9822 /* Return the GOT register. */
9825 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
9827 /* The second flow pass currently (June 1999) can't update
9828 regs_ever_live without disturbing other parts of the compiler, so
9829 update it here to make the prolog/epilogue code happy. */
9830 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
9831 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
9833 current_function_uses_pic_offset_table = 1;
9835 return pic_offset_table_rtx;
9838 /* Function to init struct machine_function.
9839 This will be called, via a pointer variable,
9840 from push_function_context. */
9842 static struct machine_function *
9843 rs6000_init_machine_status (void)
9845 return ggc_alloc_cleared (sizeof (machine_function));
9848 /* These macros test for integers and extract the low-order bits. */
9849 #define INT_P(X) \
9850 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
9851 && GET_MODE (X) == VOIDmode)
9853 #define INT_LOWPART(X) \
9854 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
9857 extract_MB (rtx op)
9859 int i;
9860 unsigned long val = INT_LOWPART (op);
9862 /* If the high bit is zero, the value is the first 1 bit we find
9863 from the left. */
9864 if ((val & 0x80000000) == 0)
9866 gcc_assert (val & 0xffffffff);
9868 i = 1;
9869 while (((val <<= 1) & 0x80000000) == 0)
9870 ++i;
9871 return i;
9874 /* If the high bit is set and the low bit is not, or the mask is all
9875 1's, the value is zero. */
9876 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
9877 return 0;
9879 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
9880 from the right. */
9881 i = 31;
9882 while (((val >>= 1) & 1) != 0)
9883 --i;
9885 return i;
9889 extract_ME (rtx op)
9891 int i;
9892 unsigned long val = INT_LOWPART (op);
9894 /* If the low bit is zero, the value is the first 1 bit we find from
9895 the right. */
9896 if ((val & 1) == 0)
9898 gcc_assert (val & 0xffffffff);
9900 i = 30;
9901 while (((val >>= 1) & 1) == 0)
9902 --i;
9904 return i;
9907 /* If the low bit is set and the high bit is not, or the mask is all
9908 1's, the value is 31. */
9909 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
9910 return 31;
9912 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
9913 from the left. */
9914 i = 0;
9915 while (((val <<= 1) & 0x80000000) != 0)
9916 ++i;
9918 return i;
9921 /* Locate some local-dynamic symbol still in use by this function
9922 so that we can print its name in some tls_ld pattern. */
9924 static const char *
9925 rs6000_get_some_local_dynamic_name (void)
9927 rtx insn;
9929 if (cfun->machine->some_ld_name)
9930 return cfun->machine->some_ld_name;
9932 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
9933 if (INSN_P (insn)
9934 && for_each_rtx (&PATTERN (insn),
9935 rs6000_get_some_local_dynamic_name_1, 0))
9936 return cfun->machine->some_ld_name;
9938 gcc_unreachable ();
9941 /* Helper function for rs6000_get_some_local_dynamic_name. */
9943 static int
9944 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
9946 rtx x = *px;
9948 if (GET_CODE (x) == SYMBOL_REF)
9950 const char *str = XSTR (x, 0);
9951 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
9953 cfun->machine->some_ld_name = str;
9954 return 1;
9958 return 0;
9961 /* Write out a function code label. */
9963 void
9964 rs6000_output_function_entry (FILE *file, const char *fname)
9966 if (fname[0] != '.')
9968 switch (DEFAULT_ABI)
9970 default:
9971 gcc_unreachable ();
9973 case ABI_AIX:
9974 if (DOT_SYMBOLS)
9975 putc ('.', file);
9976 else
9977 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
9978 break;
9980 case ABI_V4:
9981 case ABI_DARWIN:
9982 break;
9985 if (TARGET_AIX)
9986 RS6000_OUTPUT_BASENAME (file, fname);
9987 else
9988 assemble_name (file, fname);
9991 /* Print an operand. Recognize special options, documented below. */
9993 #if TARGET_ELF
9994 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
9995 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
9996 #else
9997 #define SMALL_DATA_RELOC "sda21"
9998 #define SMALL_DATA_REG 0
9999 #endif
10001 void
10002 print_operand (FILE *file, rtx x, int code)
10004 int i;
10005 HOST_WIDE_INT val;
10006 unsigned HOST_WIDE_INT uval;
10008 switch (code)
10010 case '.':
10011 /* Write out an instruction after the call which may be replaced
10012 with glue code by the loader. This depends on the AIX version. */
10013 asm_fprintf (file, RS6000_CALL_GLUE);
10014 return;
10016 /* %a is output_address. */
10018 case 'A':
10019 /* If X is a constant integer whose low-order 5 bits are zero,
10020 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10021 in the AIX assembler where "sri" with a zero shift count
10022 writes a trash instruction. */
10023 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
10024 putc ('l', file);
10025 else
10026 putc ('r', file);
10027 return;
10029 case 'b':
10030 /* If constant, low-order 16 bits of constant, unsigned.
10031 Otherwise, write normally. */
10032 if (INT_P (x))
10033 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
10034 else
10035 print_operand (file, x, 0);
10036 return;
10038 case 'B':
10039 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10040 for 64-bit mask direction. */
10041 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
10042 return;
10044 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10045 output_operand. */
10047 case 'c':
10048 /* X is a CR register. Print the number of the GT bit of the CR. */
10049 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10050 output_operand_lossage ("invalid %%E value");
10051 else
10052 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
10053 return;
10055 case 'D':
10056 /* Like 'J' but get to the EQ bit. */
10057 gcc_assert (GET_CODE (x) == REG);
10059 /* Bit 1 is EQ bit. */
10060 i = 4 * (REGNO (x) - CR0_REGNO) + 2;
10062 fprintf (file, "%d", i);
10063 return;
10065 case 'E':
10066 /* X is a CR register. Print the number of the EQ bit of the CR */
10067 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10068 output_operand_lossage ("invalid %%E value");
10069 else
10070 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
10071 return;
10073 case 'f':
10074 /* X is a CR register. Print the shift count needed to move it
10075 to the high-order four bits. */
10076 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10077 output_operand_lossage ("invalid %%f value");
10078 else
10079 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
10080 return;
10082 case 'F':
10083 /* Similar, but print the count for the rotate in the opposite
10084 direction. */
10085 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10086 output_operand_lossage ("invalid %%F value");
10087 else
10088 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
10089 return;
10091 case 'G':
10092 /* X is a constant integer. If it is negative, print "m",
10093 otherwise print "z". This is to make an aze or ame insn. */
10094 if (GET_CODE (x) != CONST_INT)
10095 output_operand_lossage ("invalid %%G value");
10096 else if (INTVAL (x) >= 0)
10097 putc ('z', file);
10098 else
10099 putc ('m', file);
10100 return;
10102 case 'h':
10103 /* If constant, output low-order five bits. Otherwise, write
10104 normally. */
10105 if (INT_P (x))
10106 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
10107 else
10108 print_operand (file, x, 0);
10109 return;
10111 case 'H':
10112 /* If constant, output low-order six bits. Otherwise, write
10113 normally. */
10114 if (INT_P (x))
10115 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
10116 else
10117 print_operand (file, x, 0);
10118 return;
10120 case 'I':
10121 /* Print `i' if this is a constant, else nothing. */
10122 if (INT_P (x))
10123 putc ('i', file);
10124 return;
10126 case 'j':
10127 /* Write the bit number in CCR for jump. */
10128 i = ccr_bit (x, 0);
10129 if (i == -1)
10130 output_operand_lossage ("invalid %%j code");
10131 else
10132 fprintf (file, "%d", i);
10133 return;
10135 case 'J':
10136 /* Similar, but add one for shift count in rlinm for scc and pass
10137 scc flag to `ccr_bit'. */
10138 i = ccr_bit (x, 1);
10139 if (i == -1)
10140 output_operand_lossage ("invalid %%J code");
10141 else
10142 /* If we want bit 31, write a shift count of zero, not 32. */
10143 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10144 return;
10146 case 'k':
10147 /* X must be a constant. Write the 1's complement of the
10148 constant. */
10149 if (! INT_P (x))
10150 output_operand_lossage ("invalid %%k value");
10151 else
10152 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
10153 return;
10155 case 'K':
10156 /* X must be a symbolic constant on ELF. Write an
10157 expression suitable for an 'addi' that adds in the low 16
10158 bits of the MEM. */
10159 if (GET_CODE (x) != CONST)
10161 print_operand_address (file, x);
10162 fputs ("@l", file);
10164 else
10166 if (GET_CODE (XEXP (x, 0)) != PLUS
10167 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
10168 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
10169 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
10170 output_operand_lossage ("invalid %%K value");
10171 print_operand_address (file, XEXP (XEXP (x, 0), 0));
10172 fputs ("@l", file);
10173 /* For GNU as, there must be a non-alphanumeric character
10174 between 'l' and the number. The '-' is added by
10175 print_operand() already. */
10176 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
10177 fputs ("+", file);
10178 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
10180 return;
10182 /* %l is output_asm_label. */
10184 case 'L':
10185 /* Write second word of DImode or DFmode reference. Works on register
10186 or non-indexed memory only. */
10187 if (GET_CODE (x) == REG)
10188 fputs (reg_names[REGNO (x) + 1], file);
10189 else if (GET_CODE (x) == MEM)
10191 /* Handle possible auto-increment. Since it is pre-increment and
10192 we have already done it, we can just use an offset of word. */
10193 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10194 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10195 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
10196 UNITS_PER_WORD));
10197 else
10198 output_address (XEXP (adjust_address_nv (x, SImode,
10199 UNITS_PER_WORD),
10200 0));
10202 if (small_data_operand (x, GET_MODE (x)))
10203 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10204 reg_names[SMALL_DATA_REG]);
10206 return;
10208 case 'm':
10209 /* MB value for a mask operand. */
10210 if (! mask_operand (x, SImode))
10211 output_operand_lossage ("invalid %%m value");
10213 fprintf (file, "%d", extract_MB (x));
10214 return;
10216 case 'M':
10217 /* ME value for a mask operand. */
10218 if (! mask_operand (x, SImode))
10219 output_operand_lossage ("invalid %%M value");
10221 fprintf (file, "%d", extract_ME (x));
10222 return;
10224 /* %n outputs the negative of its operand. */
10226 case 'N':
10227 /* Write the number of elements in the vector times 4. */
10228 if (GET_CODE (x) != PARALLEL)
10229 output_operand_lossage ("invalid %%N value");
10230 else
10231 fprintf (file, "%d", XVECLEN (x, 0) * 4);
10232 return;
10234 case 'O':
10235 /* Similar, but subtract 1 first. */
10236 if (GET_CODE (x) != PARALLEL)
10237 output_operand_lossage ("invalid %%O value");
10238 else
10239 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
10240 return;
10242 case 'p':
10243 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10244 if (! INT_P (x)
10245 || INT_LOWPART (x) < 0
10246 || (i = exact_log2 (INT_LOWPART (x))) < 0)
10247 output_operand_lossage ("invalid %%p value");
10248 else
10249 fprintf (file, "%d", i);
10250 return;
10252 case 'P':
10253 /* The operand must be an indirect memory reference. The result
10254 is the register name. */
10255 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
10256 || REGNO (XEXP (x, 0)) >= 32)
10257 output_operand_lossage ("invalid %%P value");
10258 else
10259 fputs (reg_names[REGNO (XEXP (x, 0))], file);
10260 return;
10262 case 'q':
10263 /* This outputs the logical code corresponding to a boolean
10264 expression. The expression may have one or both operands
10265 negated (if one, only the first one). For condition register
10266 logical operations, it will also treat the negated
10267 CR codes as NOTs, but not handle NOTs of them. */
10269 const char *const *t = 0;
10270 const char *s;
10271 enum rtx_code code = GET_CODE (x);
10272 static const char * const tbl[3][3] = {
10273 { "and", "andc", "nor" },
10274 { "or", "orc", "nand" },
10275 { "xor", "eqv", "xor" } };
10277 if (code == AND)
10278 t = tbl[0];
10279 else if (code == IOR)
10280 t = tbl[1];
10281 else if (code == XOR)
10282 t = tbl[2];
10283 else
10284 output_operand_lossage ("invalid %%q value");
10286 if (GET_CODE (XEXP (x, 0)) != NOT)
10287 s = t[0];
10288 else
10290 if (GET_CODE (XEXP (x, 1)) == NOT)
10291 s = t[2];
10292 else
10293 s = t[1];
10296 fputs (s, file);
10298 return;
10300 case 'Q':
10301 if (TARGET_MFCRF)
10302 fputc (',', file);
10303 /* FALLTHRU */
10304 else
10305 return;
10307 case 'R':
10308 /* X is a CR register. Print the mask for `mtcrf'. */
10309 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10310 output_operand_lossage ("invalid %%R value");
10311 else
10312 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
10313 return;
10315 case 's':
10316 /* Low 5 bits of 32 - value */
10317 if (! INT_P (x))
10318 output_operand_lossage ("invalid %%s value");
10319 else
10320 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
10321 return;
10323 case 'S':
10324 /* PowerPC64 mask position. All 0's is excluded.
10325 CONST_INT 32-bit mask is considered sign-extended so any
10326 transition must occur within the CONST_INT, not on the boundary. */
10327 if (! mask64_operand (x, DImode))
10328 output_operand_lossage ("invalid %%S value");
10330 uval = INT_LOWPART (x);
10332 if (uval & 1) /* Clear Left */
10334 #if HOST_BITS_PER_WIDE_INT > 64
10335 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10336 #endif
10337 i = 64;
10339 else /* Clear Right */
10341 uval = ~uval;
10342 #if HOST_BITS_PER_WIDE_INT > 64
10343 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10344 #endif
10345 i = 63;
10347 while (uval != 0)
10348 --i, uval >>= 1;
10349 gcc_assert (i >= 0);
10350 fprintf (file, "%d", i);
10351 return;
10353 case 't':
10354 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10355 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
10357 /* Bit 3 is OV bit. */
10358 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
10360 /* If we want bit 31, write a shift count of zero, not 32. */
10361 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10362 return;
10364 case 'T':
10365 /* Print the symbolic name of a branch target register. */
10366 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
10367 && REGNO (x) != COUNT_REGISTER_REGNUM))
10368 output_operand_lossage ("invalid %%T value");
10369 else if (REGNO (x) == LINK_REGISTER_REGNUM)
10370 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
10371 else
10372 fputs ("ctr", file);
10373 return;
10375 case 'u':
10376 /* High-order 16 bits of constant for use in unsigned operand. */
10377 if (! INT_P (x))
10378 output_operand_lossage ("invalid %%u value");
10379 else
10380 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10381 (INT_LOWPART (x) >> 16) & 0xffff);
10382 return;
10384 case 'v':
10385 /* High-order 16 bits of constant for use in signed operand. */
10386 if (! INT_P (x))
10387 output_operand_lossage ("invalid %%v value");
10388 else
10389 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10390 (INT_LOWPART (x) >> 16) & 0xffff);
10391 return;
10393 case 'U':
10394 /* Print `u' if this has an auto-increment or auto-decrement. */
10395 if (GET_CODE (x) == MEM
10396 && (GET_CODE (XEXP (x, 0)) == PRE_INC
10397 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
10398 putc ('u', file);
10399 return;
10401 case 'V':
10402 /* Print the trap code for this operand. */
10403 switch (GET_CODE (x))
10405 case EQ:
10406 fputs ("eq", file); /* 4 */
10407 break;
10408 case NE:
10409 fputs ("ne", file); /* 24 */
10410 break;
10411 case LT:
10412 fputs ("lt", file); /* 16 */
10413 break;
10414 case LE:
10415 fputs ("le", file); /* 20 */
10416 break;
10417 case GT:
10418 fputs ("gt", file); /* 8 */
10419 break;
10420 case GE:
10421 fputs ("ge", file); /* 12 */
10422 break;
10423 case LTU:
10424 fputs ("llt", file); /* 2 */
10425 break;
10426 case LEU:
10427 fputs ("lle", file); /* 6 */
10428 break;
10429 case GTU:
10430 fputs ("lgt", file); /* 1 */
10431 break;
10432 case GEU:
10433 fputs ("lge", file); /* 5 */
10434 break;
10435 default:
10436 gcc_unreachable ();
10438 break;
10440 case 'w':
10441 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10442 normally. */
10443 if (INT_P (x))
10444 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
10445 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
10446 else
10447 print_operand (file, x, 0);
10448 return;
10450 case 'W':
10451 /* MB value for a PowerPC64 rldic operand. */
10452 val = (GET_CODE (x) == CONST_INT
10453 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
10455 if (val < 0)
10456 i = -1;
10457 else
10458 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
10459 if ((val <<= 1) < 0)
10460 break;
10462 #if HOST_BITS_PER_WIDE_INT == 32
10463 if (GET_CODE (x) == CONST_INT && i >= 0)
10464 i += 32; /* zero-extend high-part was all 0's */
10465 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
10467 val = CONST_DOUBLE_LOW (x);
10469 gcc_assert (val);
10470 if (val < 0)
10471 --i;
10472 else
10473 for ( ; i < 64; i++)
10474 if ((val <<= 1) < 0)
10475 break;
10477 #endif
10479 fprintf (file, "%d", i + 1);
10480 return;
10482 case 'X':
10483 if (GET_CODE (x) == MEM
10484 && legitimate_indexed_address_p (XEXP (x, 0), 0))
10485 putc ('x', file);
10486 return;
10488 case 'Y':
10489 /* Like 'L', for third word of TImode */
10490 if (GET_CODE (x) == REG)
10491 fputs (reg_names[REGNO (x) + 2], file);
10492 else if (GET_CODE (x) == MEM)
10494 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10495 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10496 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
10497 else
10498 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
10499 if (small_data_operand (x, GET_MODE (x)))
10500 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10501 reg_names[SMALL_DATA_REG]);
10503 return;
10505 case 'z':
10506 /* X is a SYMBOL_REF. Write out the name preceded by a
10507 period and without any trailing data in brackets. Used for function
10508 names. If we are configured for System V (or the embedded ABI) on
10509 the PowerPC, do not emit the period, since those systems do not use
10510 TOCs and the like. */
10511 gcc_assert (GET_CODE (x) == SYMBOL_REF);
10513 /* Mark the decl as referenced so that cgraph will output the
10514 function. */
10515 if (SYMBOL_REF_DECL (x))
10516 mark_decl_referenced (SYMBOL_REF_DECL (x));
10518 /* For macho, check to see if we need a stub. */
10519 if (TARGET_MACHO)
10521 const char *name = XSTR (x, 0);
10522 #if TARGET_MACHO
10523 if (MACHOPIC_INDIRECT
10524 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
10525 name = machopic_indirection_name (x, /*stub_p=*/true);
10526 #endif
10527 assemble_name (file, name);
10529 else if (!DOT_SYMBOLS)
10530 assemble_name (file, XSTR (x, 0));
10531 else
10532 rs6000_output_function_entry (file, XSTR (x, 0));
10533 return;
10535 case 'Z':
10536 /* Like 'L', for last word of TImode. */
10537 if (GET_CODE (x) == REG)
10538 fputs (reg_names[REGNO (x) + 3], file);
10539 else if (GET_CODE (x) == MEM)
10541 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10542 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
10543 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
10544 else
10545 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
10546 if (small_data_operand (x, GET_MODE (x)))
10547 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10548 reg_names[SMALL_DATA_REG]);
10550 return;
10552 /* Print AltiVec or SPE memory operand. */
10553 case 'y':
10555 rtx tmp;
10557 gcc_assert (GET_CODE (x) == MEM);
10559 tmp = XEXP (x, 0);
10561 if (TARGET_E500)
10563 /* Handle [reg]. */
10564 if (GET_CODE (tmp) == REG)
10566 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
10567 break;
10569 /* Handle [reg+UIMM]. */
10570 else if (GET_CODE (tmp) == PLUS &&
10571 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
10573 int x;
10575 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
10577 x = INTVAL (XEXP (tmp, 1));
10578 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
10579 break;
10582 /* Fall through. Must be [reg+reg]. */
10584 if (TARGET_ALTIVEC
10585 && GET_CODE (tmp) == AND
10586 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
10587 && INTVAL (XEXP (tmp, 1)) == -16)
10588 tmp = XEXP (tmp, 0);
10589 if (GET_CODE (tmp) == REG)
10590 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
10591 else
10593 gcc_assert (GET_CODE (tmp) == PLUS
10594 && GET_CODE (XEXP (tmp, 1)) == REG);
10596 if (REGNO (XEXP (tmp, 0)) == 0)
10597 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
10598 reg_names[ REGNO (XEXP (tmp, 0)) ]);
10599 else
10600 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
10601 reg_names[ REGNO (XEXP (tmp, 1)) ]);
10603 break;
10606 case 0:
10607 if (GET_CODE (x) == REG)
10608 fprintf (file, "%s", reg_names[REGNO (x)]);
10609 else if (GET_CODE (x) == MEM)
10611 /* We need to handle PRE_INC and PRE_DEC here, since we need to
10612 know the width from the mode. */
10613 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
10614 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
10615 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
10616 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
10617 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
10618 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
10619 else
10620 output_address (XEXP (x, 0));
10622 else
10623 output_addr_const (file, x);
10624 return;
10626 case '&':
10627 assemble_name (file, rs6000_get_some_local_dynamic_name ());
10628 return;
10630 default:
10631 output_operand_lossage ("invalid %%xn code");
10635 /* Print the address of an operand. */
10637 void
10638 print_operand_address (FILE *file, rtx x)
10640 if (GET_CODE (x) == REG)
10641 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
10642 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
10643 || GET_CODE (x) == LABEL_REF)
10645 output_addr_const (file, x);
10646 if (small_data_operand (x, GET_MODE (x)))
10647 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10648 reg_names[SMALL_DATA_REG]);
10649 else
10650 gcc_assert (!TARGET_TOC);
10652 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
10654 if (REGNO (XEXP (x, 0)) == 0)
10655 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
10656 reg_names[ REGNO (XEXP (x, 0)) ]);
10657 else
10658 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
10659 reg_names[ REGNO (XEXP (x, 1)) ]);
10661 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
10662 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
10663 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
10664 #if TARGET_ELF
10665 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
10666 && CONSTANT_P (XEXP (x, 1)))
10668 output_addr_const (file, XEXP (x, 1));
10669 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
10671 #endif
10672 #if TARGET_MACHO
10673 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
10674 && CONSTANT_P (XEXP (x, 1)))
10676 fprintf (file, "lo16(");
10677 output_addr_const (file, XEXP (x, 1));
10678 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
10680 #endif
10681 else if (legitimate_constant_pool_address_p (x))
10683 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
10685 rtx contains_minus = XEXP (x, 1);
10686 rtx minus, symref;
10687 const char *name;
10689 /* Find the (minus (sym) (toc)) buried in X, and temporarily
10690 turn it into (sym) for output_addr_const. */
10691 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
10692 contains_minus = XEXP (contains_minus, 0);
10694 minus = XEXP (contains_minus, 0);
10695 symref = XEXP (minus, 0);
10696 XEXP (contains_minus, 0) = symref;
10697 if (TARGET_ELF)
10699 char *newname;
10701 name = XSTR (symref, 0);
10702 newname = alloca (strlen (name) + sizeof ("@toc"));
10703 strcpy (newname, name);
10704 strcat (newname, "@toc");
10705 XSTR (symref, 0) = newname;
10707 output_addr_const (file, XEXP (x, 1));
10708 if (TARGET_ELF)
10709 XSTR (symref, 0) = name;
10710 XEXP (contains_minus, 0) = minus;
10712 else
10713 output_addr_const (file, XEXP (x, 1));
10715 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
10717 else
10718 gcc_unreachable ();
10721 /* Target hook for assembling integer objects. The PowerPC version has
10722 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
10723 is defined. It also needs to handle DI-mode objects on 64-bit
10724 targets. */
10726 static bool
10727 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
10729 #ifdef RELOCATABLE_NEEDS_FIXUP
10730 /* Special handling for SI values. */
10731 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
10733 extern int in_toc_section (void);
10734 static int recurse = 0;
10736 /* For -mrelocatable, we mark all addresses that need to be fixed up
10737 in the .fixup section. */
10738 if (TARGET_RELOCATABLE
10739 && !in_toc_section ()
10740 && !in_text_section ()
10741 && !in_unlikely_text_section ()
10742 && !recurse
10743 && GET_CODE (x) != CONST_INT
10744 && GET_CODE (x) != CONST_DOUBLE
10745 && CONSTANT_P (x))
10747 char buf[256];
10749 recurse = 1;
10750 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
10751 fixuplabelno++;
10752 ASM_OUTPUT_LABEL (asm_out_file, buf);
10753 fprintf (asm_out_file, "\t.long\t(");
10754 output_addr_const (asm_out_file, x);
10755 fprintf (asm_out_file, ")@fixup\n");
10756 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
10757 ASM_OUTPUT_ALIGN (asm_out_file, 2);
10758 fprintf (asm_out_file, "\t.long\t");
10759 assemble_name (asm_out_file, buf);
10760 fprintf (asm_out_file, "\n\t.previous\n");
10761 recurse = 0;
10762 return true;
10764 /* Remove initial .'s to turn a -mcall-aixdesc function
10765 address into the address of the descriptor, not the function
10766 itself. */
10767 else if (GET_CODE (x) == SYMBOL_REF
10768 && XSTR (x, 0)[0] == '.'
10769 && DEFAULT_ABI == ABI_AIX)
10771 const char *name = XSTR (x, 0);
10772 while (*name == '.')
10773 name++;
10775 fprintf (asm_out_file, "\t.long\t%s\n", name);
10776 return true;
10779 #endif /* RELOCATABLE_NEEDS_FIXUP */
10780 return default_assemble_integer (x, size, aligned_p);
10783 #ifdef HAVE_GAS_HIDDEN
10784 /* Emit an assembler directive to set symbol visibility for DECL to
10785 VISIBILITY_TYPE. */
10787 static void
10788 rs6000_assemble_visibility (tree decl, int vis)
10790 /* Functions need to have their entry point symbol visibility set as
10791 well as their descriptor symbol visibility. */
10792 if (DEFAULT_ABI == ABI_AIX
10793 && DOT_SYMBOLS
10794 && TREE_CODE (decl) == FUNCTION_DECL)
10796 static const char * const visibility_types[] = {
10797 NULL, "internal", "hidden", "protected"
10800 const char *name, *type;
10802 name = ((* targetm.strip_name_encoding)
10803 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
10804 type = visibility_types[vis];
10806 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
10807 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
10809 else
10810 default_assemble_visibility (decl, vis);
10812 #endif
10814 enum rtx_code
10815 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
10817 /* Reversal of FP compares takes care -- an ordered compare
10818 becomes an unordered compare and vice versa. */
10819 if (mode == CCFPmode
10820 && (!flag_finite_math_only
10821 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
10822 || code == UNEQ || code == LTGT))
10823 return reverse_condition_maybe_unordered (code);
10824 else
10825 return reverse_condition (code);
10828 /* Generate a compare for CODE. Return a brand-new rtx that
10829 represents the result of the compare. */
10831 static rtx
10832 rs6000_generate_compare (enum rtx_code code)
10834 enum machine_mode comp_mode;
10835 rtx compare_result;
10837 if (rs6000_compare_fp_p)
10838 comp_mode = CCFPmode;
10839 else if (code == GTU || code == LTU
10840 || code == GEU || code == LEU)
10841 comp_mode = CCUNSmode;
10842 else if ((code == EQ || code == NE)
10843 && GET_CODE (rs6000_compare_op0) == SUBREG
10844 && GET_CODE (rs6000_compare_op1) == SUBREG
10845 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
10846 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
10847 /* These are unsigned values, perhaps there will be a later
10848 ordering compare that can be shared with this one.
10849 Unfortunately we cannot detect the signedness of the operands
10850 for non-subregs. */
10851 comp_mode = CCUNSmode;
10852 else
10853 comp_mode = CCmode;
10855 /* First, the compare. */
10856 compare_result = gen_reg_rtx (comp_mode);
10858 /* SPE FP compare instructions on the GPRs. Yuck! */
10859 if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT)
10860 && rs6000_compare_fp_p)
10862 rtx cmp, or_result, compare_result2;
10863 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
10865 if (op_mode == VOIDmode)
10866 op_mode = GET_MODE (rs6000_compare_op1);
10868 /* Note: The E500 comparison instructions set the GT bit (x +
10869 1), on success. This explains the mess. */
10871 switch (code)
10873 case EQ: case UNEQ: case NE: case LTGT:
10874 switch (op_mode)
10876 case SFmode:
10877 cmp = flag_unsafe_math_optimizations
10878 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
10879 rs6000_compare_op1)
10880 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
10881 rs6000_compare_op1);
10882 break;
10884 case DFmode:
10885 cmp = flag_unsafe_math_optimizations
10886 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
10887 rs6000_compare_op1)
10888 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
10889 rs6000_compare_op1);
10890 break;
10892 default:
10893 gcc_unreachable ();
10895 break;
10897 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
10898 switch (op_mode)
10900 case SFmode:
10901 cmp = flag_unsafe_math_optimizations
10902 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
10903 rs6000_compare_op1)
10904 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
10905 rs6000_compare_op1);
10906 break;
10908 case DFmode:
10909 cmp = flag_unsafe_math_optimizations
10910 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
10911 rs6000_compare_op1)
10912 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
10913 rs6000_compare_op1);
10914 break;
10916 default:
10917 gcc_unreachable ();
10919 break;
10921 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
10922 switch (op_mode)
10924 case SFmode:
10925 cmp = flag_unsafe_math_optimizations
10926 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
10927 rs6000_compare_op1)
10928 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
10929 rs6000_compare_op1);
10930 break;
10932 case DFmode:
10933 cmp = flag_unsafe_math_optimizations
10934 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
10935 rs6000_compare_op1)
10936 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
10937 rs6000_compare_op1);
10938 break;
10940 default:
10941 gcc_unreachable ();
10943 break;
10944 default:
10945 gcc_unreachable ();
10948 /* Synthesize LE and GE from LT/GT || EQ. */
10949 if (code == LE || code == GE || code == LEU || code == GEU)
10951 emit_insn (cmp);
10953 switch (code)
10955 case LE: code = LT; break;
10956 case GE: code = GT; break;
10957 case LEU: code = LT; break;
10958 case GEU: code = GT; break;
10959 default: gcc_unreachable ();
10962 compare_result2 = gen_reg_rtx (CCFPmode);
10964 /* Do the EQ. */
10965 switch (op_mode)
10967 case SFmode:
10968 cmp = flag_unsafe_math_optimizations
10969 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
10970 rs6000_compare_op1)
10971 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
10972 rs6000_compare_op1);
10973 break;
10975 case DFmode:
10976 cmp = flag_unsafe_math_optimizations
10977 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
10978 rs6000_compare_op1)
10979 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
10980 rs6000_compare_op1);
10981 break;
10983 default:
10984 gcc_unreachable ();
10986 emit_insn (cmp);
10988 /* OR them together. */
10989 or_result = gen_reg_rtx (CCFPmode);
10990 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
10991 compare_result2);
10992 compare_result = or_result;
10993 code = EQ;
10995 else
10997 if (code == NE || code == LTGT)
10998 code = NE;
10999 else
11000 code = EQ;
11003 emit_insn (cmp);
11005 else
11007 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11008 CLOBBERs to match cmptf_internal2 pattern. */
11009 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
11010 && GET_MODE (rs6000_compare_op0) == TFmode
11011 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
11012 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
11013 emit_insn (gen_rtx_PARALLEL (VOIDmode,
11014 gen_rtvec (9,
11015 gen_rtx_SET (VOIDmode,
11016 compare_result,
11017 gen_rtx_COMPARE (comp_mode,
11018 rs6000_compare_op0,
11019 rs6000_compare_op1)),
11020 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11021 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11022 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11023 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11024 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11025 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11026 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11027 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
11028 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
11029 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
11031 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
11032 comp_mode = CCEQmode;
11033 compare_result = gen_reg_rtx (CCEQmode);
11034 if (TARGET_64BIT)
11035 emit_insn (gen_stack_protect_testdi (compare_result,
11036 rs6000_compare_op0, op1));
11037 else
11038 emit_insn (gen_stack_protect_testsi (compare_result,
11039 rs6000_compare_op0, op1));
11041 else
11042 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
11043 gen_rtx_COMPARE (comp_mode,
11044 rs6000_compare_op0,
11045 rs6000_compare_op1)));
11048 /* Some kinds of FP comparisons need an OR operation;
11049 under flag_finite_math_only we don't bother. */
11050 if (rs6000_compare_fp_p
11051 && !flag_finite_math_only
11052 && !(TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)
11053 && (code == LE || code == GE
11054 || code == UNEQ || code == LTGT
11055 || code == UNGT || code == UNLT))
11057 enum rtx_code or1, or2;
11058 rtx or1_rtx, or2_rtx, compare2_rtx;
11059 rtx or_result = gen_reg_rtx (CCEQmode);
11061 switch (code)
11063 case LE: or1 = LT; or2 = EQ; break;
11064 case GE: or1 = GT; or2 = EQ; break;
11065 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
11066 case LTGT: or1 = LT; or2 = GT; break;
11067 case UNGT: or1 = UNORDERED; or2 = GT; break;
11068 case UNLT: or1 = UNORDERED; or2 = LT; break;
11069 default: gcc_unreachable ();
11071 validate_condition_mode (or1, comp_mode);
11072 validate_condition_mode (or2, comp_mode);
11073 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
11074 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
11075 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
11076 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
11077 const_true_rtx);
11078 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
11080 compare_result = or_result;
11081 code = EQ;
11084 validate_condition_mode (code, GET_MODE (compare_result));
11086 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
11090 /* Emit the RTL for an sCOND pattern. */
11092 void
11093 rs6000_emit_sCOND (enum rtx_code code, rtx result)
11095 rtx condition_rtx;
11096 enum machine_mode op_mode;
11097 enum rtx_code cond_code;
11099 condition_rtx = rs6000_generate_compare (code);
11100 cond_code = GET_CODE (condition_rtx);
11102 if (TARGET_E500 && rs6000_compare_fp_p
11103 && !TARGET_FPRS && TARGET_HARD_FLOAT)
11105 rtx t;
11107 PUT_MODE (condition_rtx, SImode);
11108 t = XEXP (condition_rtx, 0);
11110 gcc_assert (cond_code == NE || cond_code == EQ);
11112 if (cond_code == NE)
11113 emit_insn (gen_e500_flip_gt_bit (t, t));
11115 emit_insn (gen_move_from_CR_gt_bit (result, t));
11116 return;
11119 if (cond_code == NE
11120 || cond_code == GE || cond_code == LE
11121 || cond_code == GEU || cond_code == LEU
11122 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
11124 rtx not_result = gen_reg_rtx (CCEQmode);
11125 rtx not_op, rev_cond_rtx;
11126 enum machine_mode cc_mode;
11128 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
11130 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
11131 SImode, XEXP (condition_rtx, 0), const0_rtx);
11132 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
11133 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
11134 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
11137 op_mode = GET_MODE (rs6000_compare_op0);
11138 if (op_mode == VOIDmode)
11139 op_mode = GET_MODE (rs6000_compare_op1);
11141 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
11143 PUT_MODE (condition_rtx, DImode);
11144 convert_move (result, condition_rtx, 0);
11146 else
11148 PUT_MODE (condition_rtx, SImode);
11149 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
11153 /* Emit a branch of kind CODE to location LOC. */
11155 void
11156 rs6000_emit_cbranch (enum rtx_code code, rtx loc)
11158 rtx condition_rtx, loc_ref;
11160 condition_rtx = rs6000_generate_compare (code);
11161 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
11162 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
11163 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
11164 loc_ref, pc_rtx)));
11167 /* Return the string to output a conditional branch to LABEL, which is
11168 the operand number of the label, or -1 if the branch is really a
11169 conditional return.
11171 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11172 condition code register and its mode specifies what kind of
11173 comparison we made.
11175 REVERSED is nonzero if we should reverse the sense of the comparison.
11177 INSN is the insn. */
11179 char *
11180 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
11182 static char string[64];
11183 enum rtx_code code = GET_CODE (op);
11184 rtx cc_reg = XEXP (op, 0);
11185 enum machine_mode mode = GET_MODE (cc_reg);
11186 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
11187 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
11188 int really_reversed = reversed ^ need_longbranch;
11189 char *s = string;
11190 const char *ccode;
11191 const char *pred;
11192 rtx note;
11194 validate_condition_mode (code, mode);
11196 /* Work out which way this really branches. We could use
11197 reverse_condition_maybe_unordered here always but this
11198 makes the resulting assembler clearer. */
11199 if (really_reversed)
11201 /* Reversal of FP compares takes care -- an ordered compare
11202 becomes an unordered compare and vice versa. */
11203 if (mode == CCFPmode)
11204 code = reverse_condition_maybe_unordered (code);
11205 else
11206 code = reverse_condition (code);
11209 if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
11211 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11212 to the GT bit. */
11213 switch (code)
11215 case EQ:
11216 /* Opposite of GT. */
11217 code = GT;
11218 break;
11220 case NE:
11221 code = UNLE;
11222 break;
11224 default:
11225 gcc_unreachable ();
11229 switch (code)
11231 /* Not all of these are actually distinct opcodes, but
11232 we distinguish them for clarity of the resulting assembler. */
11233 case NE: case LTGT:
11234 ccode = "ne"; break;
11235 case EQ: case UNEQ:
11236 ccode = "eq"; break;
11237 case GE: case GEU:
11238 ccode = "ge"; break;
11239 case GT: case GTU: case UNGT:
11240 ccode = "gt"; break;
11241 case LE: case LEU:
11242 ccode = "le"; break;
11243 case LT: case LTU: case UNLT:
11244 ccode = "lt"; break;
11245 case UNORDERED: ccode = "un"; break;
11246 case ORDERED: ccode = "nu"; break;
11247 case UNGE: ccode = "nl"; break;
11248 case UNLE: ccode = "ng"; break;
11249 default:
11250 gcc_unreachable ();
11253 /* Maybe we have a guess as to how likely the branch is.
11254 The old mnemonics don't have a way to specify this information. */
11255 pred = "";
11256 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
11257 if (note != NULL_RTX)
11259 /* PROB is the difference from 50%. */
11260 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
11262 /* Only hint for highly probable/improbable branches on newer
11263 cpus as static prediction overrides processor dynamic
11264 prediction. For older cpus we may as well always hint, but
11265 assume not taken for branches that are very close to 50% as a
11266 mispredicted taken branch is more expensive than a
11267 mispredicted not-taken branch. */
11268 if (rs6000_always_hint
11269 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
11271 if (abs (prob) > REG_BR_PROB_BASE / 20
11272 && ((prob > 0) ^ need_longbranch))
11273 pred = "+";
11274 else
11275 pred = "-";
11279 if (label == NULL)
11280 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
11281 else
11282 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
11284 /* We need to escape any '%' characters in the reg_names string.
11285 Assume they'd only be the first character.... */
11286 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
11287 *s++ = '%';
11288 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
11290 if (label != NULL)
11292 /* If the branch distance was too far, we may have to use an
11293 unconditional branch to go the distance. */
11294 if (need_longbranch)
11295 s += sprintf (s, ",$+8\n\tb %s", label);
11296 else
11297 s += sprintf (s, ",%s", label);
11300 return string;
11303 /* Return the string to flip the GT bit on a CR. */
11304 char *
11305 output_e500_flip_gt_bit (rtx dst, rtx src)
11307 static char string[64];
11308 int a, b;
11310 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
11311 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
11313 /* GT bit. */
11314 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
11315 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
11317 sprintf (string, "crnot %d,%d", a, b);
11318 return string;
11321 /* Return insn index for the vector compare instruction for given CODE,
11322 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11323 not available. */
11325 static int
11326 get_vec_cmp_insn (enum rtx_code code,
11327 enum machine_mode dest_mode,
11328 enum machine_mode op_mode)
11330 if (!TARGET_ALTIVEC)
11331 return INSN_NOT_AVAILABLE;
11333 switch (code)
11335 case EQ:
11336 if (dest_mode == V16QImode && op_mode == V16QImode)
11337 return UNSPEC_VCMPEQUB;
11338 if (dest_mode == V8HImode && op_mode == V8HImode)
11339 return UNSPEC_VCMPEQUH;
11340 if (dest_mode == V4SImode && op_mode == V4SImode)
11341 return UNSPEC_VCMPEQUW;
11342 if (dest_mode == V4SImode && op_mode == V4SFmode)
11343 return UNSPEC_VCMPEQFP;
11344 break;
11345 case GE:
11346 if (dest_mode == V4SImode && op_mode == V4SFmode)
11347 return UNSPEC_VCMPGEFP;
11348 case GT:
11349 if (dest_mode == V16QImode && op_mode == V16QImode)
11350 return UNSPEC_VCMPGTSB;
11351 if (dest_mode == V8HImode && op_mode == V8HImode)
11352 return UNSPEC_VCMPGTSH;
11353 if (dest_mode == V4SImode && op_mode == V4SImode)
11354 return UNSPEC_VCMPGTSW;
11355 if (dest_mode == V4SImode && op_mode == V4SFmode)
11356 return UNSPEC_VCMPGTFP;
11357 break;
11358 case GTU:
11359 if (dest_mode == V16QImode && op_mode == V16QImode)
11360 return UNSPEC_VCMPGTUB;
11361 if (dest_mode == V8HImode && op_mode == V8HImode)
11362 return UNSPEC_VCMPGTUH;
11363 if (dest_mode == V4SImode && op_mode == V4SImode)
11364 return UNSPEC_VCMPGTUW;
11365 break;
11366 default:
11367 break;
11369 return INSN_NOT_AVAILABLE;
11372 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
11373 DMODE is expected destination mode. This is a recursive function. */
11375 static rtx
11376 rs6000_emit_vector_compare (enum rtx_code rcode,
11377 rtx op0, rtx op1,
11378 enum machine_mode dmode)
11380 int vec_cmp_insn;
11381 rtx mask;
11382 enum machine_mode dest_mode;
11383 enum machine_mode op_mode = GET_MODE (op1);
11385 gcc_assert (TARGET_ALTIVEC);
11386 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
11388 /* Floating point vector compare instructions uses destination V4SImode.
11389 Move destination to appropriate mode later. */
11390 if (dmode == V4SFmode)
11391 dest_mode = V4SImode;
11392 else
11393 dest_mode = dmode;
11395 mask = gen_reg_rtx (dest_mode);
11396 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11398 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
11400 bool swap_operands = false;
11401 bool try_again = false;
11402 switch (rcode)
11404 case LT:
11405 rcode = GT;
11406 swap_operands = true;
11407 try_again = true;
11408 break;
11409 case LTU:
11410 rcode = GTU;
11411 swap_operands = true;
11412 try_again = true;
11413 break;
11414 case NE:
11415 /* Treat A != B as ~(A==B). */
11417 enum insn_code nor_code;
11418 rtx eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
11419 dest_mode);
11421 nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
11422 gcc_assert (nor_code != CODE_FOR_nothing);
11423 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
11425 if (dmode != dest_mode)
11427 rtx temp = gen_reg_rtx (dest_mode);
11428 convert_move (temp, mask, 0);
11429 return temp;
11431 return mask;
11433 break;
11434 case GE:
11435 case GEU:
11436 case LE:
11437 case LEU:
11438 /* Try GT/GTU/LT/LTU OR EQ */
11440 rtx c_rtx, eq_rtx;
11441 enum insn_code ior_code;
11442 enum rtx_code new_code;
11444 switch (rcode)
11446 case GE:
11447 new_code = GT;
11448 break;
11450 case GEU:
11451 new_code = GTU;
11452 break;
11454 case LE:
11455 new_code = LT;
11456 break;
11458 case LEU:
11459 new_code = LTU;
11460 break;
11462 default:
11463 gcc_unreachable ();
11466 c_rtx = rs6000_emit_vector_compare (new_code,
11467 op0, op1, dest_mode);
11468 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
11469 dest_mode);
11471 ior_code = ior_optab->handlers[(int)dest_mode].insn_code;
11472 gcc_assert (ior_code != CODE_FOR_nothing);
11473 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
11474 if (dmode != dest_mode)
11476 rtx temp = gen_reg_rtx (dest_mode);
11477 convert_move (temp, mask, 0);
11478 return temp;
11480 return mask;
11482 break;
11483 default:
11484 gcc_unreachable ();
11487 if (try_again)
11489 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11490 /* You only get two chances. */
11491 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
11494 if (swap_operands)
11496 rtx tmp;
11497 tmp = op0;
11498 op0 = op1;
11499 op1 = tmp;
11503 emit_insn (gen_rtx_SET (VOIDmode, mask,
11504 gen_rtx_UNSPEC (dest_mode,
11505 gen_rtvec (2, op0, op1),
11506 vec_cmp_insn)));
11507 if (dmode != dest_mode)
11509 rtx temp = gen_reg_rtx (dest_mode);
11510 convert_move (temp, mask, 0);
11511 return temp;
11513 return mask;
11516 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
11517 valid insn doesn exist for given mode. */
11519 static int
11520 get_vsel_insn (enum machine_mode mode)
11522 switch (mode)
11524 case V4SImode:
11525 return UNSPEC_VSEL4SI;
11526 break;
11527 case V4SFmode:
11528 return UNSPEC_VSEL4SF;
11529 break;
11530 case V8HImode:
11531 return UNSPEC_VSEL8HI;
11532 break;
11533 case V16QImode:
11534 return UNSPEC_VSEL16QI;
11535 break;
11536 default:
11537 return INSN_NOT_AVAILABLE;
11538 break;
11540 return INSN_NOT_AVAILABLE;
11543 /* Emit vector select insn where DEST is destination using
11544 operands OP1, OP2 and MASK. */
11546 static void
11547 rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
11549 rtx t, temp;
11550 enum machine_mode dest_mode = GET_MODE (dest);
11551 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
11553 temp = gen_reg_rtx (dest_mode);
11555 /* For each vector element, select op1 when mask is 1 otherwise
11556 select op2. */
11557 t = gen_rtx_SET (VOIDmode, temp,
11558 gen_rtx_UNSPEC (dest_mode,
11559 gen_rtvec (3, op2, op1, mask),
11560 vsel_insn_index));
11561 emit_insn (t);
11562 emit_move_insn (dest, temp);
11563 return;
11566 /* Emit vector conditional expression.
11567 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
11568 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
11571 rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
11572 rtx cond, rtx cc_op0, rtx cc_op1)
11574 enum machine_mode dest_mode = GET_MODE (dest);
11575 enum rtx_code rcode = GET_CODE (cond);
11576 rtx mask;
11578 if (!TARGET_ALTIVEC)
11579 return 0;
11581 /* Get the vector mask for the given relational operations. */
11582 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
11584 rs6000_emit_vector_select (dest, op1, op2, mask);
11586 return 1;
11589 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
11590 operands of the last comparison is nonzero/true, FALSE_COND if it
11591 is zero/false. Return 0 if the hardware has no such operation. */
11594 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
11596 enum rtx_code code = GET_CODE (op);
11597 rtx op0 = rs6000_compare_op0;
11598 rtx op1 = rs6000_compare_op1;
11599 REAL_VALUE_TYPE c1;
11600 enum machine_mode compare_mode = GET_MODE (op0);
11601 enum machine_mode result_mode = GET_MODE (dest);
11602 rtx temp;
11603 bool is_against_zero;
11605 /* These modes should always match. */
11606 if (GET_MODE (op1) != compare_mode
11607 /* In the isel case however, we can use a compare immediate, so
11608 op1 may be a small constant. */
11609 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
11610 return 0;
11611 if (GET_MODE (true_cond) != result_mode)
11612 return 0;
11613 if (GET_MODE (false_cond) != result_mode)
11614 return 0;
11616 /* First, work out if the hardware can do this at all, or
11617 if it's too slow.... */
11618 if (! rs6000_compare_fp_p)
11620 if (TARGET_ISEL)
11621 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
11622 return 0;
11624 else if (TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS
11625 && GET_MODE_CLASS (compare_mode) == MODE_FLOAT)
11626 return 0;
11628 is_against_zero = op1 == CONST0_RTX (compare_mode);
11630 /* A floating-point subtract might overflow, underflow, or produce
11631 an inexact result, thus changing the floating-point flags, so it
11632 can't be generated if we care about that. It's safe if one side
11633 of the construct is zero, since then no subtract will be
11634 generated. */
11635 if (GET_MODE_CLASS (compare_mode) == MODE_FLOAT
11636 && flag_trapping_math && ! is_against_zero)
11637 return 0;
11639 /* Eliminate half of the comparisons by switching operands, this
11640 makes the remaining code simpler. */
11641 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
11642 || code == LTGT || code == LT || code == UNLE)
11644 code = reverse_condition_maybe_unordered (code);
11645 temp = true_cond;
11646 true_cond = false_cond;
11647 false_cond = temp;
11650 /* UNEQ and LTGT take four instructions for a comparison with zero,
11651 it'll probably be faster to use a branch here too. */
11652 if (code == UNEQ && HONOR_NANS (compare_mode))
11653 return 0;
11655 if (GET_CODE (op1) == CONST_DOUBLE)
11656 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
11658 /* We're going to try to implement comparisons by performing
11659 a subtract, then comparing against zero. Unfortunately,
11660 Inf - Inf is NaN which is not zero, and so if we don't
11661 know that the operand is finite and the comparison
11662 would treat EQ different to UNORDERED, we can't do it. */
11663 if (HONOR_INFINITIES (compare_mode)
11664 && code != GT && code != UNGE
11665 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
11666 /* Constructs of the form (a OP b ? a : b) are safe. */
11667 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
11668 || (! rtx_equal_p (op0, true_cond)
11669 && ! rtx_equal_p (op1, true_cond))))
11670 return 0;
11672 /* At this point we know we can use fsel. */
11674 /* Reduce the comparison to a comparison against zero. */
11675 if (! is_against_zero)
11677 temp = gen_reg_rtx (compare_mode);
11678 emit_insn (gen_rtx_SET (VOIDmode, temp,
11679 gen_rtx_MINUS (compare_mode, op0, op1)));
11680 op0 = temp;
11681 op1 = CONST0_RTX (compare_mode);
11684 /* If we don't care about NaNs we can reduce some of the comparisons
11685 down to faster ones. */
11686 if (! HONOR_NANS (compare_mode))
11687 switch (code)
11689 case GT:
11690 code = LE;
11691 temp = true_cond;
11692 true_cond = false_cond;
11693 false_cond = temp;
11694 break;
11695 case UNGE:
11696 code = GE;
11697 break;
11698 case UNEQ:
11699 code = EQ;
11700 break;
11701 default:
11702 break;
11705 /* Now, reduce everything down to a GE. */
11706 switch (code)
11708 case GE:
11709 break;
11711 case LE:
11712 temp = gen_reg_rtx (compare_mode);
11713 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
11714 op0 = temp;
11715 break;
11717 case ORDERED:
11718 temp = gen_reg_rtx (compare_mode);
11719 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
11720 op0 = temp;
11721 break;
11723 case EQ:
11724 temp = gen_reg_rtx (compare_mode);
11725 emit_insn (gen_rtx_SET (VOIDmode, temp,
11726 gen_rtx_NEG (compare_mode,
11727 gen_rtx_ABS (compare_mode, op0))));
11728 op0 = temp;
11729 break;
11731 case UNGE:
11732 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
11733 temp = gen_reg_rtx (result_mode);
11734 emit_insn (gen_rtx_SET (VOIDmode, temp,
11735 gen_rtx_IF_THEN_ELSE (result_mode,
11736 gen_rtx_GE (VOIDmode,
11737 op0, op1),
11738 true_cond, false_cond)));
11739 false_cond = true_cond;
11740 true_cond = temp;
11742 temp = gen_reg_rtx (compare_mode);
11743 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
11744 op0 = temp;
11745 break;
11747 case GT:
11748 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
11749 temp = gen_reg_rtx (result_mode);
11750 emit_insn (gen_rtx_SET (VOIDmode, temp,
11751 gen_rtx_IF_THEN_ELSE (result_mode,
11752 gen_rtx_GE (VOIDmode,
11753 op0, op1),
11754 true_cond, false_cond)));
11755 true_cond = false_cond;
11756 false_cond = temp;
11758 temp = gen_reg_rtx (compare_mode);
11759 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
11760 op0 = temp;
11761 break;
11763 default:
11764 gcc_unreachable ();
11767 emit_insn (gen_rtx_SET (VOIDmode, dest,
11768 gen_rtx_IF_THEN_ELSE (result_mode,
11769 gen_rtx_GE (VOIDmode,
11770 op0, op1),
11771 true_cond, false_cond)));
11772 return 1;
11775 /* Same as above, but for ints (isel). */
11777 static int
11778 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
11780 rtx condition_rtx, cr;
11782 /* All isel implementations thus far are 32-bits. */
11783 if (GET_MODE (rs6000_compare_op0) != SImode)
11784 return 0;
11786 /* We still have to do the compare, because isel doesn't do a
11787 compare, it just looks at the CRx bits set by a previous compare
11788 instruction. */
11789 condition_rtx = rs6000_generate_compare (GET_CODE (op));
11790 cr = XEXP (condition_rtx, 0);
11792 if (GET_MODE (cr) == CCmode)
11793 emit_insn (gen_isel_signed (dest, condition_rtx,
11794 true_cond, false_cond, cr));
11795 else
11796 emit_insn (gen_isel_unsigned (dest, condition_rtx,
11797 true_cond, false_cond, cr));
11799 return 1;
11802 const char *
11803 output_isel (rtx *operands)
11805 enum rtx_code code;
11807 code = GET_CODE (operands[1]);
11808 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
11810 PUT_CODE (operands[1], reverse_condition (code));
11811 return "isel %0,%3,%2,%j1";
11813 else
11814 return "isel %0,%2,%3,%j1";
11817 void
11818 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
11820 enum machine_mode mode = GET_MODE (op0);
11821 enum rtx_code c;
11822 rtx target;
11824 if (code == SMAX || code == SMIN)
11825 c = GE;
11826 else
11827 c = GEU;
11829 if (code == SMAX || code == UMAX)
11830 target = emit_conditional_move (dest, c, op0, op1, mode,
11831 op0, op1, mode, 0);
11832 else
11833 target = emit_conditional_move (dest, c, op0, op1, mode,
11834 op1, op0, mode, 0);
11835 gcc_assert (target);
11836 if (target != dest)
11837 emit_move_insn (dest, target);
11840 /* Emit instructions to perform a load-reserved/store-conditional operation.
11841 The operation performed is an atomic
11842 (set M (CODE:MODE M OP))
11843 If not NULL, BEFORE is atomically set to M before the operation, and
11844 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
11845 If SYNC_P then a memory barrier is emitted before the operation.
11846 Either OP or M may be wrapped in a NOT operation. */
11848 void
11849 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
11850 rtx m, rtx op, rtx before_param, rtx after_param,
11851 bool sync_p)
11853 enum machine_mode used_mode;
11854 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
11855 rtx used_m;
11856 rtvec vec;
11857 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
11858 rtx shift = NULL_RTX;
11860 if (sync_p)
11861 emit_insn (gen_memory_barrier ());
11863 if (GET_CODE (m) == NOT)
11864 used_m = XEXP (m, 0);
11865 else
11866 used_m = m;
11868 /* If this is smaller than SImode, we'll have to use SImode with
11869 adjustments. */
11870 if (mode == QImode || mode == HImode)
11872 rtx newop, oldop;
11874 if (MEM_ALIGN (used_m) >= 32)
11876 int ishift = 0;
11877 if (BYTES_BIG_ENDIAN)
11878 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
11880 shift = GEN_INT (ishift);
11882 else
11884 rtx addrSI, aligned_addr;
11885 int shift_mask = mode == QImode ? 0x18 : 0x10;
11887 addrSI = force_reg (SImode, gen_lowpart_common (SImode,
11888 XEXP (used_m, 0)));
11889 shift = gen_reg_rtx (SImode);
11891 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
11892 GEN_INT (shift_mask)));
11893 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
11895 aligned_addr = expand_binop (Pmode, and_optab,
11896 XEXP (used_m, 0),
11897 GEN_INT (-4), NULL_RTX,
11898 1, OPTAB_LIB_WIDEN);
11899 used_m = change_address (used_m, SImode, aligned_addr);
11900 set_mem_align (used_m, 32);
11901 /* It's safe to keep the old alias set of USED_M, because
11902 the operation is atomic and only affects the original
11903 USED_M. */
11904 if (GET_CODE (m) == NOT)
11905 m = gen_rtx_NOT (SImode, used_m);
11906 else
11907 m = used_m;
11910 if (GET_CODE (op) == NOT)
11912 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
11913 oldop = gen_rtx_NOT (SImode, oldop);
11915 else
11916 oldop = lowpart_subreg (SImode, op, mode);
11918 switch (code)
11920 case IOR:
11921 case XOR:
11922 newop = expand_binop (SImode, and_optab,
11923 oldop, GEN_INT (imask), NULL_RTX,
11924 1, OPTAB_LIB_WIDEN);
11925 emit_insn (gen_ashlsi3 (newop, newop, shift));
11926 break;
11928 case AND:
11929 newop = expand_binop (SImode, ior_optab,
11930 oldop, GEN_INT (~imask), NULL_RTX,
11931 1, OPTAB_LIB_WIDEN);
11932 emit_insn (gen_rotlsi3 (newop, newop, shift));
11933 break;
11935 case PLUS:
11936 case MINUS:
11938 rtx mask;
11940 newop = expand_binop (SImode, and_optab,
11941 oldop, GEN_INT (imask), NULL_RTX,
11942 1, OPTAB_LIB_WIDEN);
11943 emit_insn (gen_ashlsi3 (newop, newop, shift));
11945 mask = gen_reg_rtx (SImode);
11946 emit_move_insn (mask, GEN_INT (imask));
11947 emit_insn (gen_ashlsi3 (mask, mask, shift));
11949 if (code == PLUS)
11950 newop = gen_rtx_PLUS (SImode, m, newop);
11951 else
11952 newop = gen_rtx_MINUS (SImode, m, newop);
11953 newop = gen_rtx_AND (SImode, newop, mask);
11954 newop = gen_rtx_IOR (SImode, newop,
11955 gen_rtx_AND (SImode,
11956 gen_rtx_NOT (SImode, mask),
11957 m));
11958 break;
11961 default:
11962 gcc_unreachable ();
11965 if (GET_CODE (m) == NOT)
11967 rtx mask, xorm;
11969 mask = gen_reg_rtx (SImode);
11970 emit_move_insn (mask, GEN_INT (imask));
11971 emit_insn (gen_ashlsi3 (mask, mask, shift));
11973 xorm = gen_rtx_XOR (SImode, used_m, mask);
11974 /* Depending on the value of 'op', the XOR or the operation might
11975 be able to be simplified away. */
11976 newop = simplify_gen_binary (code, SImode, xorm, newop);
11978 op = newop;
11979 used_mode = SImode;
11980 before = gen_reg_rtx (used_mode);
11981 after = gen_reg_rtx (used_mode);
11983 else
11985 used_mode = mode;
11986 before = before_param;
11987 after = after_param;
11989 if (before == NULL_RTX)
11990 before = gen_reg_rtx (used_mode);
11991 if (after == NULL_RTX)
11992 after = gen_reg_rtx (used_mode);
11995 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
11996 && used_mode != mode)
11997 the_op = op; /* Computed above. */
11998 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
11999 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
12000 else
12001 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
12003 set_after = gen_rtx_SET (VOIDmode, after, the_op);
12004 set_before = gen_rtx_SET (VOIDmode, before, used_m);
12005 set_atomic = gen_rtx_SET (VOIDmode, used_m,
12006 gen_rtx_UNSPEC (used_mode,
12007 gen_rtvec (1, the_op),
12008 UNSPEC_SYNC_OP));
12009 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
12011 if ((code == PLUS || code == MINUS) && used_mode != mode)
12012 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
12013 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
12014 else
12015 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
12016 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
12018 /* Shift and mask the return values properly. */
12019 if (used_mode != mode && before_param)
12021 emit_insn (gen_lshrsi3 (before, before, shift));
12022 convert_move (before_param, before, 1);
12025 if (used_mode != mode && after_param)
12027 emit_insn (gen_lshrsi3 (after, after, shift));
12028 convert_move (after_param, after, 1);
12031 /* The previous sequence will end with a branch that's dependent on
12032 the conditional store, so placing an isync will ensure that no
12033 other instructions (especially, no load or store instructions)
12034 can start before the atomic operation completes. */
12035 if (sync_p)
12036 emit_insn (gen_isync ());
12039 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12040 COND is true. Mark the jump as unlikely to be taken. */
12042 static void
12043 emit_unlikely_jump (rtx cond, rtx label)
12045 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
12046 rtx x;
12048 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
12049 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
12050 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
12053 /* A subroutine of the atomic operation splitters. Emit a load-locked
12054 instruction in MODE. */
12056 static void
12057 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
12059 rtx (*fn) (rtx, rtx) = NULL;
12060 if (mode == SImode)
12061 fn = gen_load_locked_si;
12062 else if (mode == DImode)
12063 fn = gen_load_locked_di;
12064 emit_insn (fn (reg, mem));
12067 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12068 instruction in MODE. */
12070 static void
12071 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
12073 rtx (*fn) (rtx, rtx, rtx) = NULL;
12074 if (mode == SImode)
12075 fn = gen_store_conditional_si;
12076 else if (mode == DImode)
12077 fn = gen_store_conditional_di;
12079 /* Emit sync before stwcx. to address PPC405 Erratum. */
12080 if (PPC405_ERRATUM77)
12081 emit_insn (gen_memory_barrier ());
12083 emit_insn (fn (res, mem, val));
12086 /* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
12087 to perform. MEM is the memory on which to operate. VAL is the second
12088 operand of the binary operator. BEFORE and AFTER are optional locations to
12089 return the value of MEM either before of after the operation. SCRATCH is
12090 a scratch register. */
12092 void
12093 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
12094 rtx before, rtx after, rtx scratch)
12096 enum machine_mode mode = GET_MODE (mem);
12097 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12099 emit_insn (gen_memory_barrier ());
12101 label = gen_label_rtx ();
12102 emit_label (label);
12103 label = gen_rtx_LABEL_REF (VOIDmode, label);
12105 if (before == NULL_RTX)
12106 before = scratch;
12107 emit_load_locked (mode, before, mem);
12109 if (code == NOT)
12110 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
12111 else if (code == AND)
12112 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
12113 else
12114 x = gen_rtx_fmt_ee (code, mode, before, val);
12116 if (after != NULL_RTX)
12117 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
12118 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
12120 emit_store_conditional (mode, cond, mem, scratch);
12122 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12123 emit_unlikely_jump (x, label);
12125 emit_insn (gen_isync ());
12128 /* Expand an atomic compare and swap operation. MEM is the memory on which
12129 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12130 value to be stored. SCRATCH is a scratch GPR. */
12132 void
12133 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
12134 rtx scratch)
12136 enum machine_mode mode = GET_MODE (mem);
12137 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12139 emit_insn (gen_memory_barrier ());
12141 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12142 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12143 emit_label (XEXP (label1, 0));
12145 emit_load_locked (mode, retval, mem);
12147 x = gen_rtx_COMPARE (CCmode, retval, oldval);
12148 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12150 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12151 emit_unlikely_jump (x, label2);
12153 emit_move_insn (scratch, newval);
12154 emit_store_conditional (mode, cond, mem, scratch);
12156 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12157 emit_unlikely_jump (x, label1);
12159 emit_insn (gen_isync ());
12160 emit_label (XEXP (label2, 0));
12163 /* Expand an atomic test and set operation. MEM is the memory on which
12164 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12166 void
12167 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
12169 enum machine_mode mode = GET_MODE (mem);
12170 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12172 emit_insn (gen_memory_barrier ());
12174 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12175 emit_label (XEXP (label, 0));
12177 emit_load_locked (mode, retval, mem);
12178 emit_move_insn (scratch, val);
12179 emit_store_conditional (mode, cond, mem, scratch);
12181 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12182 emit_unlikely_jump (x, label);
12184 emit_insn (gen_isync ());
12187 /* Emit instructions to move SRC to DST. Called by splitters for
12188 multi-register moves. It will emit at most one instruction for
12189 each register that is accessed; that is, it won't emit li/lis pairs
12190 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12191 register. */
12193 void
12194 rs6000_split_multireg_move (rtx dst, rtx src)
12196 /* The register number of the first register being moved. */
12197 int reg;
12198 /* The mode that is to be moved. */
12199 enum machine_mode mode;
12200 /* The mode that the move is being done in, and its size. */
12201 enum machine_mode reg_mode;
12202 int reg_mode_size;
12203 /* The number of registers that will be moved. */
12204 int nregs;
12206 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
12207 mode = GET_MODE (dst);
12208 nregs = hard_regno_nregs[reg][mode];
12209 if (FP_REGNO_P (reg))
12210 reg_mode = DFmode;
12211 else if (ALTIVEC_REGNO_P (reg))
12212 reg_mode = V16QImode;
12213 else
12214 reg_mode = word_mode;
12215 reg_mode_size = GET_MODE_SIZE (reg_mode);
12217 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
12219 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
12221 /* Move register range backwards, if we might have destructive
12222 overlap. */
12223 int i;
12224 for (i = nregs - 1; i >= 0; i--)
12225 emit_insn (gen_rtx_SET (VOIDmode,
12226 simplify_gen_subreg (reg_mode, dst, mode,
12227 i * reg_mode_size),
12228 simplify_gen_subreg (reg_mode, src, mode,
12229 i * reg_mode_size)));
12231 else
12233 int i;
12234 int j = -1;
12235 bool used_update = false;
12237 if (MEM_P (src) && INT_REGNO_P (reg))
12239 rtx breg;
12241 if (GET_CODE (XEXP (src, 0)) == PRE_INC
12242 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
12244 rtx delta_rtx;
12245 breg = XEXP (XEXP (src, 0), 0);
12246 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
12247 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
12248 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
12249 emit_insn (TARGET_32BIT
12250 ? gen_addsi3 (breg, breg, delta_rtx)
12251 : gen_adddi3 (breg, breg, delta_rtx));
12252 src = gen_rtx_MEM (mode, breg);
12254 else if (! offsettable_memref_p (src))
12256 rtx newsrc, basereg;
12257 basereg = gen_rtx_REG (Pmode, reg);
12258 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
12259 newsrc = gen_rtx_MEM (GET_MODE (src), basereg);
12260 MEM_COPY_ATTRIBUTES (newsrc, src);
12261 src = newsrc;
12264 breg = XEXP (src, 0);
12265 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
12266 breg = XEXP (breg, 0);
12268 /* If the base register we are using to address memory is
12269 also a destination reg, then change that register last. */
12270 if (REG_P (breg)
12271 && REGNO (breg) >= REGNO (dst)
12272 && REGNO (breg) < REGNO (dst) + nregs)
12273 j = REGNO (breg) - REGNO (dst);
12276 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
12278 rtx breg;
12280 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
12281 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
12283 rtx delta_rtx;
12284 breg = XEXP (XEXP (dst, 0), 0);
12285 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
12286 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
12287 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
12289 /* We have to update the breg before doing the store.
12290 Use store with update, if available. */
12292 if (TARGET_UPDATE)
12294 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
12295 emit_insn (TARGET_32BIT
12296 ? (TARGET_POWERPC64
12297 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
12298 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
12299 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
12300 used_update = true;
12302 else
12303 emit_insn (TARGET_32BIT
12304 ? gen_addsi3 (breg, breg, delta_rtx)
12305 : gen_adddi3 (breg, breg, delta_rtx));
12306 dst = gen_rtx_MEM (mode, breg);
12308 else
12309 gcc_assert (offsettable_memref_p (dst));
12312 for (i = 0; i < nregs; i++)
12314 /* Calculate index to next subword. */
12315 ++j;
12316 if (j == nregs)
12317 j = 0;
12319 /* If compiler already emitted move of first word by
12320 store with update, no need to do anything. */
12321 if (j == 0 && used_update)
12322 continue;
12324 emit_insn (gen_rtx_SET (VOIDmode,
12325 simplify_gen_subreg (reg_mode, dst, mode,
12326 j * reg_mode_size),
12327 simplify_gen_subreg (reg_mode, src, mode,
12328 j * reg_mode_size)));
12334 /* This page contains routines that are used to determine what the
12335 function prologue and epilogue code will do and write them out. */
12337 /* Return the first fixed-point register that is required to be
12338 saved. 32 if none. */
12341 first_reg_to_save (void)
12343 int first_reg;
12345 /* Find lowest numbered live register. */
12346 for (first_reg = 13; first_reg <= 31; first_reg++)
12347 if (regs_ever_live[first_reg]
12348 && (! call_used_regs[first_reg]
12349 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
12350 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
12351 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
12352 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
12353 break;
12355 #if TARGET_MACHO
12356 if (flag_pic
12357 && current_function_uses_pic_offset_table
12358 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
12359 return RS6000_PIC_OFFSET_TABLE_REGNUM;
12360 #endif
12362 return first_reg;
12365 /* Similar, for FP regs. */
12368 first_fp_reg_to_save (void)
12370 int first_reg;
12372 /* Find lowest numbered live register. */
12373 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
12374 if (regs_ever_live[first_reg])
12375 break;
12377 return first_reg;
12380 /* Similar, for AltiVec regs. */
12382 static int
12383 first_altivec_reg_to_save (void)
12385 int i;
12387 /* Stack frame remains as is unless we are in AltiVec ABI. */
12388 if (! TARGET_ALTIVEC_ABI)
12389 return LAST_ALTIVEC_REGNO + 1;
12391 /* Find lowest numbered live register. */
12392 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
12393 if (regs_ever_live[i])
12394 break;
12396 return i;
12399 /* Return a 32-bit mask of the AltiVec registers we need to set in
12400 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
12401 the 32-bit word is 0. */
12403 static unsigned int
12404 compute_vrsave_mask (void)
12406 unsigned int i, mask = 0;
12408 /* First, find out if we use _any_ altivec registers. */
12409 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
12410 if (regs_ever_live[i])
12411 mask |= ALTIVEC_REG_BIT (i);
12413 if (mask == 0)
12414 return mask;
12416 /* Next, remove the argument registers from the set. These must
12417 be in the VRSAVE mask set by the caller, so we don't need to add
12418 them in again. More importantly, the mask we compute here is
12419 used to generate CLOBBERs in the set_vrsave insn, and we do not
12420 wish the argument registers to die. */
12421 for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
12422 mask &= ~ALTIVEC_REG_BIT (i);
12424 /* Similarly, remove the return value from the set. */
12426 bool yes = false;
12427 diddle_return_value (is_altivec_return_reg, &yes);
12428 if (yes)
12429 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
12432 return mask;
12435 /* For a very restricted set of circumstances, we can cut down the
12436 size of prologues/epilogues by calling our own save/restore-the-world
12437 routines. */
12439 static void
12440 compute_save_world_info (rs6000_stack_t *info_ptr)
12442 info_ptr->world_save_p = 1;
12443 info_ptr->world_save_p
12444 = (WORLD_SAVE_P (info_ptr)
12445 && DEFAULT_ABI == ABI_DARWIN
12446 && ! (current_function_calls_setjmp && flag_exceptions)
12447 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
12448 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
12449 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
12450 && info_ptr->cr_save_p);
12452 /* This will not work in conjunction with sibcalls. Make sure there
12453 are none. (This check is expensive, but seldom executed.) */
12454 if (WORLD_SAVE_P (info_ptr))
12456 rtx insn;
12457 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
12458 if ( GET_CODE (insn) == CALL_INSN
12459 && SIBLING_CALL_P (insn))
12461 info_ptr->world_save_p = 0;
12462 break;
12466 if (WORLD_SAVE_P (info_ptr))
12468 /* Even if we're not touching VRsave, make sure there's room on the
12469 stack for it, if it looks like we're calling SAVE_WORLD, which
12470 will attempt to save it. */
12471 info_ptr->vrsave_size = 4;
12473 /* "Save" the VRsave register too if we're saving the world. */
12474 if (info_ptr->vrsave_mask == 0)
12475 info_ptr->vrsave_mask = compute_vrsave_mask ();
12477 /* Because the Darwin register save/restore routines only handle
12478 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
12479 check. */
12480 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
12481 && (info_ptr->first_altivec_reg_save
12482 >= FIRST_SAVED_ALTIVEC_REGNO));
12484 return;
12488 static void
12489 is_altivec_return_reg (rtx reg, void *xyes)
12491 bool *yes = (bool *) xyes;
12492 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
12493 *yes = true;
12497 /* Calculate the stack information for the current function. This is
12498 complicated by having two separate calling sequences, the AIX calling
12499 sequence and the V.4 calling sequence.
12501 AIX (and Darwin/Mac OS X) stack frames look like:
12502 32-bit 64-bit
12503 SP----> +---------------------------------------+
12504 | back chain to caller | 0 0
12505 +---------------------------------------+
12506 | saved CR | 4 8 (8-11)
12507 +---------------------------------------+
12508 | saved LR | 8 16
12509 +---------------------------------------+
12510 | reserved for compilers | 12 24
12511 +---------------------------------------+
12512 | reserved for binders | 16 32
12513 +---------------------------------------+
12514 | saved TOC pointer | 20 40
12515 +---------------------------------------+
12516 | Parameter save area (P) | 24 48
12517 +---------------------------------------+
12518 | Alloca space (A) | 24+P etc.
12519 +---------------------------------------+
12520 | Local variable space (L) | 24+P+A
12521 +---------------------------------------+
12522 | Float/int conversion temporary (X) | 24+P+A+L
12523 +---------------------------------------+
12524 | Save area for AltiVec registers (W) | 24+P+A+L+X
12525 +---------------------------------------+
12526 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
12527 +---------------------------------------+
12528 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
12529 +---------------------------------------+
12530 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
12531 +---------------------------------------+
12532 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
12533 +---------------------------------------+
12534 old SP->| back chain to caller's caller |
12535 +---------------------------------------+
12537 The required alignment for AIX configurations is two words (i.e., 8
12538 or 16 bytes).
12541 V.4 stack frames look like:
12543 SP----> +---------------------------------------+
12544 | back chain to caller | 0
12545 +---------------------------------------+
12546 | caller's saved LR | 4
12547 +---------------------------------------+
12548 | Parameter save area (P) | 8
12549 +---------------------------------------+
12550 | Alloca space (A) | 8+P
12551 +---------------------------------------+
12552 | Varargs save area (V) | 8+P+A
12553 +---------------------------------------+
12554 | Local variable space (L) | 8+P+A+V
12555 +---------------------------------------+
12556 | Float/int conversion temporary (X) | 8+P+A+V+L
12557 +---------------------------------------+
12558 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
12559 +---------------------------------------+
12560 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
12561 +---------------------------------------+
12562 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
12563 +---------------------------------------+
12564 | SPE: area for 64-bit GP registers |
12565 +---------------------------------------+
12566 | SPE alignment padding |
12567 +---------------------------------------+
12568 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
12569 +---------------------------------------+
12570 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
12571 +---------------------------------------+
12572 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
12573 +---------------------------------------+
12574 old SP->| back chain to caller's caller |
12575 +---------------------------------------+
12577 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
12578 given. (But note below and in sysv4.h that we require only 8 and
12579 may round up the size of our stack frame anyways. The historical
12580 reason is early versions of powerpc-linux which didn't properly
12581 align the stack at program startup. A happy side-effect is that
12582 -mno-eabi libraries can be used with -meabi programs.)
12584 The EABI configuration defaults to the V.4 layout. However,
12585 the stack alignment requirements may differ. If -mno-eabi is not
12586 given, the required stack alignment is 8 bytes; if -mno-eabi is
12587 given, the required alignment is 16 bytes. (But see V.4 comment
12588 above.) */
12590 #ifndef ABI_STACK_BOUNDARY
12591 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
12592 #endif
12594 static rs6000_stack_t *
12595 rs6000_stack_info (void)
12597 static rs6000_stack_t info, zero_info;
12598 rs6000_stack_t *info_ptr = &info;
12599 int reg_size = TARGET_32BIT ? 4 : 8;
12600 int ehrd_size;
12601 int save_align;
12602 HOST_WIDE_INT non_fixed_size;
12604 /* Zero all fields portably. */
12605 info = zero_info;
12607 if (TARGET_SPE)
12609 /* Cache value so we don't rescan instruction chain over and over. */
12610 if (cfun->machine->insn_chain_scanned_p == 0)
12611 cfun->machine->insn_chain_scanned_p
12612 = spe_func_has_64bit_regs_p () + 1;
12613 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
12616 /* Select which calling sequence. */
12617 info_ptr->abi = DEFAULT_ABI;
12619 /* Calculate which registers need to be saved & save area size. */
12620 info_ptr->first_gp_reg_save = first_reg_to_save ();
12621 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
12622 even if it currently looks like we won't. */
12623 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
12624 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
12625 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
12626 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
12627 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
12628 else
12629 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
12631 /* For the SPE, we have an additional upper 32-bits on each GPR.
12632 Ideally we should save the entire 64-bits only when the upper
12633 half is used in SIMD instructions. Since we only record
12634 registers live (not the size they are used in), this proves
12635 difficult because we'd have to traverse the instruction chain at
12636 the right time, taking reload into account. This is a real pain,
12637 so we opt to save the GPRs in 64-bits always if but one register
12638 gets used in 64-bits. Otherwise, all the registers in the frame
12639 get saved in 32-bits.
12641 So... since when we save all GPRs (except the SP) in 64-bits, the
12642 traditional GP save area will be empty. */
12643 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
12644 info_ptr->gp_size = 0;
12646 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
12647 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
12649 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
12650 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
12651 - info_ptr->first_altivec_reg_save);
12653 /* Does this function call anything? */
12654 info_ptr->calls_p = (! current_function_is_leaf
12655 || cfun->machine->ra_needs_full_frame);
12657 /* Determine if we need to save the link register. */
12658 if (rs6000_ra_ever_killed ()
12659 || (DEFAULT_ABI == ABI_AIX
12660 && current_function_profile
12661 && !TARGET_PROFILE_KERNEL)
12662 #ifdef TARGET_RELOCATABLE
12663 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
12664 #endif
12665 || (info_ptr->first_fp_reg_save != 64
12666 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
12667 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
12668 || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
12669 || info_ptr->calls_p)
12671 info_ptr->lr_save_p = 1;
12672 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
12675 /* Determine if we need to save the condition code registers. */
12676 if (regs_ever_live[CR2_REGNO]
12677 || regs_ever_live[CR3_REGNO]
12678 || regs_ever_live[CR4_REGNO])
12680 info_ptr->cr_save_p = 1;
12681 if (DEFAULT_ABI == ABI_V4)
12682 info_ptr->cr_size = reg_size;
12685 /* If the current function calls __builtin_eh_return, then we need
12686 to allocate stack space for registers that will hold data for
12687 the exception handler. */
12688 if (current_function_calls_eh_return)
12690 unsigned int i;
12691 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
12692 continue;
12694 /* SPE saves EH registers in 64-bits. */
12695 ehrd_size = i * (TARGET_SPE_ABI
12696 && info_ptr->spe_64bit_regs_used != 0
12697 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
12699 else
12700 ehrd_size = 0;
12702 /* Determine various sizes. */
12703 info_ptr->reg_size = reg_size;
12704 info_ptr->fixed_size = RS6000_SAVE_AREA;
12705 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
12706 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
12707 TARGET_ALTIVEC ? 16 : 8);
12708 if (FRAME_GROWS_DOWNWARD)
12709 info_ptr->vars_size
12710 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
12711 + info_ptr->parm_size,
12712 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
12713 - (info_ptr->fixed_size + info_ptr->vars_size
12714 + info_ptr->parm_size);
12716 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
12717 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
12718 else
12719 info_ptr->spe_gp_size = 0;
12721 if (TARGET_ALTIVEC_ABI)
12722 info_ptr->vrsave_mask = compute_vrsave_mask ();
12723 else
12724 info_ptr->vrsave_mask = 0;
12726 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
12727 info_ptr->vrsave_size = 4;
12728 else
12729 info_ptr->vrsave_size = 0;
12731 compute_save_world_info (info_ptr);
12733 /* Calculate the offsets. */
12734 switch (DEFAULT_ABI)
12736 case ABI_NONE:
12737 default:
12738 gcc_unreachable ();
12740 case ABI_AIX:
12741 case ABI_DARWIN:
12742 info_ptr->fp_save_offset = - info_ptr->fp_size;
12743 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
12745 if (TARGET_ALTIVEC_ABI)
12747 info_ptr->vrsave_save_offset
12748 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
12750 /* Align stack so vector save area is on a quadword boundary. */
12751 if (info_ptr->altivec_size != 0)
12752 info_ptr->altivec_padding_size
12753 = 16 - (-info_ptr->vrsave_save_offset % 16);
12754 else
12755 info_ptr->altivec_padding_size = 0;
12757 info_ptr->altivec_save_offset
12758 = info_ptr->vrsave_save_offset
12759 - info_ptr->altivec_padding_size
12760 - info_ptr->altivec_size;
12762 /* Adjust for AltiVec case. */
12763 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
12765 else
12766 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
12767 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
12768 info_ptr->lr_save_offset = 2*reg_size;
12769 break;
12771 case ABI_V4:
12772 info_ptr->fp_save_offset = - info_ptr->fp_size;
12773 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
12774 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
12776 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
12778 /* Align stack so SPE GPR save area is aligned on a
12779 double-word boundary. */
12780 if (info_ptr->spe_gp_size != 0)
12781 info_ptr->spe_padding_size
12782 = 8 - (-info_ptr->cr_save_offset % 8);
12783 else
12784 info_ptr->spe_padding_size = 0;
12786 info_ptr->spe_gp_save_offset
12787 = info_ptr->cr_save_offset
12788 - info_ptr->spe_padding_size
12789 - info_ptr->spe_gp_size;
12791 /* Adjust for SPE case. */
12792 info_ptr->toc_save_offset
12793 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
12795 else if (TARGET_ALTIVEC_ABI)
12797 info_ptr->vrsave_save_offset
12798 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
12800 /* Align stack so vector save area is on a quadword boundary. */
12801 if (info_ptr->altivec_size != 0)
12802 info_ptr->altivec_padding_size
12803 = 16 - (-info_ptr->vrsave_save_offset % 16);
12804 else
12805 info_ptr->altivec_padding_size = 0;
12807 info_ptr->altivec_save_offset
12808 = info_ptr->vrsave_save_offset
12809 - info_ptr->altivec_padding_size
12810 - info_ptr->altivec_size;
12812 /* Adjust for AltiVec case. */
12813 info_ptr->toc_save_offset
12814 = info_ptr->altivec_save_offset - info_ptr->toc_size;
12816 else
12817 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
12818 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
12819 info_ptr->lr_save_offset = reg_size;
12820 break;
12823 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
12824 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
12825 + info_ptr->gp_size
12826 + info_ptr->altivec_size
12827 + info_ptr->altivec_padding_size
12828 + info_ptr->spe_gp_size
12829 + info_ptr->spe_padding_size
12830 + ehrd_size
12831 + info_ptr->cr_size
12832 + info_ptr->lr_size
12833 + info_ptr->vrsave_size
12834 + info_ptr->toc_size,
12835 save_align);
12837 non_fixed_size = (info_ptr->vars_size
12838 + info_ptr->parm_size
12839 + info_ptr->save_size);
12841 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
12842 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
12844 /* Determine if we need to allocate any stack frame:
12846 For AIX we need to push the stack if a frame pointer is needed
12847 (because the stack might be dynamically adjusted), if we are
12848 debugging, if we make calls, or if the sum of fp_save, gp_save,
12849 and local variables are more than the space needed to save all
12850 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
12851 + 18*8 = 288 (GPR13 reserved).
12853 For V.4 we don't have the stack cushion that AIX uses, but assume
12854 that the debugger can handle stackless frames. */
12856 if (info_ptr->calls_p)
12857 info_ptr->push_p = 1;
12859 else if (DEFAULT_ABI == ABI_V4)
12860 info_ptr->push_p = non_fixed_size != 0;
12862 else if (frame_pointer_needed)
12863 info_ptr->push_p = 1;
12865 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
12866 info_ptr->push_p = 1;
12868 else
12869 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
12871 /* Zero offsets if we're not saving those registers. */
12872 if (info_ptr->fp_size == 0)
12873 info_ptr->fp_save_offset = 0;
12875 if (info_ptr->gp_size == 0)
12876 info_ptr->gp_save_offset = 0;
12878 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
12879 info_ptr->altivec_save_offset = 0;
12881 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
12882 info_ptr->vrsave_save_offset = 0;
12884 if (! TARGET_SPE_ABI
12885 || info_ptr->spe_64bit_regs_used == 0
12886 || info_ptr->spe_gp_size == 0)
12887 info_ptr->spe_gp_save_offset = 0;
12889 if (! info_ptr->lr_save_p)
12890 info_ptr->lr_save_offset = 0;
12892 if (! info_ptr->cr_save_p)
12893 info_ptr->cr_save_offset = 0;
12895 if (! info_ptr->toc_save_p)
12896 info_ptr->toc_save_offset = 0;
12898 return info_ptr;
12901 /* Return true if the current function uses any GPRs in 64-bit SIMD
12902 mode. */
12904 static bool
12905 spe_func_has_64bit_regs_p (void)
12907 rtx insns, insn;
12909 /* Functions that save and restore all the call-saved registers will
12910 need to save/restore the registers in 64-bits. */
12911 if (current_function_calls_eh_return
12912 || current_function_calls_setjmp
12913 || current_function_has_nonlocal_goto)
12914 return true;
12916 insns = get_insns ();
12918 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
12920 if (INSN_P (insn))
12922 rtx i;
12924 /* FIXME: This should be implemented with attributes...
12926 (set_attr "spe64" "true")....then,
12927 if (get_spe64(insn)) return true;
12929 It's the only reliable way to do the stuff below. */
12931 i = PATTERN (insn);
12932 if (GET_CODE (i) == SET)
12934 enum machine_mode mode = GET_MODE (SET_SRC (i));
12936 if (SPE_VECTOR_MODE (mode))
12937 return true;
12938 if (TARGET_E500_DOUBLE && mode == DFmode)
12939 return true;
12944 return false;
12947 static void
12948 debug_stack_info (rs6000_stack_t *info)
12950 const char *abi_string;
12952 if (! info)
12953 info = rs6000_stack_info ();
12955 fprintf (stderr, "\nStack information for function %s:\n",
12956 ((current_function_decl && DECL_NAME (current_function_decl))
12957 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
12958 : "<unknown>"));
12960 switch (info->abi)
12962 default: abi_string = "Unknown"; break;
12963 case ABI_NONE: abi_string = "NONE"; break;
12964 case ABI_AIX: abi_string = "AIX"; break;
12965 case ABI_DARWIN: abi_string = "Darwin"; break;
12966 case ABI_V4: abi_string = "V.4"; break;
12969 fprintf (stderr, "\tABI = %5s\n", abi_string);
12971 if (TARGET_ALTIVEC_ABI)
12972 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
12974 if (TARGET_SPE_ABI)
12975 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
12977 if (info->first_gp_reg_save != 32)
12978 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
12980 if (info->first_fp_reg_save != 64)
12981 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
12983 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
12984 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
12985 info->first_altivec_reg_save);
12987 if (info->lr_save_p)
12988 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
12990 if (info->cr_save_p)
12991 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
12993 if (info->toc_save_p)
12994 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
12996 if (info->vrsave_mask)
12997 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
12999 if (info->push_p)
13000 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
13002 if (info->calls_p)
13003 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
13005 if (info->gp_save_offset)
13006 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
13008 if (info->fp_save_offset)
13009 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
13011 if (info->altivec_save_offset)
13012 fprintf (stderr, "\taltivec_save_offset = %5d\n",
13013 info->altivec_save_offset);
13015 if (info->spe_gp_save_offset)
13016 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
13017 info->spe_gp_save_offset);
13019 if (info->vrsave_save_offset)
13020 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
13021 info->vrsave_save_offset);
13023 if (info->lr_save_offset)
13024 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
13026 if (info->cr_save_offset)
13027 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
13029 if (info->toc_save_offset)
13030 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
13032 if (info->varargs_save_offset)
13033 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
13035 if (info->total_size)
13036 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13037 info->total_size);
13039 if (info->vars_size)
13040 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13041 info->vars_size);
13043 if (info->parm_size)
13044 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
13046 if (info->fixed_size)
13047 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
13049 if (info->gp_size)
13050 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
13052 if (info->spe_gp_size)
13053 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
13055 if (info->fp_size)
13056 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
13058 if (info->altivec_size)
13059 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
13061 if (info->vrsave_size)
13062 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
13064 if (info->altivec_padding_size)
13065 fprintf (stderr, "\taltivec_padding_size= %5d\n",
13066 info->altivec_padding_size);
13068 if (info->spe_padding_size)
13069 fprintf (stderr, "\tspe_padding_size = %5d\n",
13070 info->spe_padding_size);
13072 if (info->lr_size)
13073 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
13075 if (info->cr_size)
13076 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
13078 if (info->toc_size)
13079 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
13081 if (info->save_size)
13082 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
13084 if (info->reg_size != 4)
13085 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
13087 fprintf (stderr, "\n");
13091 rs6000_return_addr (int count, rtx frame)
13093 /* Currently we don't optimize very well between prolog and body
13094 code and for PIC code the code can be actually quite bad, so
13095 don't try to be too clever here. */
13096 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
13098 cfun->machine->ra_needs_full_frame = 1;
13100 return
13101 gen_rtx_MEM
13102 (Pmode,
13103 memory_address
13104 (Pmode,
13105 plus_constant (copy_to_reg
13106 (gen_rtx_MEM (Pmode,
13107 memory_address (Pmode, frame))),
13108 RETURN_ADDRESS_OFFSET)));
13111 cfun->machine->ra_need_lr = 1;
13112 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
13115 /* Say whether a function is a candidate for sibcall handling or not.
13116 We do not allow indirect calls to be optimized into sibling calls.
13117 Also, we can't do it if there are any vector parameters; there's
13118 nowhere to put the VRsave code so it works; note that functions with
13119 vector parameters are required to have a prototype, so the argument
13120 type info must be available here. (The tail recursion case can work
13121 with vector parameters, but there's no way to distinguish here.) */
13122 static bool
13123 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
13125 tree type;
13126 if (decl)
13128 if (TARGET_ALTIVEC_VRSAVE)
13130 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
13131 type; type = TREE_CHAIN (type))
13133 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
13134 return false;
13137 if (DEFAULT_ABI == ABI_DARWIN
13138 || (*targetm.binds_local_p) (decl))
13140 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
13142 if (!lookup_attribute ("longcall", attr_list)
13143 || lookup_attribute ("shortcall", attr_list))
13144 return true;
13147 return false;
13150 /* NULL if INSN insn is valid within a low-overhead loop.
13151 Otherwise return why doloop cannot be applied.
13152 PowerPC uses the COUNT register for branch on table instructions. */
13154 static const char *
13155 rs6000_invalid_within_doloop (rtx insn)
13157 if (CALL_P (insn))
13158 return "Function call in the loop.";
13160 if (JUMP_P (insn)
13161 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
13162 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
13163 return "Computed branch in the loop.";
13165 return NULL;
13168 static int
13169 rs6000_ra_ever_killed (void)
13171 rtx top;
13172 rtx reg;
13173 rtx insn;
13175 if (current_function_is_thunk)
13176 return 0;
13178 /* regs_ever_live has LR marked as used if any sibcalls are present,
13179 but this should not force saving and restoring in the
13180 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13181 clobbers LR, so that is inappropriate. */
13183 /* Also, the prologue can generate a store into LR that
13184 doesn't really count, like this:
13186 move LR->R0
13187 bcl to set PIC register
13188 move LR->R31
13189 move R0->LR
13191 When we're called from the epilogue, we need to avoid counting
13192 this as a store. */
13194 push_topmost_sequence ();
13195 top = get_insns ();
13196 pop_topmost_sequence ();
13197 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
13199 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
13201 if (INSN_P (insn))
13203 if (FIND_REG_INC_NOTE (insn, reg))
13204 return 1;
13205 else if (GET_CODE (insn) == CALL_INSN
13206 && !SIBLING_CALL_P (insn))
13207 return 1;
13208 else if (set_of (reg, insn) != NULL_RTX
13209 && !prologue_epilogue_contains (insn))
13210 return 1;
13213 return 0;
13216 /* Add a REG_MAYBE_DEAD note to the insn. */
13217 static void
13218 rs6000_maybe_dead (rtx insn)
13220 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
13221 const0_rtx,
13222 REG_NOTES (insn));
13225 /* Emit instructions needed to load the TOC register.
13226 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13227 a constant pool; or for SVR4 -fpic. */
13229 void
13230 rs6000_emit_load_toc_table (int fromprolog)
13232 rtx dest, insn;
13233 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
13235 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
13237 char buf[30];
13238 rtx lab, tmp1, tmp2, got, tempLR;
13240 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13241 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13242 if (flag_pic == 2)
13243 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13244 else
13245 got = rs6000_got_sym ();
13246 tmp1 = tmp2 = dest;
13247 if (!fromprolog)
13249 tmp1 = gen_reg_rtx (Pmode);
13250 tmp2 = gen_reg_rtx (Pmode);
13252 tempLR = (fromprolog
13253 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13254 : gen_reg_rtx (Pmode));
13255 insn = emit_insn (gen_load_toc_v4_PIC_1 (tempLR, lab));
13256 if (fromprolog)
13257 rs6000_maybe_dead (insn);
13258 insn = emit_move_insn (tmp1, tempLR);
13259 if (fromprolog)
13260 rs6000_maybe_dead (insn);
13261 insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
13262 if (fromprolog)
13263 rs6000_maybe_dead (insn);
13264 insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
13265 if (fromprolog)
13266 rs6000_maybe_dead (insn);
13268 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
13270 rtx tempLR = (fromprolog
13271 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13272 : gen_reg_rtx (Pmode));
13274 insn = emit_insn (gen_load_toc_v4_pic_si (tempLR));
13275 if (fromprolog)
13276 rs6000_maybe_dead (insn);
13277 insn = emit_move_insn (dest, tempLR);
13278 if (fromprolog)
13279 rs6000_maybe_dead (insn);
13281 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
13283 char buf[30];
13284 rtx tempLR = (fromprolog
13285 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13286 : gen_reg_rtx (Pmode));
13287 rtx temp0 = (fromprolog
13288 ? gen_rtx_REG (Pmode, 0)
13289 : gen_reg_rtx (Pmode));
13291 if (fromprolog)
13293 rtx symF, symL;
13295 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13296 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13298 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
13299 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13301 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
13302 symF)));
13303 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
13304 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
13305 symL,
13306 symF)));
13308 else
13310 rtx tocsym;
13312 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13313 emit_insn (gen_load_toc_v4_PIC_1b (tempLR, tocsym));
13314 emit_move_insn (dest, tempLR);
13315 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
13317 insn = emit_insn (gen_addsi3 (dest, temp0, dest));
13318 if (fromprolog)
13319 rs6000_maybe_dead (insn);
13321 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
13323 /* This is for AIX code running in non-PIC ELF32. */
13324 char buf[30];
13325 rtx realsym;
13326 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
13327 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13329 insn = emit_insn (gen_elf_high (dest, realsym));
13330 if (fromprolog)
13331 rs6000_maybe_dead (insn);
13332 insn = emit_insn (gen_elf_low (dest, dest, realsym));
13333 if (fromprolog)
13334 rs6000_maybe_dead (insn);
13336 else
13338 gcc_assert (DEFAULT_ABI == ABI_AIX);
13340 if (TARGET_32BIT)
13341 insn = emit_insn (gen_load_toc_aix_si (dest));
13342 else
13343 insn = emit_insn (gen_load_toc_aix_di (dest));
13344 if (fromprolog)
13345 rs6000_maybe_dead (insn);
13349 /* Emit instructions to restore the link register after determining where
13350 its value has been stored. */
13352 void
13353 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
13355 rs6000_stack_t *info = rs6000_stack_info ();
13356 rtx operands[2];
13358 operands[0] = source;
13359 operands[1] = scratch;
13361 if (info->lr_save_p)
13363 rtx frame_rtx = stack_pointer_rtx;
13364 HOST_WIDE_INT sp_offset = 0;
13365 rtx tmp;
13367 if (frame_pointer_needed
13368 || current_function_calls_alloca
13369 || info->total_size > 32767)
13371 emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
13372 frame_rtx = operands[1];
13374 else if (info->push_p)
13375 sp_offset = info->total_size;
13377 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
13378 tmp = gen_rtx_MEM (Pmode, tmp);
13379 emit_move_insn (tmp, operands[0]);
13381 else
13382 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
13385 static GTY(()) int set = -1;
13388 get_TOC_alias_set (void)
13390 if (set == -1)
13391 set = new_alias_set ();
13392 return set;
13395 /* This returns nonzero if the current function uses the TOC. This is
13396 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
13397 is generated by the ABI_V4 load_toc_* patterns. */
13398 #if TARGET_ELF
13399 static int
13400 uses_TOC (void)
13402 rtx insn;
13404 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
13405 if (INSN_P (insn))
13407 rtx pat = PATTERN (insn);
13408 int i;
13410 if (GET_CODE (pat) == PARALLEL)
13411 for (i = 0; i < XVECLEN (pat, 0); i++)
13413 rtx sub = XVECEXP (pat, 0, i);
13414 if (GET_CODE (sub) == USE)
13416 sub = XEXP (sub, 0);
13417 if (GET_CODE (sub) == UNSPEC
13418 && XINT (sub, 1) == UNSPEC_TOC)
13419 return 1;
13423 return 0;
13425 #endif
13428 create_TOC_reference (rtx symbol)
13430 return gen_rtx_PLUS (Pmode,
13431 gen_rtx_REG (Pmode, TOC_REGISTER),
13432 gen_rtx_CONST (Pmode,
13433 gen_rtx_MINUS (Pmode, symbol,
13434 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
13437 /* If _Unwind_* has been called from within the same module,
13438 toc register is not guaranteed to be saved to 40(1) on function
13439 entry. Save it there in that case. */
13441 void
13442 rs6000_aix_emit_builtin_unwind_init (void)
13444 rtx mem;
13445 rtx stack_top = gen_reg_rtx (Pmode);
13446 rtx opcode_addr = gen_reg_rtx (Pmode);
13447 rtx opcode = gen_reg_rtx (SImode);
13448 rtx tocompare = gen_reg_rtx (SImode);
13449 rtx no_toc_save_needed = gen_label_rtx ();
13451 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
13452 emit_move_insn (stack_top, mem);
13454 mem = gen_rtx_MEM (Pmode,
13455 gen_rtx_PLUS (Pmode, stack_top,
13456 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
13457 emit_move_insn (opcode_addr, mem);
13458 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
13459 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
13460 : 0xE8410028, SImode));
13462 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
13463 SImode, NULL_RTX, NULL_RTX,
13464 no_toc_save_needed);
13466 mem = gen_rtx_MEM (Pmode,
13467 gen_rtx_PLUS (Pmode, stack_top,
13468 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
13469 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
13470 emit_label (no_toc_save_needed);
13473 /* This ties together stack memory (MEM with an alias set of
13474 rs6000_sr_alias_set) and the change to the stack pointer. */
13476 static void
13477 rs6000_emit_stack_tie (void)
13479 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
13481 set_mem_alias_set (mem, rs6000_sr_alias_set);
13482 emit_insn (gen_stack_tie (mem));
13485 /* Emit the correct code for allocating stack space, as insns.
13486 If COPY_R12, make sure a copy of the old frame is left in r12.
13487 The generated code may use hard register 0 as a temporary. */
13489 static void
13490 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
13492 rtx insn;
13493 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
13494 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
13495 rtx todec = gen_int_mode (-size, Pmode);
13497 if (INTVAL (todec) != -size)
13499 warning (0, "stack frame too large");
13500 emit_insn (gen_trap ());
13501 return;
13504 if (current_function_limit_stack)
13506 if (REG_P (stack_limit_rtx)
13507 && REGNO (stack_limit_rtx) > 1
13508 && REGNO (stack_limit_rtx) <= 31)
13510 emit_insn (TARGET_32BIT
13511 ? gen_addsi3 (tmp_reg,
13512 stack_limit_rtx,
13513 GEN_INT (size))
13514 : gen_adddi3 (tmp_reg,
13515 stack_limit_rtx,
13516 GEN_INT (size)));
13518 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
13519 const0_rtx));
13521 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
13522 && TARGET_32BIT
13523 && DEFAULT_ABI == ABI_V4)
13525 rtx toload = gen_rtx_CONST (VOIDmode,
13526 gen_rtx_PLUS (Pmode,
13527 stack_limit_rtx,
13528 GEN_INT (size)));
13530 emit_insn (gen_elf_high (tmp_reg, toload));
13531 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
13532 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
13533 const0_rtx));
13535 else
13536 warning (0, "stack limit expression is not supported");
13539 if (copy_r12 || ! TARGET_UPDATE)
13540 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
13542 if (TARGET_UPDATE)
13544 if (size > 32767)
13546 /* Need a note here so that try_split doesn't get confused. */
13547 if (get_last_insn () == NULL_RTX)
13548 emit_note (NOTE_INSN_DELETED);
13549 insn = emit_move_insn (tmp_reg, todec);
13550 try_split (PATTERN (insn), insn, 0);
13551 todec = tmp_reg;
13554 insn = emit_insn (TARGET_32BIT
13555 ? gen_movsi_update (stack_reg, stack_reg,
13556 todec, stack_reg)
13557 : gen_movdi_di_update (stack_reg, stack_reg,
13558 todec, stack_reg));
13560 else
13562 insn = emit_insn (TARGET_32BIT
13563 ? gen_addsi3 (stack_reg, stack_reg, todec)
13564 : gen_adddi3 (stack_reg, stack_reg, todec));
13565 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
13566 gen_rtx_REG (Pmode, 12));
13569 RTX_FRAME_RELATED_P (insn) = 1;
13570 REG_NOTES (insn) =
13571 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
13572 gen_rtx_SET (VOIDmode, stack_reg,
13573 gen_rtx_PLUS (Pmode, stack_reg,
13574 GEN_INT (-size))),
13575 REG_NOTES (insn));
13578 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
13579 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
13580 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
13581 deduce these equivalences by itself so it wasn't necessary to hold
13582 its hand so much. */
13584 static void
13585 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
13586 rtx reg2, rtx rreg)
13588 rtx real, temp;
13590 /* copy_rtx will not make unique copies of registers, so we need to
13591 ensure we don't have unwanted sharing here. */
13592 if (reg == reg2)
13593 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
13595 if (reg == rreg)
13596 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
13598 real = copy_rtx (PATTERN (insn));
13600 if (reg2 != NULL_RTX)
13601 real = replace_rtx (real, reg2, rreg);
13603 real = replace_rtx (real, reg,
13604 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
13605 STACK_POINTER_REGNUM),
13606 GEN_INT (val)));
13608 /* We expect that 'real' is either a SET or a PARALLEL containing
13609 SETs (and possibly other stuff). In a PARALLEL, all the SETs
13610 are important so they all have to be marked RTX_FRAME_RELATED_P. */
13612 if (GET_CODE (real) == SET)
13614 rtx set = real;
13616 temp = simplify_rtx (SET_SRC (set));
13617 if (temp)
13618 SET_SRC (set) = temp;
13619 temp = simplify_rtx (SET_DEST (set));
13620 if (temp)
13621 SET_DEST (set) = temp;
13622 if (GET_CODE (SET_DEST (set)) == MEM)
13624 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
13625 if (temp)
13626 XEXP (SET_DEST (set), 0) = temp;
13629 else
13631 int i;
13633 gcc_assert (GET_CODE (real) == PARALLEL);
13634 for (i = 0; i < XVECLEN (real, 0); i++)
13635 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
13637 rtx set = XVECEXP (real, 0, i);
13639 temp = simplify_rtx (SET_SRC (set));
13640 if (temp)
13641 SET_SRC (set) = temp;
13642 temp = simplify_rtx (SET_DEST (set));
13643 if (temp)
13644 SET_DEST (set) = temp;
13645 if (GET_CODE (SET_DEST (set)) == MEM)
13647 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
13648 if (temp)
13649 XEXP (SET_DEST (set), 0) = temp;
13651 RTX_FRAME_RELATED_P (set) = 1;
13655 if (TARGET_SPE)
13656 real = spe_synthesize_frame_save (real);
13658 RTX_FRAME_RELATED_P (insn) = 1;
13659 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
13660 real,
13661 REG_NOTES (insn));
13664 /* Given an SPE frame note, return a PARALLEL of SETs with the
13665 original note, plus a synthetic register save. */
13667 static rtx
13668 spe_synthesize_frame_save (rtx real)
13670 rtx synth, offset, reg, real2;
13672 if (GET_CODE (real) != SET
13673 || GET_MODE (SET_SRC (real)) != V2SImode)
13674 return real;
13676 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
13677 frame related note. The parallel contains a set of the register
13678 being saved, and another set to a synthetic register (n+1200).
13679 This is so we can differentiate between 64-bit and 32-bit saves.
13680 Words cannot describe this nastiness. */
13682 gcc_assert (GET_CODE (SET_DEST (real)) == MEM
13683 && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS
13684 && GET_CODE (SET_SRC (real)) == REG);
13686 /* Transform:
13687 (set (mem (plus (reg x) (const y)))
13688 (reg z))
13689 into:
13690 (set (mem (plus (reg x) (const y+4)))
13691 (reg z+1200))
13694 real2 = copy_rtx (real);
13695 PUT_MODE (SET_DEST (real2), SImode);
13696 reg = SET_SRC (real2);
13697 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
13698 synth = copy_rtx (real2);
13700 if (BYTES_BIG_ENDIAN)
13702 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
13703 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
13706 reg = SET_SRC (synth);
13708 synth = replace_rtx (synth, reg,
13709 gen_rtx_REG (SImode, REGNO (reg) + 1200));
13711 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
13712 synth = replace_rtx (synth, offset,
13713 GEN_INT (INTVAL (offset)
13714 + (BYTES_BIG_ENDIAN ? 0 : 4)));
13716 RTX_FRAME_RELATED_P (synth) = 1;
13717 RTX_FRAME_RELATED_P (real2) = 1;
13718 if (BYTES_BIG_ENDIAN)
13719 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
13720 else
13721 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
13723 return real;
13726 /* Returns an insn that has a vrsave set operation with the
13727 appropriate CLOBBERs. */
13729 static rtx
13730 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
13732 int nclobs, i;
13733 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
13734 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
13736 clobs[0]
13737 = gen_rtx_SET (VOIDmode,
13738 vrsave,
13739 gen_rtx_UNSPEC_VOLATILE (SImode,
13740 gen_rtvec (2, reg, vrsave),
13741 UNSPECV_SET_VRSAVE));
13743 nclobs = 1;
13745 /* We need to clobber the registers in the mask so the scheduler
13746 does not move sets to VRSAVE before sets of AltiVec registers.
13748 However, if the function receives nonlocal gotos, reload will set
13749 all call saved registers live. We will end up with:
13751 (set (reg 999) (mem))
13752 (parallel [ (set (reg vrsave) (unspec blah))
13753 (clobber (reg 999))])
13755 The clobber will cause the store into reg 999 to be dead, and
13756 flow will attempt to delete an epilogue insn. In this case, we
13757 need an unspec use/set of the register. */
13759 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
13760 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
13762 if (!epiloguep || call_used_regs [i])
13763 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
13764 gen_rtx_REG (V4SImode, i));
13765 else
13767 rtx reg = gen_rtx_REG (V4SImode, i);
13769 clobs[nclobs++]
13770 = gen_rtx_SET (VOIDmode,
13771 reg,
13772 gen_rtx_UNSPEC (V4SImode,
13773 gen_rtvec (1, reg), 27));
13777 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
13779 for (i = 0; i < nclobs; ++i)
13780 XVECEXP (insn, 0, i) = clobs[i];
13782 return insn;
13785 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
13786 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
13788 static void
13789 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
13790 unsigned int regno, int offset, HOST_WIDE_INT total_size)
13792 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
13793 rtx replacea, replaceb;
13795 int_rtx = GEN_INT (offset);
13797 /* Some cases that need register indexed addressing. */
13798 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
13799 || (TARGET_E500_DOUBLE && mode == DFmode)
13800 || (TARGET_SPE_ABI
13801 && SPE_VECTOR_MODE (mode)
13802 && !SPE_CONST_OFFSET_OK (offset)))
13804 /* Whomever calls us must make sure r11 is available in the
13805 flow path of instructions in the prologue. */
13806 offset_rtx = gen_rtx_REG (Pmode, 11);
13807 emit_move_insn (offset_rtx, int_rtx);
13809 replacea = offset_rtx;
13810 replaceb = int_rtx;
13812 else
13814 offset_rtx = int_rtx;
13815 replacea = NULL_RTX;
13816 replaceb = NULL_RTX;
13819 reg = gen_rtx_REG (mode, regno);
13820 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
13821 mem = gen_rtx_MEM (mode, addr);
13822 set_mem_alias_set (mem, rs6000_sr_alias_set);
13824 insn = emit_move_insn (mem, reg);
13826 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
13829 /* Emit an offset memory reference suitable for a frame store, while
13830 converting to a valid addressing mode. */
13832 static rtx
13833 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
13835 rtx int_rtx, offset_rtx;
13837 int_rtx = GEN_INT (offset);
13839 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
13840 || (TARGET_E500_DOUBLE && mode == DFmode))
13842 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
13843 emit_move_insn (offset_rtx, int_rtx);
13845 else
13846 offset_rtx = int_rtx;
13848 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
13851 /* Look for user-defined global regs. We should not save and restore these,
13852 and cannot use stmw/lmw if there are any in its range. */
13854 static bool
13855 no_global_regs_above (int first_greg)
13857 int i;
13858 for (i = 0; i < 32 - first_greg; i++)
13859 if (global_regs[first_greg + i])
13860 return false;
13861 return true;
13864 #ifndef TARGET_FIX_AND_CONTINUE
13865 #define TARGET_FIX_AND_CONTINUE 0
13866 #endif
13868 /* Emit function prologue as insns. */
13870 void
13871 rs6000_emit_prologue (void)
13873 rs6000_stack_t *info = rs6000_stack_info ();
13874 enum machine_mode reg_mode = Pmode;
13875 int reg_size = TARGET_32BIT ? 4 : 8;
13876 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
13877 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
13878 rtx frame_reg_rtx = sp_reg_rtx;
13879 rtx cr_save_rtx = NULL_RTX;
13880 rtx insn;
13881 int saving_FPRs_inline;
13882 int using_store_multiple;
13883 HOST_WIDE_INT sp_offset = 0;
13885 if (TARGET_FIX_AND_CONTINUE)
13887 /* gdb on darwin arranges to forward a function from the old
13888 address by modifying the first 5 instructions of the function
13889 to branch to the overriding function. This is necessary to
13890 permit function pointers that point to the old function to
13891 actually forward to the new function. */
13892 emit_insn (gen_nop ());
13893 emit_insn (gen_nop ());
13894 emit_insn (gen_nop ());
13895 emit_insn (gen_nop ());
13896 emit_insn (gen_nop ());
13899 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
13901 reg_mode = V2SImode;
13902 reg_size = 8;
13905 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
13906 && (!TARGET_SPE_ABI
13907 || info->spe_64bit_regs_used == 0)
13908 && info->first_gp_reg_save < 31
13909 && no_global_regs_above (info->first_gp_reg_save));
13910 saving_FPRs_inline = (info->first_fp_reg_save == 64
13911 || FP_SAVE_INLINE (info->first_fp_reg_save)
13912 || current_function_calls_eh_return
13913 || cfun->machine->ra_need_lr);
13915 /* For V.4, update stack before we do any saving and set back pointer. */
13916 if (info->push_p
13917 && (DEFAULT_ABI == ABI_V4
13918 || current_function_calls_eh_return))
13920 if (info->total_size < 32767)
13921 sp_offset = info->total_size;
13922 else
13923 frame_reg_rtx = frame_ptr_rtx;
13924 rs6000_emit_allocate_stack (info->total_size,
13925 (frame_reg_rtx != sp_reg_rtx
13926 && (info->cr_save_p
13927 || info->lr_save_p
13928 || info->first_fp_reg_save < 64
13929 || info->first_gp_reg_save < 32
13930 )));
13931 if (frame_reg_rtx != sp_reg_rtx)
13932 rs6000_emit_stack_tie ();
13935 /* Handle world saves specially here. */
13936 if (WORLD_SAVE_P (info))
13938 int i, j, sz;
13939 rtx treg;
13940 rtvec p;
13942 /* save_world expects lr in r0. */
13943 if (info->lr_save_p)
13945 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
13946 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
13947 RTX_FRAME_RELATED_P (insn) = 1;
13950 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
13951 assumptions about the offsets of various bits of the stack
13952 frame. */
13953 gcc_assert (info->gp_save_offset == -220
13954 && info->fp_save_offset == -144
13955 && info->lr_save_offset == 8
13956 && info->cr_save_offset == 4
13957 && info->push_p
13958 && info->lr_save_p
13959 && (!current_function_calls_eh_return
13960 || info->ehrd_offset == -432)
13961 && info->vrsave_save_offset == -224
13962 && info->altivec_save_offset == (-224 -16 -192));
13964 treg = gen_rtx_REG (SImode, 11);
13965 emit_move_insn (treg, GEN_INT (-info->total_size));
13967 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
13968 in R11. It also clobbers R12, so beware! */
13970 /* Preserve CR2 for save_world prologues */
13971 sz = 6;
13972 sz += 32 - info->first_gp_reg_save;
13973 sz += 64 - info->first_fp_reg_save;
13974 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
13975 p = rtvec_alloc (sz);
13976 j = 0;
13977 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
13978 gen_rtx_REG (Pmode,
13979 LINK_REGISTER_REGNUM));
13980 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
13981 gen_rtx_SYMBOL_REF (Pmode,
13982 "*save_world"));
13983 /* We do floats first so that the instruction pattern matches
13984 properly. */
13985 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
13987 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
13988 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
13989 GEN_INT (info->fp_save_offset
13990 + sp_offset + 8 * i));
13991 rtx mem = gen_rtx_MEM (DFmode, addr);
13992 set_mem_alias_set (mem, rs6000_sr_alias_set);
13994 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
13996 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
13998 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
13999 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14000 GEN_INT (info->altivec_save_offset
14001 + sp_offset + 16 * i));
14002 rtx mem = gen_rtx_MEM (V4SImode, addr);
14003 set_mem_alias_set (mem, rs6000_sr_alias_set);
14005 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14007 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14009 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14010 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14011 GEN_INT (info->gp_save_offset
14012 + sp_offset + reg_size * i));
14013 rtx mem = gen_rtx_MEM (reg_mode, addr);
14014 set_mem_alias_set (mem, rs6000_sr_alias_set);
14016 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14020 /* CR register traditionally saved as CR2. */
14021 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14022 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14023 GEN_INT (info->cr_save_offset
14024 + sp_offset));
14025 rtx mem = gen_rtx_MEM (reg_mode, addr);
14026 set_mem_alias_set (mem, rs6000_sr_alias_set);
14028 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14030 /* Prevent any attempt to delete the setting of r0 and treg! */
14031 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 0));
14032 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, treg);
14033 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode, sp_reg_rtx);
14035 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14036 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14037 NULL_RTX, NULL_RTX);
14039 if (current_function_calls_eh_return)
14041 unsigned int i;
14042 for (i = 0; ; ++i)
14044 unsigned int regno = EH_RETURN_DATA_REGNO (i);
14045 if (regno == INVALID_REGNUM)
14046 break;
14047 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14048 info->ehrd_offset + sp_offset
14049 + reg_size * (int) i,
14050 info->total_size);
14055 /* Save AltiVec registers if needed. */
14056 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14058 int i;
14060 /* There should be a non inline version of this, for when we
14061 are saving lots of vector registers. */
14062 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14063 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14065 rtx areg, savereg, mem;
14066 int offset;
14068 offset = info->altivec_save_offset + sp_offset
14069 + 16 * (i - info->first_altivec_reg_save);
14071 savereg = gen_rtx_REG (V4SImode, i);
14073 areg = gen_rtx_REG (Pmode, 0);
14074 emit_move_insn (areg, GEN_INT (offset));
14076 /* AltiVec addressing mode is [reg+reg]. */
14077 mem = gen_rtx_MEM (V4SImode,
14078 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
14080 set_mem_alias_set (mem, rs6000_sr_alias_set);
14082 insn = emit_move_insn (mem, savereg);
14084 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14085 areg, GEN_INT (offset));
14089 /* VRSAVE is a bit vector representing which AltiVec registers
14090 are used. The OS uses this to determine which vector
14091 registers to save on a context switch. We need to save
14092 VRSAVE on the stack frame, add whatever AltiVec registers we
14093 used in this function, and do the corresponding magic in the
14094 epilogue. */
14096 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14097 && info->vrsave_mask != 0)
14099 rtx reg, mem, vrsave;
14100 int offset;
14102 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14103 as frame_reg_rtx and r11 as the static chain pointer for
14104 nested functions. */
14105 reg = gen_rtx_REG (SImode, 0);
14106 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14107 if (TARGET_MACHO)
14108 emit_insn (gen_get_vrsave_internal (reg));
14109 else
14110 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
14112 if (!WORLD_SAVE_P (info))
14114 /* Save VRSAVE. */
14115 offset = info->vrsave_save_offset + sp_offset;
14117 = gen_rtx_MEM (SImode,
14118 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
14119 set_mem_alias_set (mem, rs6000_sr_alias_set);
14120 insn = emit_move_insn (mem, reg);
14123 /* Include the registers in the mask. */
14124 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
14126 insn = emit_insn (generate_set_vrsave (reg, info, 0));
14129 /* If we use the link register, get it into r0. */
14130 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14132 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14133 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14134 RTX_FRAME_RELATED_P (insn) = 1;
14137 /* If we need to save CR, put it into r12. */
14138 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
14140 rtx set;
14142 cr_save_rtx = gen_rtx_REG (SImode, 12);
14143 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14144 RTX_FRAME_RELATED_P (insn) = 1;
14145 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14146 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14147 But that's OK. All we have to do is specify that _one_ condition
14148 code register is saved in this stack slot. The thrower's epilogue
14149 will then restore all the call-saved registers.
14150 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14151 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
14152 gen_rtx_REG (SImode, CR2_REGNO));
14153 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14154 set,
14155 REG_NOTES (insn));
14158 /* Do any required saving of fpr's. If only one or two to save, do
14159 it ourselves. Otherwise, call function. */
14160 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
14162 int i;
14163 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14164 if ((regs_ever_live[info->first_fp_reg_save+i]
14165 && ! call_used_regs[info->first_fp_reg_save+i]))
14166 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
14167 info->first_fp_reg_save + i,
14168 info->fp_save_offset + sp_offset + 8 * i,
14169 info->total_size);
14171 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
14173 int i;
14174 char rname[30];
14175 const char *alloc_rname;
14176 rtvec p;
14177 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
14179 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
14180 gen_rtx_REG (Pmode,
14181 LINK_REGISTER_REGNUM));
14182 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
14183 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
14184 alloc_rname = ggc_strdup (rname);
14185 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
14186 gen_rtx_SYMBOL_REF (Pmode,
14187 alloc_rname));
14188 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14190 rtx addr, reg, mem;
14191 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14192 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14193 GEN_INT (info->fp_save_offset
14194 + sp_offset + 8*i));
14195 mem = gen_rtx_MEM (DFmode, addr);
14196 set_mem_alias_set (mem, rs6000_sr_alias_set);
14198 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
14200 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14201 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14202 NULL_RTX, NULL_RTX);
14205 /* Save GPRs. This is done as a PARALLEL if we are using
14206 the store-multiple instructions. */
14207 if (!WORLD_SAVE_P (info) && using_store_multiple)
14209 rtvec p;
14210 int i;
14211 p = rtvec_alloc (32 - info->first_gp_reg_save);
14212 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14214 rtx addr, reg, mem;
14215 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14216 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14217 GEN_INT (info->gp_save_offset
14218 + sp_offset
14219 + reg_size * i));
14220 mem = gen_rtx_MEM (reg_mode, addr);
14221 set_mem_alias_set (mem, rs6000_sr_alias_set);
14223 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
14225 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14226 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14227 NULL_RTX, NULL_RTX);
14229 else if (!WORLD_SAVE_P (info))
14231 int i;
14232 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14233 if ((regs_ever_live[info->first_gp_reg_save + i]
14234 && (!call_used_regs[info->first_gp_reg_save + i]
14235 || (i + info->first_gp_reg_save
14236 == RS6000_PIC_OFFSET_TABLE_REGNUM
14237 && TARGET_TOC && TARGET_MINIMAL_TOC)))
14238 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14239 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14240 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
14242 rtx addr, reg, mem;
14243 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14245 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14247 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
14248 rtx b;
14250 if (!SPE_CONST_OFFSET_OK (offset))
14252 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14253 emit_move_insn (b, GEN_INT (offset));
14255 else
14256 b = GEN_INT (offset);
14258 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
14259 mem = gen_rtx_MEM (V2SImode, addr);
14260 set_mem_alias_set (mem, rs6000_sr_alias_set);
14261 insn = emit_move_insn (mem, reg);
14263 if (GET_CODE (b) == CONST_INT)
14264 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14265 NULL_RTX, NULL_RTX);
14266 else
14267 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14268 b, GEN_INT (offset));
14270 else
14272 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14273 GEN_INT (info->gp_save_offset
14274 + sp_offset
14275 + reg_size * i));
14276 mem = gen_rtx_MEM (reg_mode, addr);
14277 set_mem_alias_set (mem, rs6000_sr_alias_set);
14279 insn = emit_move_insn (mem, reg);
14280 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14281 NULL_RTX, NULL_RTX);
14286 /* ??? There's no need to emit actual instructions here, but it's the
14287 easiest way to get the frame unwind information emitted. */
14288 if (!WORLD_SAVE_P (info) && current_function_calls_eh_return)
14290 unsigned int i, regno;
14292 /* In AIX ABI we need to pretend we save r2 here. */
14293 if (TARGET_AIX)
14295 rtx addr, reg, mem;
14297 reg = gen_rtx_REG (reg_mode, 2);
14298 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14299 GEN_INT (sp_offset + 5 * reg_size));
14300 mem = gen_rtx_MEM (reg_mode, addr);
14301 set_mem_alias_set (mem, rs6000_sr_alias_set);
14303 insn = emit_move_insn (mem, reg);
14304 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14305 NULL_RTX, NULL_RTX);
14306 PATTERN (insn) = gen_blockage ();
14309 for (i = 0; ; ++i)
14311 regno = EH_RETURN_DATA_REGNO (i);
14312 if (regno == INVALID_REGNUM)
14313 break;
14315 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14316 info->ehrd_offset + sp_offset
14317 + reg_size * (int) i,
14318 info->total_size);
14322 /* Save lr if we used it. */
14323 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14325 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14326 GEN_INT (info->lr_save_offset + sp_offset));
14327 rtx reg = gen_rtx_REG (Pmode, 0);
14328 rtx mem = gen_rtx_MEM (Pmode, addr);
14329 /* This should not be of rs6000_sr_alias_set, because of
14330 __builtin_return_address. */
14332 insn = emit_move_insn (mem, reg);
14333 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14334 NULL_RTX, NULL_RTX);
14337 /* Save CR if we use any that must be preserved. */
14338 if (!WORLD_SAVE_P (info) && info->cr_save_p)
14340 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14341 GEN_INT (info->cr_save_offset + sp_offset));
14342 rtx mem = gen_rtx_MEM (SImode, addr);
14343 /* See the large comment above about why CR2_REGNO is used. */
14344 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
14346 set_mem_alias_set (mem, rs6000_sr_alias_set);
14348 /* If r12 was used to hold the original sp, copy cr into r0 now
14349 that it's free. */
14350 if (REGNO (frame_reg_rtx) == 12)
14352 rtx set;
14354 cr_save_rtx = gen_rtx_REG (SImode, 0);
14355 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14356 RTX_FRAME_RELATED_P (insn) = 1;
14357 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
14358 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14359 set,
14360 REG_NOTES (insn));
14363 insn = emit_move_insn (mem, cr_save_rtx);
14365 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14366 NULL_RTX, NULL_RTX);
14369 /* Update stack and set back pointer unless this is V.4,
14370 for which it was done previously. */
14371 if (!WORLD_SAVE_P (info) && info->push_p
14372 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
14373 rs6000_emit_allocate_stack (info->total_size, FALSE);
14375 /* Set frame pointer, if needed. */
14376 if (frame_pointer_needed)
14378 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
14379 sp_reg_rtx);
14380 RTX_FRAME_RELATED_P (insn) = 1;
14383 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
14384 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
14385 || (DEFAULT_ABI == ABI_V4
14386 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
14387 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
14389 /* If emit_load_toc_table will use the link register, we need to save
14390 it. We use R12 for this purpose because emit_load_toc_table
14391 can use register 0. This allows us to use a plain 'blr' to return
14392 from the procedure more often. */
14393 int save_LR_around_toc_setup = (TARGET_ELF
14394 && DEFAULT_ABI != ABI_AIX
14395 && flag_pic
14396 && ! info->lr_save_p
14397 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
14398 if (save_LR_around_toc_setup)
14400 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
14402 insn = emit_move_insn (frame_ptr_rtx, lr);
14403 rs6000_maybe_dead (insn);
14404 RTX_FRAME_RELATED_P (insn) = 1;
14406 rs6000_emit_load_toc_table (TRUE);
14408 insn = emit_move_insn (lr, frame_ptr_rtx);
14409 rs6000_maybe_dead (insn);
14410 RTX_FRAME_RELATED_P (insn) = 1;
14412 else
14413 rs6000_emit_load_toc_table (TRUE);
14416 #if TARGET_MACHO
14417 if (DEFAULT_ABI == ABI_DARWIN
14418 && flag_pic && current_function_uses_pic_offset_table)
14420 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
14421 rtx src = machopic_function_base_sym ();
14423 /* Save and restore LR locally around this call (in R0). */
14424 if (!info->lr_save_p)
14425 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode, 0), lr));
14427 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr, src)));
14429 insn = emit_move_insn (gen_rtx_REG (Pmode,
14430 RS6000_PIC_OFFSET_TABLE_REGNUM),
14431 lr);
14432 rs6000_maybe_dead (insn);
14434 if (!info->lr_save_p)
14435 rs6000_maybe_dead (emit_move_insn (lr, gen_rtx_REG (Pmode, 0)));
14437 #endif
14440 /* Write function prologue. */
14442 static void
14443 rs6000_output_function_prologue (FILE *file,
14444 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
14446 rs6000_stack_t *info = rs6000_stack_info ();
14448 if (TARGET_DEBUG_STACK)
14449 debug_stack_info (info);
14451 /* Write .extern for any function we will call to save and restore
14452 fp values. */
14453 if (info->first_fp_reg_save < 64
14454 && !FP_SAVE_INLINE (info->first_fp_reg_save))
14455 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
14456 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
14457 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
14458 RESTORE_FP_SUFFIX);
14460 /* Write .extern for AIX common mode routines, if needed. */
14461 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
14463 fputs ("\t.extern __mulh\n", file);
14464 fputs ("\t.extern __mull\n", file);
14465 fputs ("\t.extern __divss\n", file);
14466 fputs ("\t.extern __divus\n", file);
14467 fputs ("\t.extern __quoss\n", file);
14468 fputs ("\t.extern __quous\n", file);
14469 common_mode_defined = 1;
14472 if (! HAVE_prologue)
14474 start_sequence ();
14476 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
14477 the "toplevel" insn chain. */
14478 emit_note (NOTE_INSN_DELETED);
14479 rs6000_emit_prologue ();
14480 emit_note (NOTE_INSN_DELETED);
14482 /* Expand INSN_ADDRESSES so final() doesn't crash. */
14484 rtx insn;
14485 unsigned addr = 0;
14486 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
14488 INSN_ADDRESSES_NEW (insn, addr);
14489 addr += 4;
14493 if (TARGET_DEBUG_STACK)
14494 debug_rtx_list (get_insns (), 100);
14495 final (get_insns (), file, FALSE);
14496 end_sequence ();
14499 rs6000_pic_labelno++;
14502 /* Emit function epilogue as insns.
14504 At present, dwarf2out_frame_debug_expr doesn't understand
14505 register restores, so we don't bother setting RTX_FRAME_RELATED_P
14506 anywhere in the epilogue. Most of the insns below would in any case
14507 need special notes to explain where r11 is in relation to the stack. */
14509 void
14510 rs6000_emit_epilogue (int sibcall)
14512 rs6000_stack_t *info;
14513 int restoring_FPRs_inline;
14514 int using_load_multiple;
14515 int using_mfcr_multiple;
14516 int use_backchain_to_restore_sp;
14517 int sp_offset = 0;
14518 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
14519 rtx frame_reg_rtx = sp_reg_rtx;
14520 enum machine_mode reg_mode = Pmode;
14521 int reg_size = TARGET_32BIT ? 4 : 8;
14522 int i;
14524 info = rs6000_stack_info ();
14526 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14528 reg_mode = V2SImode;
14529 reg_size = 8;
14532 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
14533 && (!TARGET_SPE_ABI
14534 || info->spe_64bit_regs_used == 0)
14535 && info->first_gp_reg_save < 31
14536 && no_global_regs_above (info->first_gp_reg_save));
14537 restoring_FPRs_inline = (sibcall
14538 || current_function_calls_eh_return
14539 || info->first_fp_reg_save == 64
14540 || FP_SAVE_INLINE (info->first_fp_reg_save));
14541 use_backchain_to_restore_sp = (frame_pointer_needed
14542 || current_function_calls_alloca
14543 || info->total_size > 32767);
14544 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
14545 || rs6000_cpu == PROCESSOR_PPC603
14546 || rs6000_cpu == PROCESSOR_PPC750
14547 || optimize_size);
14549 if (WORLD_SAVE_P (info))
14551 int i, j;
14552 char rname[30];
14553 const char *alloc_rname;
14554 rtvec p;
14556 /* eh_rest_world_r10 will return to the location saved in the LR
14557 stack slot (which is not likely to be our caller.)
14558 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
14559 rest_world is similar, except any R10 parameter is ignored.
14560 The exception-handling stuff that was here in 2.95 is no
14561 longer necessary. */
14563 p = rtvec_alloc (9
14565 + 32 - info->first_gp_reg_save
14566 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
14567 + 63 + 1 - info->first_fp_reg_save);
14569 strcpy (rname, ((current_function_calls_eh_return) ?
14570 "*eh_rest_world_r10" : "*rest_world"));
14571 alloc_rname = ggc_strdup (rname);
14573 j = 0;
14574 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
14575 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
14576 gen_rtx_REG (Pmode,
14577 LINK_REGISTER_REGNUM));
14578 RTVEC_ELT (p, j++)
14579 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
14580 /* The instruction pattern requires a clobber here;
14581 it is shared with the restVEC helper. */
14582 RTVEC_ELT (p, j++)
14583 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
14586 /* CR register traditionally saved as CR2. */
14587 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14588 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14589 GEN_INT (info->cr_save_offset));
14590 rtx mem = gen_rtx_MEM (reg_mode, addr);
14591 set_mem_alias_set (mem, rs6000_sr_alias_set);
14593 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14596 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14598 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14599 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14600 GEN_INT (info->gp_save_offset
14601 + reg_size * i));
14602 rtx mem = gen_rtx_MEM (reg_mode, addr);
14603 set_mem_alias_set (mem, rs6000_sr_alias_set);
14605 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14607 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
14609 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
14610 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14611 GEN_INT (info->altivec_save_offset
14612 + 16 * i));
14613 rtx mem = gen_rtx_MEM (V4SImode, addr);
14614 set_mem_alias_set (mem, rs6000_sr_alias_set);
14616 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14618 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
14620 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14621 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14622 GEN_INT (info->fp_save_offset
14623 + 8 * i));
14624 rtx mem = gen_rtx_MEM (DFmode, addr);
14625 set_mem_alias_set (mem, rs6000_sr_alias_set);
14627 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14629 RTVEC_ELT (p, j++)
14630 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
14631 RTVEC_ELT (p, j++)
14632 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
14633 RTVEC_ELT (p, j++)
14634 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
14635 RTVEC_ELT (p, j++)
14636 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
14637 RTVEC_ELT (p, j++)
14638 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
14639 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
14641 return;
14644 /* If we have a frame pointer, a call to alloca, or a large stack
14645 frame, restore the old stack pointer using the backchain. Otherwise,
14646 we know what size to update it with. */
14647 if (use_backchain_to_restore_sp)
14649 /* Under V.4, don't reset the stack pointer until after we're done
14650 loading the saved registers. */
14651 if (DEFAULT_ABI == ABI_V4)
14652 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
14654 emit_move_insn (frame_reg_rtx,
14655 gen_rtx_MEM (Pmode, sp_reg_rtx));
14658 else if (info->push_p)
14660 if (DEFAULT_ABI == ABI_V4
14661 || current_function_calls_eh_return)
14662 sp_offset = info->total_size;
14663 else
14665 emit_insn (TARGET_32BIT
14666 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
14667 GEN_INT (info->total_size))
14668 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
14669 GEN_INT (info->total_size)));
14673 /* Restore AltiVec registers if needed. */
14674 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14676 int i;
14678 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14679 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14681 rtx addr, areg, mem;
14683 areg = gen_rtx_REG (Pmode, 0);
14684 emit_move_insn
14685 (areg, GEN_INT (info->altivec_save_offset
14686 + sp_offset
14687 + 16 * (i - info->first_altivec_reg_save)));
14689 /* AltiVec addressing mode is [reg+reg]. */
14690 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
14691 mem = gen_rtx_MEM (V4SImode, addr);
14692 set_mem_alias_set (mem, rs6000_sr_alias_set);
14694 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
14698 /* Restore VRSAVE if needed. */
14699 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14700 && info->vrsave_mask != 0)
14702 rtx addr, mem, reg;
14704 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14705 GEN_INT (info->vrsave_save_offset + sp_offset));
14706 mem = gen_rtx_MEM (SImode, addr);
14707 set_mem_alias_set (mem, rs6000_sr_alias_set);
14708 reg = gen_rtx_REG (SImode, 12);
14709 emit_move_insn (reg, mem);
14711 emit_insn (generate_set_vrsave (reg, info, 1));
14714 /* Get the old lr if we saved it. */
14715 if (info->lr_save_p)
14717 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
14718 info->lr_save_offset + sp_offset);
14720 set_mem_alias_set (mem, rs6000_sr_alias_set);
14722 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
14725 /* Get the old cr if we saved it. */
14726 if (info->cr_save_p)
14728 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14729 GEN_INT (info->cr_save_offset + sp_offset));
14730 rtx mem = gen_rtx_MEM (SImode, addr);
14732 set_mem_alias_set (mem, rs6000_sr_alias_set);
14734 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
14737 /* Set LR here to try to overlap restores below. */
14738 if (info->lr_save_p)
14739 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
14740 gen_rtx_REG (Pmode, 0));
14742 /* Load exception handler data registers, if needed. */
14743 if (current_function_calls_eh_return)
14745 unsigned int i, regno;
14747 if (TARGET_AIX)
14749 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14750 GEN_INT (sp_offset + 5 * reg_size));
14751 rtx mem = gen_rtx_MEM (reg_mode, addr);
14753 set_mem_alias_set (mem, rs6000_sr_alias_set);
14755 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
14758 for (i = 0; ; ++i)
14760 rtx mem;
14762 regno = EH_RETURN_DATA_REGNO (i);
14763 if (regno == INVALID_REGNUM)
14764 break;
14766 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
14767 info->ehrd_offset + sp_offset
14768 + reg_size * (int) i);
14769 set_mem_alias_set (mem, rs6000_sr_alias_set);
14771 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
14775 /* Restore GPRs. This is done as a PARALLEL if we are using
14776 the load-multiple instructions. */
14777 if (using_load_multiple)
14779 rtvec p;
14780 p = rtvec_alloc (32 - info->first_gp_reg_save);
14781 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14783 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14784 GEN_INT (info->gp_save_offset
14785 + sp_offset
14786 + reg_size * i));
14787 rtx mem = gen_rtx_MEM (reg_mode, addr);
14789 set_mem_alias_set (mem, rs6000_sr_alias_set);
14791 RTVEC_ELT (p, i) =
14792 gen_rtx_SET (VOIDmode,
14793 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
14794 mem);
14796 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14798 else
14799 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14800 if ((regs_ever_live[info->first_gp_reg_save + i]
14801 && (!call_used_regs[info->first_gp_reg_save + i]
14802 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14803 && TARGET_TOC && TARGET_MINIMAL_TOC)))
14804 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14805 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
14806 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
14808 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14809 GEN_INT (info->gp_save_offset
14810 + sp_offset
14811 + reg_size * i));
14812 rtx mem = gen_rtx_MEM (reg_mode, addr);
14814 /* Restore 64-bit quantities for SPE. */
14815 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14817 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
14818 rtx b;
14820 if (!SPE_CONST_OFFSET_OK (offset))
14822 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14823 emit_move_insn (b, GEN_INT (offset));
14825 else
14826 b = GEN_INT (offset);
14828 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
14829 mem = gen_rtx_MEM (V2SImode, addr);
14832 set_mem_alias_set (mem, rs6000_sr_alias_set);
14834 emit_move_insn (gen_rtx_REG (reg_mode,
14835 info->first_gp_reg_save + i), mem);
14838 /* Restore fpr's if we need to do it without calling a function. */
14839 if (restoring_FPRs_inline)
14840 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14841 if ((regs_ever_live[info->first_fp_reg_save+i]
14842 && ! call_used_regs[info->first_fp_reg_save+i]))
14844 rtx addr, mem;
14845 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14846 GEN_INT (info->fp_save_offset
14847 + sp_offset
14848 + 8 * i));
14849 mem = gen_rtx_MEM (DFmode, addr);
14850 set_mem_alias_set (mem, rs6000_sr_alias_set);
14852 emit_move_insn (gen_rtx_REG (DFmode,
14853 info->first_fp_reg_save + i),
14854 mem);
14857 /* If we saved cr, restore it here. Just those that were used. */
14858 if (info->cr_save_p)
14860 rtx r12_rtx = gen_rtx_REG (SImode, 12);
14861 int count = 0;
14863 if (using_mfcr_multiple)
14865 for (i = 0; i < 8; i++)
14866 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
14867 count++;
14868 gcc_assert (count);
14871 if (using_mfcr_multiple && count > 1)
14873 rtvec p;
14874 int ndx;
14876 p = rtvec_alloc (count);
14878 ndx = 0;
14879 for (i = 0; i < 8; i++)
14880 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
14882 rtvec r = rtvec_alloc (2);
14883 RTVEC_ELT (r, 0) = r12_rtx;
14884 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
14885 RTVEC_ELT (p, ndx) =
14886 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
14887 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
14888 ndx++;
14890 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14891 gcc_assert (ndx == count);
14893 else
14894 for (i = 0; i < 8; i++)
14895 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
14897 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
14898 CR0_REGNO+i),
14899 r12_rtx));
14903 /* If this is V.4, unwind the stack pointer after all of the loads
14904 have been done. We need to emit a block here so that sched
14905 doesn't decide to move the sp change before the register restores
14906 (which may not have any obvious dependency on the stack). This
14907 doesn't hurt performance, because there is no scheduling that can
14908 be done after this point. */
14909 if (DEFAULT_ABI == ABI_V4
14910 || current_function_calls_eh_return)
14912 if (frame_reg_rtx != sp_reg_rtx)
14913 rs6000_emit_stack_tie ();
14915 if (use_backchain_to_restore_sp)
14917 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
14919 else if (sp_offset != 0)
14921 emit_insn (TARGET_32BIT
14922 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
14923 GEN_INT (sp_offset))
14924 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
14925 GEN_INT (sp_offset)));
14929 if (current_function_calls_eh_return)
14931 rtx sa = EH_RETURN_STACKADJ_RTX;
14932 emit_insn (TARGET_32BIT
14933 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
14934 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
14937 if (!sibcall)
14939 rtvec p;
14940 if (! restoring_FPRs_inline)
14941 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
14942 else
14943 p = rtvec_alloc (2);
14945 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
14946 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
14947 gen_rtx_REG (Pmode,
14948 LINK_REGISTER_REGNUM));
14950 /* If we have to restore more than two FP registers, branch to the
14951 restore function. It will return to our caller. */
14952 if (! restoring_FPRs_inline)
14954 int i;
14955 char rname[30];
14956 const char *alloc_rname;
14958 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
14959 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
14960 alloc_rname = ggc_strdup (rname);
14961 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
14962 gen_rtx_SYMBOL_REF (Pmode,
14963 alloc_rname));
14965 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14967 rtx addr, mem;
14968 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
14969 GEN_INT (info->fp_save_offset + 8*i));
14970 mem = gen_rtx_MEM (DFmode, addr);
14971 set_mem_alias_set (mem, rs6000_sr_alias_set);
14973 RTVEC_ELT (p, i+3) =
14974 gen_rtx_SET (VOIDmode,
14975 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
14976 mem);
14980 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
14984 /* Write function epilogue. */
14986 static void
14987 rs6000_output_function_epilogue (FILE *file,
14988 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
14990 rs6000_stack_t *info = rs6000_stack_info ();
14992 if (! HAVE_epilogue)
14994 rtx insn = get_last_insn ();
14995 /* If the last insn was a BARRIER, we don't have to write anything except
14996 the trace table. */
14997 if (GET_CODE (insn) == NOTE)
14998 insn = prev_nonnote_insn (insn);
14999 if (insn == 0 || GET_CODE (insn) != BARRIER)
15001 /* This is slightly ugly, but at least we don't have two
15002 copies of the epilogue-emitting code. */
15003 start_sequence ();
15005 /* A NOTE_INSN_DELETED is supposed to be at the start
15006 and end of the "toplevel" insn chain. */
15007 emit_note (NOTE_INSN_DELETED);
15008 rs6000_emit_epilogue (FALSE);
15009 emit_note (NOTE_INSN_DELETED);
15011 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15013 rtx insn;
15014 unsigned addr = 0;
15015 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15017 INSN_ADDRESSES_NEW (insn, addr);
15018 addr += 4;
15022 if (TARGET_DEBUG_STACK)
15023 debug_rtx_list (get_insns (), 100);
15024 final (get_insns (), file, FALSE);
15025 end_sequence ();
15029 #if TARGET_MACHO
15030 macho_branch_islands ();
15031 /* Mach-O doesn't support labels at the end of objects, so if
15032 it looks like we might want one, insert a NOP. */
15034 rtx insn = get_last_insn ();
15035 while (insn
15036 && NOTE_P (insn)
15037 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL)
15038 insn = PREV_INSN (insn);
15039 if (insn
15040 && (LABEL_P (insn)
15041 || (NOTE_P (insn)
15042 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
15043 fputs ("\tnop\n", file);
15045 #endif
15047 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15048 on its format.
15050 We don't output a traceback table if -finhibit-size-directive was
15051 used. The documentation for -finhibit-size-directive reads
15052 ``don't output a @code{.size} assembler directive, or anything
15053 else that would cause trouble if the function is split in the
15054 middle, and the two halves are placed at locations far apart in
15055 memory.'' The traceback table has this property, since it
15056 includes the offset from the start of the function to the
15057 traceback table itself.
15059 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15060 different traceback table. */
15061 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
15062 && rs6000_traceback != traceback_none)
15064 const char *fname = NULL;
15065 const char *language_string = lang_hooks.name;
15066 int fixed_parms = 0, float_parms = 0, parm_info = 0;
15067 int i;
15068 int optional_tbtab;
15070 if (rs6000_traceback == traceback_full)
15071 optional_tbtab = 1;
15072 else if (rs6000_traceback == traceback_part)
15073 optional_tbtab = 0;
15074 else
15075 optional_tbtab = !optimize_size && !TARGET_ELF;
15077 if (optional_tbtab)
15079 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
15080 while (*fname == '.') /* V.4 encodes . in the name */
15081 fname++;
15083 /* Need label immediately before tbtab, so we can compute
15084 its offset from the function start. */
15085 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15086 ASM_OUTPUT_LABEL (file, fname);
15089 /* The .tbtab pseudo-op can only be used for the first eight
15090 expressions, since it can't handle the possibly variable
15091 length fields that follow. However, if you omit the optional
15092 fields, the assembler outputs zeros for all optional fields
15093 anyways, giving each variable length field is minimum length
15094 (as defined in sys/debug.h). Thus we can not use the .tbtab
15095 pseudo-op at all. */
15097 /* An all-zero word flags the start of the tbtab, for debuggers
15098 that have to find it by searching forward from the entry
15099 point or from the current pc. */
15100 fputs ("\t.long 0\n", file);
15102 /* Tbtab format type. Use format type 0. */
15103 fputs ("\t.byte 0,", file);
15105 /* Language type. Unfortunately, there does not seem to be any
15106 official way to discover the language being compiled, so we
15107 use language_string.
15108 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15109 Java is 13. Objective-C is 14. */
15110 if (! strcmp (language_string, "GNU C"))
15111 i = 0;
15112 else if (! strcmp (language_string, "GNU F77")
15113 || ! strcmp (language_string, "GNU F95"))
15114 i = 1;
15115 else if (! strcmp (language_string, "GNU Pascal"))
15116 i = 2;
15117 else if (! strcmp (language_string, "GNU Ada"))
15118 i = 3;
15119 else if (! strcmp (language_string, "GNU C++"))
15120 i = 9;
15121 else if (! strcmp (language_string, "GNU Java"))
15122 i = 13;
15123 else if (! strcmp (language_string, "GNU Objective-C"))
15124 i = 14;
15125 else
15126 gcc_unreachable ();
15127 fprintf (file, "%d,", i);
15129 /* 8 single bit fields: global linkage (not set for C extern linkage,
15130 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15131 from start of procedure stored in tbtab, internal function, function
15132 has controlled storage, function has no toc, function uses fp,
15133 function logs/aborts fp operations. */
15134 /* Assume that fp operations are used if any fp reg must be saved. */
15135 fprintf (file, "%d,",
15136 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
15138 /* 6 bitfields: function is interrupt handler, name present in
15139 proc table, function calls alloca, on condition directives
15140 (controls stack walks, 3 bits), saves condition reg, saves
15141 link reg. */
15142 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15143 set up as a frame pointer, even when there is no alloca call. */
15144 fprintf (file, "%d,",
15145 ((optional_tbtab << 6)
15146 | ((optional_tbtab & frame_pointer_needed) << 5)
15147 | (info->cr_save_p << 1)
15148 | (info->lr_save_p)));
15150 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15151 (6 bits). */
15152 fprintf (file, "%d,",
15153 (info->push_p << 7) | (64 - info->first_fp_reg_save));
15155 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15156 fprintf (file, "%d,", (32 - first_reg_to_save ()));
15158 if (optional_tbtab)
15160 /* Compute the parameter info from the function decl argument
15161 list. */
15162 tree decl;
15163 int next_parm_info_bit = 31;
15165 for (decl = DECL_ARGUMENTS (current_function_decl);
15166 decl; decl = TREE_CHAIN (decl))
15168 rtx parameter = DECL_INCOMING_RTL (decl);
15169 enum machine_mode mode = GET_MODE (parameter);
15171 if (GET_CODE (parameter) == REG)
15173 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
15175 int bits;
15177 float_parms++;
15179 switch (mode)
15181 case SFmode:
15182 bits = 0x2;
15183 break;
15185 case DFmode:
15186 case TFmode:
15187 bits = 0x3;
15188 break;
15190 default:
15191 gcc_unreachable ();
15194 /* If only one bit will fit, don't or in this entry. */
15195 if (next_parm_info_bit > 0)
15196 parm_info |= (bits << (next_parm_info_bit - 1));
15197 next_parm_info_bit -= 2;
15199 else
15201 fixed_parms += ((GET_MODE_SIZE (mode)
15202 + (UNITS_PER_WORD - 1))
15203 / UNITS_PER_WORD);
15204 next_parm_info_bit -= 1;
15210 /* Number of fixed point parameters. */
15211 /* This is actually the number of words of fixed point parameters; thus
15212 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15213 fprintf (file, "%d,", fixed_parms);
15215 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15216 all on stack. */
15217 /* This is actually the number of fp registers that hold parameters;
15218 and thus the maximum value is 13. */
15219 /* Set parameters on stack bit if parameters are not in their original
15220 registers, regardless of whether they are on the stack? Xlc
15221 seems to set the bit when not optimizing. */
15222 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
15224 if (! optional_tbtab)
15225 return;
15227 /* Optional fields follow. Some are variable length. */
15229 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15230 11 double float. */
15231 /* There is an entry for each parameter in a register, in the order that
15232 they occur in the parameter list. Any intervening arguments on the
15233 stack are ignored. If the list overflows a long (max possible length
15234 34 bits) then completely leave off all elements that don't fit. */
15235 /* Only emit this long if there was at least one parameter. */
15236 if (fixed_parms || float_parms)
15237 fprintf (file, "\t.long %d\n", parm_info);
15239 /* Offset from start of code to tb table. */
15240 fputs ("\t.long ", file);
15241 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15242 if (TARGET_AIX)
15243 RS6000_OUTPUT_BASENAME (file, fname);
15244 else
15245 assemble_name (file, fname);
15246 putc ('-', file);
15247 rs6000_output_function_entry (file, fname);
15248 putc ('\n', file);
15250 /* Interrupt handler mask. */
15251 /* Omit this long, since we never set the interrupt handler bit
15252 above. */
15254 /* Number of CTL (controlled storage) anchors. */
15255 /* Omit this long, since the has_ctl bit is never set above. */
15257 /* Displacement into stack of each CTL anchor. */
15258 /* Omit this list of longs, because there are no CTL anchors. */
15260 /* Length of function name. */
15261 if (*fname == '*')
15262 ++fname;
15263 fprintf (file, "\t.short %d\n", (int) strlen (fname));
15265 /* Function name. */
15266 assemble_string (fname, strlen (fname));
15268 /* Register for alloca automatic storage; this is always reg 31.
15269 Only emit this if the alloca bit was set above. */
15270 if (frame_pointer_needed)
15271 fputs ("\t.byte 31\n", file);
15273 fputs ("\t.align 2\n", file);
15277 /* A C compound statement that outputs the assembler code for a thunk
15278 function, used to implement C++ virtual function calls with
15279 multiple inheritance. The thunk acts as a wrapper around a virtual
15280 function, adjusting the implicit object parameter before handing
15281 control off to the real function.
15283 First, emit code to add the integer DELTA to the location that
15284 contains the incoming first argument. Assume that this argument
15285 contains a pointer, and is the one used to pass the `this' pointer
15286 in C++. This is the incoming argument *before* the function
15287 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15288 values of all other incoming arguments.
15290 After the addition, emit code to jump to FUNCTION, which is a
15291 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15292 not touch the return address. Hence returning from FUNCTION will
15293 return to whoever called the current `thunk'.
15295 The effect must be as if FUNCTION had been called directly with the
15296 adjusted first argument. This macro is responsible for emitting
15297 all of the code for a thunk function; output_function_prologue()
15298 and output_function_epilogue() are not invoked.
15300 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15301 been extracted from it.) It might possibly be useful on some
15302 targets, but probably not.
15304 If you do not define this macro, the target-independent code in the
15305 C++ frontend will generate a less efficient heavyweight thunk that
15306 calls FUNCTION instead of jumping to it. The generic approach does
15307 not support varargs. */
15309 static void
15310 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
15311 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
15312 tree function)
15314 rtx this, insn, funexp;
15316 reload_completed = 1;
15317 epilogue_completed = 1;
15318 no_new_pseudos = 1;
15319 reset_block_changes ();
15321 /* Mark the end of the (empty) prologue. */
15322 emit_note (NOTE_INSN_PROLOGUE_END);
15324 /* Find the "this" pointer. If the function returns a structure,
15325 the structure return pointer is in r3. */
15326 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
15327 this = gen_rtx_REG (Pmode, 4);
15328 else
15329 this = gen_rtx_REG (Pmode, 3);
15331 /* Apply the constant offset, if required. */
15332 if (delta)
15334 rtx delta_rtx = GEN_INT (delta);
15335 emit_insn (TARGET_32BIT
15336 ? gen_addsi3 (this, this, delta_rtx)
15337 : gen_adddi3 (this, this, delta_rtx));
15340 /* Apply the offset from the vtable, if required. */
15341 if (vcall_offset)
15343 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
15344 rtx tmp = gen_rtx_REG (Pmode, 12);
15346 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
15347 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
15349 emit_insn (TARGET_32BIT
15350 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
15351 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
15352 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
15354 else
15356 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
15358 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
15360 emit_insn (TARGET_32BIT
15361 ? gen_addsi3 (this, this, tmp)
15362 : gen_adddi3 (this, this, tmp));
15365 /* Generate a tail call to the target function. */
15366 if (!TREE_USED (function))
15368 assemble_external (function);
15369 TREE_USED (function) = 1;
15371 funexp = XEXP (DECL_RTL (function), 0);
15372 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
15374 #if TARGET_MACHO
15375 if (MACHOPIC_INDIRECT)
15376 funexp = machopic_indirect_call_target (funexp);
15377 #endif
15379 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
15380 generate sibcall RTL explicitly. */
15381 insn = emit_call_insn (
15382 gen_rtx_PARALLEL (VOIDmode,
15383 gen_rtvec (4,
15384 gen_rtx_CALL (VOIDmode,
15385 funexp, const0_rtx),
15386 gen_rtx_USE (VOIDmode, const0_rtx),
15387 gen_rtx_USE (VOIDmode,
15388 gen_rtx_REG (SImode,
15389 LINK_REGISTER_REGNUM)),
15390 gen_rtx_RETURN (VOIDmode))));
15391 SIBLING_CALL_P (insn) = 1;
15392 emit_barrier ();
15394 /* Run just enough of rest_of_compilation to get the insns emitted.
15395 There's not really enough bulk here to make other passes such as
15396 instruction scheduling worth while. Note that use_thunk calls
15397 assemble_start_function and assemble_end_function. */
15398 insn = get_insns ();
15399 insn_locators_initialize ();
15400 shorten_branches (insn);
15401 final_start_function (insn, file, 1);
15402 final (insn, file, 1);
15403 final_end_function ();
15405 reload_completed = 0;
15406 epilogue_completed = 0;
15407 no_new_pseudos = 0;
15410 /* A quick summary of the various types of 'constant-pool tables'
15411 under PowerPC:
15413 Target Flags Name One table per
15414 AIX (none) AIX TOC object file
15415 AIX -mfull-toc AIX TOC object file
15416 AIX -mminimal-toc AIX minimal TOC translation unit
15417 SVR4/EABI (none) SVR4 SDATA object file
15418 SVR4/EABI -fpic SVR4 pic object file
15419 SVR4/EABI -fPIC SVR4 PIC translation unit
15420 SVR4/EABI -mrelocatable EABI TOC function
15421 SVR4/EABI -maix AIX TOC object file
15422 SVR4/EABI -maix -mminimal-toc
15423 AIX minimal TOC translation unit
15425 Name Reg. Set by entries contains:
15426 made by addrs? fp? sum?
15428 AIX TOC 2 crt0 as Y option option
15429 AIX minimal TOC 30 prolog gcc Y Y option
15430 SVR4 SDATA 13 crt0 gcc N Y N
15431 SVR4 pic 30 prolog ld Y not yet N
15432 SVR4 PIC 30 prolog gcc Y option option
15433 EABI TOC 30 prolog gcc Y option option
15437 /* Hash functions for the hash table. */
15439 static unsigned
15440 rs6000_hash_constant (rtx k)
15442 enum rtx_code code = GET_CODE (k);
15443 enum machine_mode mode = GET_MODE (k);
15444 unsigned result = (code << 3) ^ mode;
15445 const char *format;
15446 int flen, fidx;
15448 format = GET_RTX_FORMAT (code);
15449 flen = strlen (format);
15450 fidx = 0;
15452 switch (code)
15454 case LABEL_REF:
15455 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
15457 case CONST_DOUBLE:
15458 if (mode != VOIDmode)
15459 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
15460 flen = 2;
15461 break;
15463 case CODE_LABEL:
15464 fidx = 3;
15465 break;
15467 default:
15468 break;
15471 for (; fidx < flen; fidx++)
15472 switch (format[fidx])
15474 case 's':
15476 unsigned i, len;
15477 const char *str = XSTR (k, fidx);
15478 len = strlen (str);
15479 result = result * 613 + len;
15480 for (i = 0; i < len; i++)
15481 result = result * 613 + (unsigned) str[i];
15482 break;
15484 case 'u':
15485 case 'e':
15486 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
15487 break;
15488 case 'i':
15489 case 'n':
15490 result = result * 613 + (unsigned) XINT (k, fidx);
15491 break;
15492 case 'w':
15493 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
15494 result = result * 613 + (unsigned) XWINT (k, fidx);
15495 else
15497 size_t i;
15498 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
15499 result = result * 613 + (unsigned) (XWINT (k, fidx)
15500 >> CHAR_BIT * i);
15502 break;
15503 case '0':
15504 break;
15505 default:
15506 gcc_unreachable ();
15509 return result;
15512 static unsigned
15513 toc_hash_function (const void *hash_entry)
15515 const struct toc_hash_struct *thc =
15516 (const struct toc_hash_struct *) hash_entry;
15517 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
15520 /* Compare H1 and H2 for equivalence. */
15522 static int
15523 toc_hash_eq (const void *h1, const void *h2)
15525 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
15526 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
15528 if (((const struct toc_hash_struct *) h1)->key_mode
15529 != ((const struct toc_hash_struct *) h2)->key_mode)
15530 return 0;
15532 return rtx_equal_p (r1, r2);
15535 /* These are the names given by the C++ front-end to vtables, and
15536 vtable-like objects. Ideally, this logic should not be here;
15537 instead, there should be some programmatic way of inquiring as
15538 to whether or not an object is a vtable. */
15540 #define VTABLE_NAME_P(NAME) \
15541 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
15542 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
15543 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
15544 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
15545 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
15547 void
15548 rs6000_output_symbol_ref (FILE *file, rtx x)
15550 /* Currently C++ toc references to vtables can be emitted before it
15551 is decided whether the vtable is public or private. If this is
15552 the case, then the linker will eventually complain that there is
15553 a reference to an unknown section. Thus, for vtables only,
15554 we emit the TOC reference to reference the symbol and not the
15555 section. */
15556 const char *name = XSTR (x, 0);
15558 if (VTABLE_NAME_P (name))
15560 RS6000_OUTPUT_BASENAME (file, name);
15562 else
15563 assemble_name (file, name);
15566 /* Output a TOC entry. We derive the entry name from what is being
15567 written. */
15569 void
15570 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
15572 char buf[256];
15573 const char *name = buf;
15574 const char *real_name;
15575 rtx base = x;
15576 int offset = 0;
15578 gcc_assert (!TARGET_NO_TOC);
15580 /* When the linker won't eliminate them, don't output duplicate
15581 TOC entries (this happens on AIX if there is any kind of TOC,
15582 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
15583 CODE_LABELs. */
15584 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
15586 struct toc_hash_struct *h;
15587 void * * found;
15589 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
15590 time because GGC is not initialized at that point. */
15591 if (toc_hash_table == NULL)
15592 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
15593 toc_hash_eq, NULL);
15595 h = ggc_alloc (sizeof (*h));
15596 h->key = x;
15597 h->key_mode = mode;
15598 h->labelno = labelno;
15600 found = htab_find_slot (toc_hash_table, h, 1);
15601 if (*found == NULL)
15602 *found = h;
15603 else /* This is indeed a duplicate.
15604 Set this label equal to that label. */
15606 fputs ("\t.set ", file);
15607 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
15608 fprintf (file, "%d,", labelno);
15609 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
15610 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
15611 found)->labelno));
15612 return;
15616 /* If we're going to put a double constant in the TOC, make sure it's
15617 aligned properly when strict alignment is on. */
15618 if (GET_CODE (x) == CONST_DOUBLE
15619 && STRICT_ALIGNMENT
15620 && GET_MODE_BITSIZE (mode) >= 64
15621 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
15622 ASM_OUTPUT_ALIGN (file, 3);
15625 (*targetm.asm_out.internal_label) (file, "LC", labelno);
15627 /* Handle FP constants specially. Note that if we have a minimal
15628 TOC, things we put here aren't actually in the TOC, so we can allow
15629 FP constants. */
15630 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
15632 REAL_VALUE_TYPE rv;
15633 long k[4];
15635 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
15636 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
15638 if (TARGET_64BIT)
15640 if (TARGET_MINIMAL_TOC)
15641 fputs (DOUBLE_INT_ASM_OP, file);
15642 else
15643 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15644 k[0] & 0xffffffff, k[1] & 0xffffffff,
15645 k[2] & 0xffffffff, k[3] & 0xffffffff);
15646 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
15647 k[0] & 0xffffffff, k[1] & 0xffffffff,
15648 k[2] & 0xffffffff, k[3] & 0xffffffff);
15649 return;
15651 else
15653 if (TARGET_MINIMAL_TOC)
15654 fputs ("\t.long ", file);
15655 else
15656 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15657 k[0] & 0xffffffff, k[1] & 0xffffffff,
15658 k[2] & 0xffffffff, k[3] & 0xffffffff);
15659 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
15660 k[0] & 0xffffffff, k[1] & 0xffffffff,
15661 k[2] & 0xffffffff, k[3] & 0xffffffff);
15662 return;
15665 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
15667 REAL_VALUE_TYPE rv;
15668 long k[2];
15670 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
15671 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
15673 if (TARGET_64BIT)
15675 if (TARGET_MINIMAL_TOC)
15676 fputs (DOUBLE_INT_ASM_OP, file);
15677 else
15678 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
15679 k[0] & 0xffffffff, k[1] & 0xffffffff);
15680 fprintf (file, "0x%lx%08lx\n",
15681 k[0] & 0xffffffff, k[1] & 0xffffffff);
15682 return;
15684 else
15686 if (TARGET_MINIMAL_TOC)
15687 fputs ("\t.long ", file);
15688 else
15689 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
15690 k[0] & 0xffffffff, k[1] & 0xffffffff);
15691 fprintf (file, "0x%lx,0x%lx\n",
15692 k[0] & 0xffffffff, k[1] & 0xffffffff);
15693 return;
15696 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
15698 REAL_VALUE_TYPE rv;
15699 long l;
15701 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
15702 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
15704 if (TARGET_64BIT)
15706 if (TARGET_MINIMAL_TOC)
15707 fputs (DOUBLE_INT_ASM_OP, file);
15708 else
15709 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
15710 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
15711 return;
15713 else
15715 if (TARGET_MINIMAL_TOC)
15716 fputs ("\t.long ", file);
15717 else
15718 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
15719 fprintf (file, "0x%lx\n", l & 0xffffffff);
15720 return;
15723 else if (GET_MODE (x) == VOIDmode
15724 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
15726 unsigned HOST_WIDE_INT low;
15727 HOST_WIDE_INT high;
15729 if (GET_CODE (x) == CONST_DOUBLE)
15731 low = CONST_DOUBLE_LOW (x);
15732 high = CONST_DOUBLE_HIGH (x);
15734 else
15735 #if HOST_BITS_PER_WIDE_INT == 32
15737 low = INTVAL (x);
15738 high = (low & 0x80000000) ? ~0 : 0;
15740 #else
15742 low = INTVAL (x) & 0xffffffff;
15743 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
15745 #endif
15747 /* TOC entries are always Pmode-sized, but since this
15748 is a bigendian machine then if we're putting smaller
15749 integer constants in the TOC we have to pad them.
15750 (This is still a win over putting the constants in
15751 a separate constant pool, because then we'd have
15752 to have both a TOC entry _and_ the actual constant.)
15754 For a 32-bit target, CONST_INT values are loaded and shifted
15755 entirely within `low' and can be stored in one TOC entry. */
15757 /* It would be easy to make this work, but it doesn't now. */
15758 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
15760 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
15762 #if HOST_BITS_PER_WIDE_INT == 32
15763 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
15764 POINTER_SIZE, &low, &high, 0);
15765 #else
15766 low |= high << 32;
15767 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
15768 high = (HOST_WIDE_INT) low >> 32;
15769 low &= 0xffffffff;
15770 #endif
15773 if (TARGET_64BIT)
15775 if (TARGET_MINIMAL_TOC)
15776 fputs (DOUBLE_INT_ASM_OP, file);
15777 else
15778 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
15779 (long) high & 0xffffffff, (long) low & 0xffffffff);
15780 fprintf (file, "0x%lx%08lx\n",
15781 (long) high & 0xffffffff, (long) low & 0xffffffff);
15782 return;
15784 else
15786 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
15788 if (TARGET_MINIMAL_TOC)
15789 fputs ("\t.long ", file);
15790 else
15791 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
15792 (long) high & 0xffffffff, (long) low & 0xffffffff);
15793 fprintf (file, "0x%lx,0x%lx\n",
15794 (long) high & 0xffffffff, (long) low & 0xffffffff);
15796 else
15798 if (TARGET_MINIMAL_TOC)
15799 fputs ("\t.long ", file);
15800 else
15801 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
15802 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
15804 return;
15808 if (GET_CODE (x) == CONST)
15810 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
15812 base = XEXP (XEXP (x, 0), 0);
15813 offset = INTVAL (XEXP (XEXP (x, 0), 1));
15816 switch (GET_CODE (base))
15818 case SYMBOL_REF:
15819 name = XSTR (base, 0);
15820 break;
15822 case LABEL_REF:
15823 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
15824 CODE_LABEL_NUMBER (XEXP (base, 0)));
15825 break;
15827 case CODE_LABEL:
15828 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
15829 break;
15831 default:
15832 gcc_unreachable ();
15835 real_name = (*targetm.strip_name_encoding) (name);
15836 if (TARGET_MINIMAL_TOC)
15837 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
15838 else
15840 fprintf (file, "\t.tc %s", real_name);
15842 if (offset < 0)
15843 fprintf (file, ".N%d", - offset);
15844 else if (offset)
15845 fprintf (file, ".P%d", offset);
15847 fputs ("[TC],", file);
15850 /* Currently C++ toc references to vtables can be emitted before it
15851 is decided whether the vtable is public or private. If this is
15852 the case, then the linker will eventually complain that there is
15853 a TOC reference to an unknown section. Thus, for vtables only,
15854 we emit the TOC reference to reference the symbol and not the
15855 section. */
15856 if (VTABLE_NAME_P (name))
15858 RS6000_OUTPUT_BASENAME (file, name);
15859 if (offset < 0)
15860 fprintf (file, "%d", offset);
15861 else if (offset > 0)
15862 fprintf (file, "+%d", offset);
15864 else
15865 output_addr_const (file, x);
15866 putc ('\n', file);
15869 /* Output an assembler pseudo-op to write an ASCII string of N characters
15870 starting at P to FILE.
15872 On the RS/6000, we have to do this using the .byte operation and
15873 write out special characters outside the quoted string.
15874 Also, the assembler is broken; very long strings are truncated,
15875 so we must artificially break them up early. */
15877 void
15878 output_ascii (FILE *file, const char *p, int n)
15880 char c;
15881 int i, count_string;
15882 const char *for_string = "\t.byte \"";
15883 const char *for_decimal = "\t.byte ";
15884 const char *to_close = NULL;
15886 count_string = 0;
15887 for (i = 0; i < n; i++)
15889 c = *p++;
15890 if (c >= ' ' && c < 0177)
15892 if (for_string)
15893 fputs (for_string, file);
15894 putc (c, file);
15896 /* Write two quotes to get one. */
15897 if (c == '"')
15899 putc (c, file);
15900 ++count_string;
15903 for_string = NULL;
15904 for_decimal = "\"\n\t.byte ";
15905 to_close = "\"\n";
15906 ++count_string;
15908 if (count_string >= 512)
15910 fputs (to_close, file);
15912 for_string = "\t.byte \"";
15913 for_decimal = "\t.byte ";
15914 to_close = NULL;
15915 count_string = 0;
15918 else
15920 if (for_decimal)
15921 fputs (for_decimal, file);
15922 fprintf (file, "%d", c);
15924 for_string = "\n\t.byte \"";
15925 for_decimal = ", ";
15926 to_close = "\n";
15927 count_string = 0;
15931 /* Now close the string if we have written one. Then end the line. */
15932 if (to_close)
15933 fputs (to_close, file);
15936 /* Generate a unique section name for FILENAME for a section type
15937 represented by SECTION_DESC. Output goes into BUF.
15939 SECTION_DESC can be any string, as long as it is different for each
15940 possible section type.
15942 We name the section in the same manner as xlc. The name begins with an
15943 underscore followed by the filename (after stripping any leading directory
15944 names) with the last period replaced by the string SECTION_DESC. If
15945 FILENAME does not contain a period, SECTION_DESC is appended to the end of
15946 the name. */
15948 void
15949 rs6000_gen_section_name (char **buf, const char *filename,
15950 const char *section_desc)
15952 const char *q, *after_last_slash, *last_period = 0;
15953 char *p;
15954 int len;
15956 after_last_slash = filename;
15957 for (q = filename; *q; q++)
15959 if (*q == '/')
15960 after_last_slash = q + 1;
15961 else if (*q == '.')
15962 last_period = q;
15965 len = strlen (after_last_slash) + strlen (section_desc) + 2;
15966 *buf = (char *) xmalloc (len);
15968 p = *buf;
15969 *p++ = '_';
15971 for (q = after_last_slash; *q; q++)
15973 if (q == last_period)
15975 strcpy (p, section_desc);
15976 p += strlen (section_desc);
15977 break;
15980 else if (ISALNUM (*q))
15981 *p++ = *q;
15984 if (last_period == 0)
15985 strcpy (p, section_desc);
15986 else
15987 *p = '\0';
15990 /* Emit profile function. */
15992 void
15993 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
15995 /* Non-standard profiling for kernels, which just saves LR then calls
15996 _mcount without worrying about arg saves. The idea is to change
15997 the function prologue as little as possible as it isn't easy to
15998 account for arg save/restore code added just for _mcount. */
15999 if (TARGET_PROFILE_KERNEL)
16000 return;
16002 if (DEFAULT_ABI == ABI_AIX)
16004 #ifndef NO_PROFILE_COUNTERS
16005 # define NO_PROFILE_COUNTERS 0
16006 #endif
16007 if (NO_PROFILE_COUNTERS)
16008 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
16009 else
16011 char buf[30];
16012 const char *label_name;
16013 rtx fun;
16015 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16016 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
16017 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
16019 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
16020 fun, Pmode);
16023 else if (DEFAULT_ABI == ABI_DARWIN)
16025 const char *mcount_name = RS6000_MCOUNT;
16026 int caller_addr_regno = LINK_REGISTER_REGNUM;
16028 /* Be conservative and always set this, at least for now. */
16029 current_function_uses_pic_offset_table = 1;
16031 #if TARGET_MACHO
16032 /* For PIC code, set up a stub and collect the caller's address
16033 from r0, which is where the prologue puts it. */
16034 if (MACHOPIC_INDIRECT
16035 && current_function_uses_pic_offset_table)
16036 caller_addr_regno = 0;
16037 #endif
16038 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
16039 0, VOIDmode, 1,
16040 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
16044 /* Write function profiler code. */
16046 void
16047 output_function_profiler (FILE *file, int labelno)
16049 char buf[100];
16051 switch (DEFAULT_ABI)
16053 default:
16054 gcc_unreachable ();
16056 case ABI_V4:
16057 if (!TARGET_32BIT)
16059 warning (0, "no profiling of 64-bit code for this ABI");
16060 return;
16062 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16063 fprintf (file, "\tmflr %s\n", reg_names[0]);
16064 if (NO_PROFILE_COUNTERS)
16066 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16067 reg_names[0], reg_names[1]);
16069 else if (TARGET_SECURE_PLT && flag_pic)
16071 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16072 reg_names[0], reg_names[1]);
16073 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16074 asm_fprintf (file, "\t{cau|addis} %s,%s,",
16075 reg_names[12], reg_names[12]);
16076 assemble_name (file, buf);
16077 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
16078 assemble_name (file, buf);
16079 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
16081 else if (flag_pic == 1)
16083 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
16084 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16085 reg_names[0], reg_names[1]);
16086 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16087 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
16088 assemble_name (file, buf);
16089 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
16091 else if (flag_pic > 1)
16093 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16094 reg_names[0], reg_names[1]);
16095 /* Now, we need to get the address of the label. */
16096 fputs ("\tbcl 20,31,1f\n\t.long ", file);
16097 assemble_name (file, buf);
16098 fputs ("-.\n1:", file);
16099 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
16100 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
16101 reg_names[0], reg_names[11]);
16102 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
16103 reg_names[0], reg_names[0], reg_names[11]);
16105 else
16107 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
16108 assemble_name (file, buf);
16109 fputs ("@ha\n", file);
16110 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16111 reg_names[0], reg_names[1]);
16112 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
16113 assemble_name (file, buf);
16114 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
16117 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16118 fprintf (file, "\tbl %s%s\n",
16119 RS6000_MCOUNT, flag_pic ? "@plt" : "");
16120 break;
16122 case ABI_AIX:
16123 case ABI_DARWIN:
16124 if (!TARGET_PROFILE_KERNEL)
16126 /* Don't do anything, done in output_profile_hook (). */
16128 else
16130 gcc_assert (!TARGET_32BIT);
16132 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
16133 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
16135 if (cfun->static_chain_decl != NULL)
16137 asm_fprintf (file, "\tstd %s,24(%s)\n",
16138 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16139 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16140 asm_fprintf (file, "\tld %s,24(%s)\n",
16141 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16143 else
16144 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16146 break;
16151 /* Power4 load update and store update instructions are cracked into a
16152 load or store and an integer insn which are executed in the same cycle.
16153 Branches have their own dispatch slot which does not count against the
16154 GCC issue rate, but it changes the program flow so there are no other
16155 instructions to issue in this cycle. */
16157 static int
16158 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
16159 int verbose ATTRIBUTE_UNUSED,
16160 rtx insn, int more)
16162 if (GET_CODE (PATTERN (insn)) == USE
16163 || GET_CODE (PATTERN (insn)) == CLOBBER)
16164 return more;
16166 if (rs6000_sched_groups)
16168 if (is_microcoded_insn (insn))
16169 return 0;
16170 else if (is_cracked_insn (insn))
16171 return more > 2 ? more - 2 : 0;
16174 return more - 1;
16177 /* Adjust the cost of a scheduling dependency. Return the new cost of
16178 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16180 static int
16181 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
16183 if (! recog_memoized (insn))
16184 return 0;
16186 if (REG_NOTE_KIND (link) != 0)
16187 return 0;
16189 if (REG_NOTE_KIND (link) == 0)
16191 /* Data dependency; DEP_INSN writes a register that INSN reads
16192 some cycles later. */
16194 /* Separate a load from a narrower, dependent store. */
16195 if (rs6000_sched_groups
16196 && GET_CODE (PATTERN (insn)) == SET
16197 && GET_CODE (PATTERN (dep_insn)) == SET
16198 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
16199 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
16200 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
16201 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
16202 return cost + 14;
16204 switch (get_attr_type (insn))
16206 case TYPE_JMPREG:
16207 /* Tell the first scheduling pass about the latency between
16208 a mtctr and bctr (and mtlr and br/blr). The first
16209 scheduling pass will not know about this latency since
16210 the mtctr instruction, which has the latency associated
16211 to it, will be generated by reload. */
16212 return TARGET_POWER ? 5 : 4;
16213 case TYPE_BRANCH:
16214 /* Leave some extra cycles between a compare and its
16215 dependent branch, to inhibit expensive mispredicts. */
16216 if ((rs6000_cpu_attr == CPU_PPC603
16217 || rs6000_cpu_attr == CPU_PPC604
16218 || rs6000_cpu_attr == CPU_PPC604E
16219 || rs6000_cpu_attr == CPU_PPC620
16220 || rs6000_cpu_attr == CPU_PPC630
16221 || rs6000_cpu_attr == CPU_PPC750
16222 || rs6000_cpu_attr == CPU_PPC7400
16223 || rs6000_cpu_attr == CPU_PPC7450
16224 || rs6000_cpu_attr == CPU_POWER4
16225 || rs6000_cpu_attr == CPU_POWER5)
16226 && recog_memoized (dep_insn)
16227 && (INSN_CODE (dep_insn) >= 0)
16228 && (get_attr_type (dep_insn) == TYPE_CMP
16229 || get_attr_type (dep_insn) == TYPE_COMPARE
16230 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
16231 || get_attr_type (dep_insn) == TYPE_IMUL_COMPARE
16232 || get_attr_type (dep_insn) == TYPE_LMUL_COMPARE
16233 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
16234 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL
16235 || get_attr_type (dep_insn) == TYPE_DELAYED_CR))
16236 return cost + 2;
16237 default:
16238 break;
16240 /* Fall out to return default cost. */
16243 return cost;
16246 /* The function returns a true if INSN is microcoded.
16247 Return false otherwise. */
16249 static bool
16250 is_microcoded_insn (rtx insn)
16252 if (!insn || !INSN_P (insn)
16253 || GET_CODE (PATTERN (insn)) == USE
16254 || GET_CODE (PATTERN (insn)) == CLOBBER)
16255 return false;
16257 if (rs6000_sched_groups)
16259 enum attr_type type = get_attr_type (insn);
16260 if (type == TYPE_LOAD_EXT_U
16261 || type == TYPE_LOAD_EXT_UX
16262 || type == TYPE_LOAD_UX
16263 || type == TYPE_STORE_UX
16264 || type == TYPE_MFCR)
16265 return true;
16268 return false;
16271 /* The function returns a nonzero value if INSN can be scheduled only
16272 as the first insn in a dispatch group ("dispatch-slot restricted").
16273 In this case, the returned value indicates how many dispatch slots
16274 the insn occupies (at the beginning of the group).
16275 Return 0 otherwise. */
16277 static int
16278 is_dispatch_slot_restricted (rtx insn)
16280 enum attr_type type;
16282 if (!rs6000_sched_groups)
16283 return 0;
16285 if (!insn
16286 || insn == NULL_RTX
16287 || GET_CODE (insn) == NOTE
16288 || GET_CODE (PATTERN (insn)) == USE
16289 || GET_CODE (PATTERN (insn)) == CLOBBER)
16290 return 0;
16292 type = get_attr_type (insn);
16294 switch (type)
16296 case TYPE_MFCR:
16297 case TYPE_MFCRF:
16298 case TYPE_MTCR:
16299 case TYPE_DELAYED_CR:
16300 case TYPE_CR_LOGICAL:
16301 case TYPE_MTJMPR:
16302 case TYPE_MFJMPR:
16303 return 1;
16304 case TYPE_IDIV:
16305 case TYPE_LDIV:
16306 return 2;
16307 case TYPE_LOAD_L:
16308 case TYPE_STORE_C:
16309 case TYPE_ISYNC:
16310 case TYPE_SYNC:
16311 return 4;
16312 default:
16313 if (rs6000_cpu == PROCESSOR_POWER5
16314 && is_cracked_insn (insn))
16315 return 2;
16316 return 0;
16320 /* The function returns true if INSN is cracked into 2 instructions
16321 by the processor (and therefore occupies 2 issue slots). */
16323 static bool
16324 is_cracked_insn (rtx insn)
16326 if (!insn || !INSN_P (insn)
16327 || GET_CODE (PATTERN (insn)) == USE
16328 || GET_CODE (PATTERN (insn)) == CLOBBER)
16329 return false;
16331 if (rs6000_sched_groups)
16333 enum attr_type type = get_attr_type (insn);
16334 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
16335 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
16336 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
16337 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
16338 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
16339 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
16340 || type == TYPE_IDIV || type == TYPE_LDIV
16341 || type == TYPE_INSERT_WORD)
16342 return true;
16345 return false;
16348 /* The function returns true if INSN can be issued only from
16349 the branch slot. */
16351 static bool
16352 is_branch_slot_insn (rtx insn)
16354 if (!insn || !INSN_P (insn)
16355 || GET_CODE (PATTERN (insn)) == USE
16356 || GET_CODE (PATTERN (insn)) == CLOBBER)
16357 return false;
16359 if (rs6000_sched_groups)
16361 enum attr_type type = get_attr_type (insn);
16362 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
16363 return true;
16364 return false;
16367 return false;
16370 /* A C statement (sans semicolon) to update the integer scheduling
16371 priority INSN_PRIORITY (INSN). Increase the priority to execute the
16372 INSN earlier, reduce the priority to execute INSN later. Do not
16373 define this macro if you do not need to adjust the scheduling
16374 priorities of insns. */
16376 static int
16377 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
16379 /* On machines (like the 750) which have asymmetric integer units,
16380 where one integer unit can do multiply and divides and the other
16381 can't, reduce the priority of multiply/divide so it is scheduled
16382 before other integer operations. */
16384 #if 0
16385 if (! INSN_P (insn))
16386 return priority;
16388 if (GET_CODE (PATTERN (insn)) == USE)
16389 return priority;
16391 switch (rs6000_cpu_attr) {
16392 case CPU_PPC750:
16393 switch (get_attr_type (insn))
16395 default:
16396 break;
16398 case TYPE_IMUL:
16399 case TYPE_IDIV:
16400 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
16401 priority, priority);
16402 if (priority >= 0 && priority < 0x01000000)
16403 priority >>= 3;
16404 break;
16407 #endif
16409 if (is_dispatch_slot_restricted (insn)
16410 && reload_completed
16411 && current_sched_info->sched_max_insns_priority
16412 && rs6000_sched_restricted_insns_priority)
16415 /* Prioritize insns that can be dispatched only in the first
16416 dispatch slot. */
16417 if (rs6000_sched_restricted_insns_priority == 1)
16418 /* Attach highest priority to insn. This means that in
16419 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
16420 precede 'priority' (critical path) considerations. */
16421 return current_sched_info->sched_max_insns_priority;
16422 else if (rs6000_sched_restricted_insns_priority == 2)
16423 /* Increase priority of insn by a minimal amount. This means that in
16424 haifa-sched.c:ready_sort(), only 'priority' (critical path)
16425 considerations precede dispatch-slot restriction considerations. */
16426 return (priority + 1);
16429 return priority;
16432 /* Return how many instructions the machine can issue per cycle. */
16434 static int
16435 rs6000_issue_rate (void)
16437 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
16438 if (!reload_completed)
16439 return 1;
16441 switch (rs6000_cpu_attr) {
16442 case CPU_RIOS1: /* ? */
16443 case CPU_RS64A:
16444 case CPU_PPC601: /* ? */
16445 case CPU_PPC7450:
16446 return 3;
16447 case CPU_PPC440:
16448 case CPU_PPC603:
16449 case CPU_PPC750:
16450 case CPU_PPC7400:
16451 case CPU_PPC8540:
16452 return 2;
16453 case CPU_RIOS2:
16454 case CPU_PPC604:
16455 case CPU_PPC604E:
16456 case CPU_PPC620:
16457 case CPU_PPC630:
16458 return 4;
16459 case CPU_POWER4:
16460 case CPU_POWER5:
16461 return 5;
16462 default:
16463 return 1;
16467 /* Return how many instructions to look ahead for better insn
16468 scheduling. */
16470 static int
16471 rs6000_use_sched_lookahead (void)
16473 if (rs6000_cpu_attr == CPU_PPC8540)
16474 return 4;
16475 return 0;
16478 /* Determine is PAT refers to memory. */
16480 static bool
16481 is_mem_ref (rtx pat)
16483 const char * fmt;
16484 int i, j;
16485 bool ret = false;
16487 if (GET_CODE (pat) == MEM)
16488 return true;
16490 /* Recursively process the pattern. */
16491 fmt = GET_RTX_FORMAT (GET_CODE (pat));
16493 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
16495 if (fmt[i] == 'e')
16496 ret |= is_mem_ref (XEXP (pat, i));
16497 else if (fmt[i] == 'E')
16498 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
16499 ret |= is_mem_ref (XVECEXP (pat, i, j));
16502 return ret;
16505 /* Determine if PAT is a PATTERN of a load insn. */
16507 static bool
16508 is_load_insn1 (rtx pat)
16510 if (!pat || pat == NULL_RTX)
16511 return false;
16513 if (GET_CODE (pat) == SET)
16514 return is_mem_ref (SET_SRC (pat));
16516 if (GET_CODE (pat) == PARALLEL)
16518 int i;
16520 for (i = 0; i < XVECLEN (pat, 0); i++)
16521 if (is_load_insn1 (XVECEXP (pat, 0, i)))
16522 return true;
16525 return false;
16528 /* Determine if INSN loads from memory. */
16530 static bool
16531 is_load_insn (rtx insn)
16533 if (!insn || !INSN_P (insn))
16534 return false;
16536 if (GET_CODE (insn) == CALL_INSN)
16537 return false;
16539 return is_load_insn1 (PATTERN (insn));
16542 /* Determine if PAT is a PATTERN of a store insn. */
16544 static bool
16545 is_store_insn1 (rtx pat)
16547 if (!pat || pat == NULL_RTX)
16548 return false;
16550 if (GET_CODE (pat) == SET)
16551 return is_mem_ref (SET_DEST (pat));
16553 if (GET_CODE (pat) == PARALLEL)
16555 int i;
16557 for (i = 0; i < XVECLEN (pat, 0); i++)
16558 if (is_store_insn1 (XVECEXP (pat, 0, i)))
16559 return true;
16562 return false;
16565 /* Determine if INSN stores to memory. */
16567 static bool
16568 is_store_insn (rtx insn)
16570 if (!insn || !INSN_P (insn))
16571 return false;
16573 return is_store_insn1 (PATTERN (insn));
16576 /* Returns whether the dependence between INSN and NEXT is considered
16577 costly by the given target. */
16579 static bool
16580 rs6000_is_costly_dependence (rtx insn, rtx next, rtx link, int cost,
16581 int distance)
16583 /* If the flag is not enabled - no dependence is considered costly;
16584 allow all dependent insns in the same group.
16585 This is the most aggressive option. */
16586 if (rs6000_sched_costly_dep == no_dep_costly)
16587 return false;
16589 /* If the flag is set to 1 - a dependence is always considered costly;
16590 do not allow dependent instructions in the same group.
16591 This is the most conservative option. */
16592 if (rs6000_sched_costly_dep == all_deps_costly)
16593 return true;
16595 if (rs6000_sched_costly_dep == store_to_load_dep_costly
16596 && is_load_insn (next)
16597 && is_store_insn (insn))
16598 /* Prevent load after store in the same group. */
16599 return true;
16601 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
16602 && is_load_insn (next)
16603 && is_store_insn (insn)
16604 && (!link || (int) REG_NOTE_KIND (link) == 0))
16605 /* Prevent load after store in the same group if it is a true
16606 dependence. */
16607 return true;
16609 /* The flag is set to X; dependences with latency >= X are considered costly,
16610 and will not be scheduled in the same group. */
16611 if (rs6000_sched_costly_dep <= max_dep_latency
16612 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
16613 return true;
16615 return false;
16618 /* Return the next insn after INSN that is found before TAIL is reached,
16619 skipping any "non-active" insns - insns that will not actually occupy
16620 an issue slot. Return NULL_RTX if such an insn is not found. */
16622 static rtx
16623 get_next_active_insn (rtx insn, rtx tail)
16625 rtx next_insn;
16627 if (!insn || insn == tail)
16628 return NULL_RTX;
16630 next_insn = NEXT_INSN (insn);
16632 while (next_insn
16633 && next_insn != tail
16634 && (GET_CODE (next_insn) == NOTE
16635 || GET_CODE (PATTERN (next_insn)) == USE
16636 || GET_CODE (PATTERN (next_insn)) == CLOBBER))
16638 next_insn = NEXT_INSN (next_insn);
16641 if (!next_insn || next_insn == tail)
16642 return NULL_RTX;
16644 return next_insn;
16647 /* Return whether the presence of INSN causes a dispatch group termination
16648 of group WHICH_GROUP.
16650 If WHICH_GROUP == current_group, this function will return true if INSN
16651 causes the termination of the current group (i.e, the dispatch group to
16652 which INSN belongs). This means that INSN will be the last insn in the
16653 group it belongs to.
16655 If WHICH_GROUP == previous_group, this function will return true if INSN
16656 causes the termination of the previous group (i.e, the dispatch group that
16657 precedes the group to which INSN belongs). This means that INSN will be
16658 the first insn in the group it belongs to). */
16660 static bool
16661 insn_terminates_group_p (rtx insn, enum group_termination which_group)
16663 enum attr_type type;
16665 if (! insn)
16666 return false;
16668 type = get_attr_type (insn);
16670 if (is_microcoded_insn (insn))
16671 return true;
16673 if (which_group == current_group)
16675 if (is_branch_slot_insn (insn))
16676 return true;
16677 return false;
16679 else if (which_group == previous_group)
16681 if (is_dispatch_slot_restricted (insn))
16682 return true;
16683 return false;
16686 return false;
16689 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
16690 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
16692 static bool
16693 is_costly_group (rtx *group_insns, rtx next_insn)
16695 int i;
16696 rtx link;
16697 int cost;
16698 int issue_rate = rs6000_issue_rate ();
16700 for (i = 0; i < issue_rate; i++)
16702 rtx insn = group_insns[i];
16703 if (!insn)
16704 continue;
16705 for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
16707 rtx next = XEXP (link, 0);
16708 if (next == next_insn)
16710 cost = insn_cost (insn, link, next_insn);
16711 if (rs6000_is_costly_dependence (insn, next_insn, link, cost, 0))
16712 return true;
16717 return false;
16720 /* Utility of the function redefine_groups.
16721 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
16722 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
16723 to keep it "far" (in a separate group) from GROUP_INSNS, following
16724 one of the following schemes, depending on the value of the flag
16725 -minsert_sched_nops = X:
16726 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
16727 in order to force NEXT_INSN into a separate group.
16728 (2) X < sched_finish_regroup_exact: insert exactly X nops.
16729 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
16730 insertion (has a group just ended, how many vacant issue slots remain in the
16731 last group, and how many dispatch groups were encountered so far). */
16733 static int
16734 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
16735 rtx next_insn, bool *group_end, int can_issue_more,
16736 int *group_count)
16738 rtx nop;
16739 bool force;
16740 int issue_rate = rs6000_issue_rate ();
16741 bool end = *group_end;
16742 int i;
16744 if (next_insn == NULL_RTX)
16745 return can_issue_more;
16747 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
16748 return can_issue_more;
16750 force = is_costly_group (group_insns, next_insn);
16751 if (!force)
16752 return can_issue_more;
16754 if (sched_verbose > 6)
16755 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
16756 *group_count ,can_issue_more);
16758 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
16760 if (*group_end)
16761 can_issue_more = 0;
16763 /* Since only a branch can be issued in the last issue_slot, it is
16764 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
16765 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
16766 in this case the last nop will start a new group and the branch
16767 will be forced to the new group. */
16768 if (can_issue_more && !is_branch_slot_insn (next_insn))
16769 can_issue_more--;
16771 while (can_issue_more > 0)
16773 nop = gen_nop ();
16774 emit_insn_before (nop, next_insn);
16775 can_issue_more--;
16778 *group_end = true;
16779 return 0;
16782 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
16784 int n_nops = rs6000_sched_insert_nops;
16786 /* Nops can't be issued from the branch slot, so the effective
16787 issue_rate for nops is 'issue_rate - 1'. */
16788 if (can_issue_more == 0)
16789 can_issue_more = issue_rate;
16790 can_issue_more--;
16791 if (can_issue_more == 0)
16793 can_issue_more = issue_rate - 1;
16794 (*group_count)++;
16795 end = true;
16796 for (i = 0; i < issue_rate; i++)
16798 group_insns[i] = 0;
16802 while (n_nops > 0)
16804 nop = gen_nop ();
16805 emit_insn_before (nop, next_insn);
16806 if (can_issue_more == issue_rate - 1) /* new group begins */
16807 end = false;
16808 can_issue_more--;
16809 if (can_issue_more == 0)
16811 can_issue_more = issue_rate - 1;
16812 (*group_count)++;
16813 end = true;
16814 for (i = 0; i < issue_rate; i++)
16816 group_insns[i] = 0;
16819 n_nops--;
16822 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
16823 can_issue_more++;
16825 /* Is next_insn going to start a new group? */
16826 *group_end
16827 = (end
16828 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
16829 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
16830 || (can_issue_more < issue_rate &&
16831 insn_terminates_group_p (next_insn, previous_group)));
16832 if (*group_end && end)
16833 (*group_count)--;
16835 if (sched_verbose > 6)
16836 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
16837 *group_count, can_issue_more);
16838 return can_issue_more;
16841 return can_issue_more;
16844 /* This function tries to synch the dispatch groups that the compiler "sees"
16845 with the dispatch groups that the processor dispatcher is expected to
16846 form in practice. It tries to achieve this synchronization by forcing the
16847 estimated processor grouping on the compiler (as opposed to the function
16848 'pad_goups' which tries to force the scheduler's grouping on the processor).
16850 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
16851 examines the (estimated) dispatch groups that will be formed by the processor
16852 dispatcher. It marks these group boundaries to reflect the estimated
16853 processor grouping, overriding the grouping that the scheduler had marked.
16854 Depending on the value of the flag '-minsert-sched-nops' this function can
16855 force certain insns into separate groups or force a certain distance between
16856 them by inserting nops, for example, if there exists a "costly dependence"
16857 between the insns.
16859 The function estimates the group boundaries that the processor will form as
16860 follows: It keeps track of how many vacant issue slots are available after
16861 each insn. A subsequent insn will start a new group if one of the following
16862 4 cases applies:
16863 - no more vacant issue slots remain in the current dispatch group.
16864 - only the last issue slot, which is the branch slot, is vacant, but the next
16865 insn is not a branch.
16866 - only the last 2 or less issue slots, including the branch slot, are vacant,
16867 which means that a cracked insn (which occupies two issue slots) can't be
16868 issued in this group.
16869 - less than 'issue_rate' slots are vacant, and the next insn always needs to
16870 start a new group. */
16872 static int
16873 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
16875 rtx insn, next_insn;
16876 int issue_rate;
16877 int can_issue_more;
16878 int slot, i;
16879 bool group_end;
16880 int group_count = 0;
16881 rtx *group_insns;
16883 /* Initialize. */
16884 issue_rate = rs6000_issue_rate ();
16885 group_insns = alloca (issue_rate * sizeof (rtx));
16886 for (i = 0; i < issue_rate; i++)
16888 group_insns[i] = 0;
16890 can_issue_more = issue_rate;
16891 slot = 0;
16892 insn = get_next_active_insn (prev_head_insn, tail);
16893 group_end = false;
16895 while (insn != NULL_RTX)
16897 slot = (issue_rate - can_issue_more);
16898 group_insns[slot] = insn;
16899 can_issue_more =
16900 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
16901 if (insn_terminates_group_p (insn, current_group))
16902 can_issue_more = 0;
16904 next_insn = get_next_active_insn (insn, tail);
16905 if (next_insn == NULL_RTX)
16906 return group_count + 1;
16908 /* Is next_insn going to start a new group? */
16909 group_end
16910 = (can_issue_more == 0
16911 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
16912 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
16913 || (can_issue_more < issue_rate &&
16914 insn_terminates_group_p (next_insn, previous_group)));
16916 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
16917 next_insn, &group_end, can_issue_more,
16918 &group_count);
16920 if (group_end)
16922 group_count++;
16923 can_issue_more = 0;
16924 for (i = 0; i < issue_rate; i++)
16926 group_insns[i] = 0;
16930 if (GET_MODE (next_insn) == TImode && can_issue_more)
16931 PUT_MODE (next_insn, VOIDmode);
16932 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
16933 PUT_MODE (next_insn, TImode);
16935 insn = next_insn;
16936 if (can_issue_more == 0)
16937 can_issue_more = issue_rate;
16938 } /* while */
16940 return group_count;
16943 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
16944 dispatch group boundaries that the scheduler had marked. Pad with nops
16945 any dispatch groups which have vacant issue slots, in order to force the
16946 scheduler's grouping on the processor dispatcher. The function
16947 returns the number of dispatch groups found. */
16949 static int
16950 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
16952 rtx insn, next_insn;
16953 rtx nop;
16954 int issue_rate;
16955 int can_issue_more;
16956 int group_end;
16957 int group_count = 0;
16959 /* Initialize issue_rate. */
16960 issue_rate = rs6000_issue_rate ();
16961 can_issue_more = issue_rate;
16963 insn = get_next_active_insn (prev_head_insn, tail);
16964 next_insn = get_next_active_insn (insn, tail);
16966 while (insn != NULL_RTX)
16968 can_issue_more =
16969 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
16971 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
16973 if (next_insn == NULL_RTX)
16974 break;
16976 if (group_end)
16978 /* If the scheduler had marked group termination at this location
16979 (between insn and next_indn), and neither insn nor next_insn will
16980 force group termination, pad the group with nops to force group
16981 termination. */
16982 if (can_issue_more
16983 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
16984 && !insn_terminates_group_p (insn, current_group)
16985 && !insn_terminates_group_p (next_insn, previous_group))
16987 if (!is_branch_slot_insn (next_insn))
16988 can_issue_more--;
16990 while (can_issue_more)
16992 nop = gen_nop ();
16993 emit_insn_before (nop, next_insn);
16994 can_issue_more--;
16998 can_issue_more = issue_rate;
16999 group_count++;
17002 insn = next_insn;
17003 next_insn = get_next_active_insn (insn, tail);
17006 return group_count;
17009 /* The following function is called at the end of scheduling BB.
17010 After reload, it inserts nops at insn group bundling. */
17012 static void
17013 rs6000_sched_finish (FILE *dump, int sched_verbose)
17015 int n_groups;
17017 if (sched_verbose)
17018 fprintf (dump, "=== Finishing schedule.\n");
17020 if (reload_completed && rs6000_sched_groups)
17022 if (rs6000_sched_insert_nops == sched_finish_none)
17023 return;
17025 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
17026 n_groups = pad_groups (dump, sched_verbose,
17027 current_sched_info->prev_head,
17028 current_sched_info->next_tail);
17029 else
17030 n_groups = redefine_groups (dump, sched_verbose,
17031 current_sched_info->prev_head,
17032 current_sched_info->next_tail);
17034 if (sched_verbose >= 6)
17036 fprintf (dump, "ngroups = %d\n", n_groups);
17037 print_rtl (dump, current_sched_info->prev_head);
17038 fprintf (dump, "Done finish_sched\n");
17043 /* Length in units of the trampoline for entering a nested function. */
17046 rs6000_trampoline_size (void)
17048 int ret = 0;
17050 switch (DEFAULT_ABI)
17052 default:
17053 gcc_unreachable ();
17055 case ABI_AIX:
17056 ret = (TARGET_32BIT) ? 12 : 24;
17057 break;
17059 case ABI_DARWIN:
17060 case ABI_V4:
17061 ret = (TARGET_32BIT) ? 40 : 48;
17062 break;
17065 return ret;
17068 /* Emit RTL insns to initialize the variable parts of a trampoline.
17069 FNADDR is an RTX for the address of the function's pure code.
17070 CXT is an RTX for the static chain value for the function. */
17072 void
17073 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
17075 enum machine_mode pmode = Pmode;
17076 int regsize = (TARGET_32BIT) ? 4 : 8;
17077 rtx ctx_reg = force_reg (pmode, cxt);
17079 switch (DEFAULT_ABI)
17081 default:
17082 gcc_unreachable ();
17084 /* Macros to shorten the code expansions below. */
17085 #define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
17086 #define MEM_PLUS(addr,offset) \
17087 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
17089 /* Under AIX, just build the 3 word function descriptor */
17090 case ABI_AIX:
17092 rtx fn_reg = gen_reg_rtx (pmode);
17093 rtx toc_reg = gen_reg_rtx (pmode);
17094 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
17095 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
17096 emit_move_insn (MEM_DEREF (addr), fn_reg);
17097 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
17098 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
17100 break;
17102 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
17103 case ABI_DARWIN:
17104 case ABI_V4:
17105 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
17106 FALSE, VOIDmode, 4,
17107 addr, pmode,
17108 GEN_INT (rs6000_trampoline_size ()), SImode,
17109 fnaddr, pmode,
17110 ctx_reg, pmode);
17111 break;
17114 return;
17118 /* Table of valid machine attributes. */
17120 const struct attribute_spec rs6000_attribute_table[] =
17122 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
17123 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
17124 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
17125 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
17126 #ifdef SUBTARGET_ATTRIBUTE_TABLE
17127 SUBTARGET_ATTRIBUTE_TABLE,
17128 #endif
17129 { NULL, 0, 0, false, false, false, NULL }
17132 /* Handle the "altivec" attribute. The attribute may have
17133 arguments as follows:
17135 __attribute__((altivec(vector__)))
17136 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
17137 __attribute__((altivec(bool__))) (always followed by 'unsigned')
17139 and may appear more than once (e.g., 'vector bool char') in a
17140 given declaration. */
17142 static tree
17143 rs6000_handle_altivec_attribute (tree *node,
17144 tree name ATTRIBUTE_UNUSED,
17145 tree args,
17146 int flags ATTRIBUTE_UNUSED,
17147 bool *no_add_attrs)
17149 tree type = *node, result = NULL_TREE;
17150 enum machine_mode mode;
17151 int unsigned_p;
17152 char altivec_type
17153 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
17154 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
17155 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
17156 : '?');
17158 while (POINTER_TYPE_P (type)
17159 || TREE_CODE (type) == FUNCTION_TYPE
17160 || TREE_CODE (type) == METHOD_TYPE
17161 || TREE_CODE (type) == ARRAY_TYPE)
17162 type = TREE_TYPE (type);
17164 mode = TYPE_MODE (type);
17166 /* Check for invalid AltiVec type qualifiers. */
17167 if (type == long_unsigned_type_node || type == long_integer_type_node)
17169 if (TARGET_64BIT)
17170 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
17171 else if (rs6000_warn_altivec_long)
17172 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
17174 else if (type == long_long_unsigned_type_node
17175 || type == long_long_integer_type_node)
17176 error ("use of %<long long%> in AltiVec types is invalid");
17177 else if (type == double_type_node)
17178 error ("use of %<double%> in AltiVec types is invalid");
17179 else if (type == long_double_type_node)
17180 error ("use of %<long double%> in AltiVec types is invalid");
17181 else if (type == boolean_type_node)
17182 error ("use of boolean types in AltiVec types is invalid");
17183 else if (TREE_CODE (type) == COMPLEX_TYPE)
17184 error ("use of %<complex%> in AltiVec types is invalid");
17186 switch (altivec_type)
17188 case 'v':
17189 unsigned_p = TYPE_UNSIGNED (type);
17190 switch (mode)
17192 case SImode:
17193 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
17194 break;
17195 case HImode:
17196 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
17197 break;
17198 case QImode:
17199 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
17200 break;
17201 case SFmode: result = V4SF_type_node; break;
17202 /* If the user says 'vector int bool', we may be handed the 'bool'
17203 attribute _before_ the 'vector' attribute, and so select the
17204 proper type in the 'b' case below. */
17205 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
17206 result = type;
17207 default: break;
17209 break;
17210 case 'b':
17211 switch (mode)
17213 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
17214 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
17215 case QImode: case V16QImode: result = bool_V16QI_type_node;
17216 default: break;
17218 break;
17219 case 'p':
17220 switch (mode)
17222 case V8HImode: result = pixel_V8HI_type_node;
17223 default: break;
17225 default: break;
17228 if (result && result != type && TYPE_READONLY (type))
17229 result = build_qualified_type (result, TYPE_QUAL_CONST);
17231 *no_add_attrs = true; /* No need to hang on to the attribute. */
17233 if (result)
17234 *node = reconstruct_complex_type (*node, result);
17236 return NULL_TREE;
17239 /* AltiVec defines four built-in scalar types that serve as vector
17240 elements; we must teach the compiler how to mangle them. */
17242 static const char *
17243 rs6000_mangle_fundamental_type (tree type)
17245 if (type == bool_char_type_node) return "U6__boolc";
17246 if (type == bool_short_type_node) return "U6__bools";
17247 if (type == pixel_type_node) return "u7__pixel";
17248 if (type == bool_int_type_node) return "U6__booli";
17250 /* For all other types, use normal C++ mangling. */
17251 return NULL;
17254 /* Handle a "longcall" or "shortcall" attribute; arguments as in
17255 struct attribute_spec.handler. */
17257 static tree
17258 rs6000_handle_longcall_attribute (tree *node, tree name,
17259 tree args ATTRIBUTE_UNUSED,
17260 int flags ATTRIBUTE_UNUSED,
17261 bool *no_add_attrs)
17263 if (TREE_CODE (*node) != FUNCTION_TYPE
17264 && TREE_CODE (*node) != FIELD_DECL
17265 && TREE_CODE (*node) != TYPE_DECL)
17267 warning (OPT_Wattributes, "%qs attribute only applies to functions",
17268 IDENTIFIER_POINTER (name));
17269 *no_add_attrs = true;
17272 return NULL_TREE;
17275 /* Set longcall attributes on all functions declared when
17276 rs6000_default_long_calls is true. */
17277 static void
17278 rs6000_set_default_type_attributes (tree type)
17280 if (rs6000_default_long_calls
17281 && (TREE_CODE (type) == FUNCTION_TYPE
17282 || TREE_CODE (type) == METHOD_TYPE))
17283 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
17284 NULL_TREE,
17285 TYPE_ATTRIBUTES (type));
17288 /* Return a reference suitable for calling a function with the
17289 longcall attribute. */
17292 rs6000_longcall_ref (rtx call_ref)
17294 const char *call_name;
17295 tree node;
17297 if (GET_CODE (call_ref) != SYMBOL_REF)
17298 return call_ref;
17300 /* System V adds '.' to the internal name, so skip them. */
17301 call_name = XSTR (call_ref, 0);
17302 if (*call_name == '.')
17304 while (*call_name == '.')
17305 call_name++;
17307 node = get_identifier (call_name);
17308 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
17311 return force_reg (Pmode, call_ref);
17314 #ifdef USING_ELFOS_H
17316 /* A C statement or statements to switch to the appropriate section
17317 for output of RTX in mode MODE. You can assume that RTX is some
17318 kind of constant in RTL. The argument MODE is redundant except in
17319 the case of a `const_int' rtx. Select the section by calling
17320 `text_section' or one of the alternatives for other sections.
17322 Do not define this macro if you put all constants in the read-only
17323 data section. */
17325 static void
17326 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
17327 unsigned HOST_WIDE_INT align)
17329 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
17330 toc_section ();
17331 else
17332 default_elf_select_rtx_section (mode, x, align);
17335 /* A C statement or statements to switch to the appropriate
17336 section for output of DECL. DECL is either a `VAR_DECL' node
17337 or a constant of some sort. RELOC indicates whether forming
17338 the initial value of DECL requires link-time relocations. */
17340 static void
17341 rs6000_elf_select_section (tree decl, int reloc,
17342 unsigned HOST_WIDE_INT align)
17344 /* Pretend that we're always building for a shared library when
17345 ABI_AIX, because otherwise we end up with dynamic relocations
17346 in read-only sections. This happens for function pointers,
17347 references to vtables in typeinfo, and probably other cases. */
17348 default_elf_select_section_1 (decl, reloc, align,
17349 flag_pic || DEFAULT_ABI == ABI_AIX);
17352 /* A C statement to build up a unique section name, expressed as a
17353 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
17354 RELOC indicates whether the initial value of EXP requires
17355 link-time relocations. If you do not define this macro, GCC will use
17356 the symbol name prefixed by `.' as the section name. Note - this
17357 macro can now be called for uninitialized data items as well as
17358 initialized data and functions. */
17360 static void
17361 rs6000_elf_unique_section (tree decl, int reloc)
17363 /* As above, pretend that we're always building for a shared library
17364 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
17365 default_unique_section_1 (decl, reloc,
17366 flag_pic || DEFAULT_ABI == ABI_AIX);
17369 /* For a SYMBOL_REF, set generic flags and then perform some
17370 target-specific processing.
17372 When the AIX ABI is requested on a non-AIX system, replace the
17373 function name with the real name (with a leading .) rather than the
17374 function descriptor name. This saves a lot of overriding code to
17375 read the prefixes. */
17377 static void
17378 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
17380 default_encode_section_info (decl, rtl, first);
17382 if (first
17383 && TREE_CODE (decl) == FUNCTION_DECL
17384 && !TARGET_AIX
17385 && DEFAULT_ABI == ABI_AIX)
17387 rtx sym_ref = XEXP (rtl, 0);
17388 size_t len = strlen (XSTR (sym_ref, 0));
17389 char *str = alloca (len + 2);
17390 str[0] = '.';
17391 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
17392 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
17396 static bool
17397 rs6000_elf_in_small_data_p (tree decl)
17399 if (rs6000_sdata == SDATA_NONE)
17400 return false;
17402 /* We want to merge strings, so we never consider them small data. */
17403 if (TREE_CODE (decl) == STRING_CST)
17404 return false;
17406 /* Functions are never in the small data area. */
17407 if (TREE_CODE (decl) == FUNCTION_DECL)
17408 return false;
17410 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
17412 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
17413 if (strcmp (section, ".sdata") == 0
17414 || strcmp (section, ".sdata2") == 0
17415 || strcmp (section, ".sbss") == 0
17416 || strcmp (section, ".sbss2") == 0
17417 || strcmp (section, ".PPC.EMB.sdata0") == 0
17418 || strcmp (section, ".PPC.EMB.sbss0") == 0)
17419 return true;
17421 else
17423 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
17425 if (size > 0
17426 && (unsigned HOST_WIDE_INT) size <= g_switch_value
17427 /* If it's not public, and we're not going to reference it there,
17428 there's no need to put it in the small data section. */
17429 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
17430 return true;
17433 return false;
17436 #endif /* USING_ELFOS_H */
17439 /* Return a REG that occurs in ADDR with coefficient 1.
17440 ADDR can be effectively incremented by incrementing REG.
17442 r0 is special and we must not select it as an address
17443 register by this routine since our caller will try to
17444 increment the returned register via an "la" instruction. */
17447 find_addr_reg (rtx addr)
17449 while (GET_CODE (addr) == PLUS)
17451 if (GET_CODE (XEXP (addr, 0)) == REG
17452 && REGNO (XEXP (addr, 0)) != 0)
17453 addr = XEXP (addr, 0);
17454 else if (GET_CODE (XEXP (addr, 1)) == REG
17455 && REGNO (XEXP (addr, 1)) != 0)
17456 addr = XEXP (addr, 1);
17457 else if (CONSTANT_P (XEXP (addr, 0)))
17458 addr = XEXP (addr, 1);
17459 else if (CONSTANT_P (XEXP (addr, 1)))
17460 addr = XEXP (addr, 0);
17461 else
17462 gcc_unreachable ();
17464 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
17465 return addr;
17468 void
17469 rs6000_fatal_bad_address (rtx op)
17471 fatal_insn ("bad address", op);
17474 #if TARGET_MACHO
17476 static tree branch_island_list = 0;
17478 /* Remember to generate a branch island for far calls to the given
17479 function. */
17481 static void
17482 add_compiler_branch_island (tree label_name, tree function_name,
17483 int line_number)
17485 tree branch_island = build_tree_list (function_name, label_name);
17486 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
17487 TREE_CHAIN (branch_island) = branch_island_list;
17488 branch_island_list = branch_island;
17491 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
17492 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
17493 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
17494 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
17496 /* Generate far-jump branch islands for everything on the
17497 branch_island_list. Invoked immediately after the last instruction
17498 of the epilogue has been emitted; the branch-islands must be
17499 appended to, and contiguous with, the function body. Mach-O stubs
17500 are generated in machopic_output_stub(). */
17502 static void
17503 macho_branch_islands (void)
17505 char tmp_buf[512];
17506 tree branch_island;
17508 for (branch_island = branch_island_list;
17509 branch_island;
17510 branch_island = TREE_CHAIN (branch_island))
17512 const char *label =
17513 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
17514 const char *name =
17515 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
17516 char name_buf[512];
17517 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
17518 if (name[0] == '*' || name[0] == '&')
17519 strcpy (name_buf, name+1);
17520 else
17522 name_buf[0] = '_';
17523 strcpy (name_buf+1, name);
17525 strcpy (tmp_buf, "\n");
17526 strcat (tmp_buf, label);
17527 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
17528 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
17529 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
17530 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
17531 if (flag_pic)
17533 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
17534 strcat (tmp_buf, label);
17535 strcat (tmp_buf, "_pic\n");
17536 strcat (tmp_buf, label);
17537 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
17539 strcat (tmp_buf, "\taddis r11,r11,ha16(");
17540 strcat (tmp_buf, name_buf);
17541 strcat (tmp_buf, " - ");
17542 strcat (tmp_buf, label);
17543 strcat (tmp_buf, "_pic)\n");
17545 strcat (tmp_buf, "\tmtlr r0\n");
17547 strcat (tmp_buf, "\taddi r12,r11,lo16(");
17548 strcat (tmp_buf, name_buf);
17549 strcat (tmp_buf, " - ");
17550 strcat (tmp_buf, label);
17551 strcat (tmp_buf, "_pic)\n");
17553 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
17555 else
17557 strcat (tmp_buf, ":\nlis r12,hi16(");
17558 strcat (tmp_buf, name_buf);
17559 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
17560 strcat (tmp_buf, name_buf);
17561 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
17563 output_asm_insn (tmp_buf, 0);
17564 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
17565 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
17566 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
17567 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
17570 branch_island_list = 0;
17573 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
17574 already there or not. */
17576 static int
17577 no_previous_def (tree function_name)
17579 tree branch_island;
17580 for (branch_island = branch_island_list;
17581 branch_island;
17582 branch_island = TREE_CHAIN (branch_island))
17583 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
17584 return 0;
17585 return 1;
17588 /* GET_PREV_LABEL gets the label name from the previous definition of
17589 the function. */
17591 static tree
17592 get_prev_label (tree function_name)
17594 tree branch_island;
17595 for (branch_island = branch_island_list;
17596 branch_island;
17597 branch_island = TREE_CHAIN (branch_island))
17598 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
17599 return BRANCH_ISLAND_LABEL_NAME (branch_island);
17600 return 0;
17603 /* INSN is either a function call or a millicode call. It may have an
17604 unconditional jump in its delay slot.
17606 CALL_DEST is the routine we are calling. */
17608 char *
17609 output_call (rtx insn, rtx *operands, int dest_operand_number,
17610 int cookie_operand_number)
17612 static char buf[256];
17613 if (GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
17614 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
17616 tree labelname;
17617 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
17619 if (no_previous_def (funname))
17621 int line_number = 0;
17622 rtx label_rtx = gen_label_rtx ();
17623 char *label_buf, temp_buf[256];
17624 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
17625 CODE_LABEL_NUMBER (label_rtx));
17626 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
17627 labelname = get_identifier (label_buf);
17628 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
17629 if (insn)
17630 line_number = NOTE_LINE_NUMBER (insn);
17631 add_compiler_branch_island (labelname, funname, line_number);
17633 else
17634 labelname = get_prev_label (funname);
17636 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
17637 instruction will reach 'foo', otherwise link as 'bl L42'".
17638 "L42" should be a 'branch island', that will do a far jump to
17639 'foo'. Branch islands are generated in
17640 macho_branch_islands(). */
17641 sprintf (buf, "jbsr %%z%d,%.246s",
17642 dest_operand_number, IDENTIFIER_POINTER (labelname));
17644 else
17645 sprintf (buf, "bl %%z%d", dest_operand_number);
17646 return buf;
17649 /* Generate PIC and indirect symbol stubs. */
17651 void
17652 machopic_output_stub (FILE *file, const char *symb, const char *stub)
17654 unsigned int length;
17655 char *symbol_name, *lazy_ptr_name;
17656 char *local_label_0;
17657 static int label = 0;
17659 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
17660 symb = (*targetm.strip_name_encoding) (symb);
17663 length = strlen (symb);
17664 symbol_name = alloca (length + 32);
17665 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
17667 lazy_ptr_name = alloca (length + 32);
17668 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
17670 if (flag_pic == 2)
17671 machopic_picsymbol_stub1_section ();
17672 else
17673 machopic_symbol_stub1_section ();
17675 if (flag_pic == 2)
17677 fprintf (file, "\t.align 5\n");
17679 fprintf (file, "%s:\n", stub);
17680 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
17682 label++;
17683 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
17684 sprintf (local_label_0, "\"L%011d$spb\"", label);
17686 fprintf (file, "\tmflr r0\n");
17687 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
17688 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
17689 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
17690 lazy_ptr_name, local_label_0);
17691 fprintf (file, "\tmtlr r0\n");
17692 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
17693 (TARGET_64BIT ? "ldu" : "lwzu"),
17694 lazy_ptr_name, local_label_0);
17695 fprintf (file, "\tmtctr r12\n");
17696 fprintf (file, "\tbctr\n");
17698 else
17700 fprintf (file, "\t.align 4\n");
17702 fprintf (file, "%s:\n", stub);
17703 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
17705 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
17706 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
17707 (TARGET_64BIT ? "ldu" : "lwzu"),
17708 lazy_ptr_name);
17709 fprintf (file, "\tmtctr r12\n");
17710 fprintf (file, "\tbctr\n");
17713 machopic_lazy_symbol_ptr_section ();
17714 fprintf (file, "%s:\n", lazy_ptr_name);
17715 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
17716 fprintf (file, "%sdyld_stub_binding_helper\n",
17717 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
17720 /* Legitimize PIC addresses. If the address is already
17721 position-independent, we return ORIG. Newly generated
17722 position-independent addresses go into a reg. This is REG if non
17723 zero, otherwise we allocate register(s) as necessary. */
17725 #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x8000) < 0x10000)
17728 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
17729 rtx reg)
17731 rtx base, offset;
17733 if (reg == NULL && ! reload_in_progress && ! reload_completed)
17734 reg = gen_reg_rtx (Pmode);
17736 if (GET_CODE (orig) == CONST)
17738 rtx reg_temp;
17740 if (GET_CODE (XEXP (orig, 0)) == PLUS
17741 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
17742 return orig;
17744 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
17746 /* Use a different reg for the intermediate value, as
17747 it will be marked UNCHANGING. */
17748 reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
17749 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
17750 Pmode, reg_temp);
17751 offset =
17752 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
17753 Pmode, reg);
17755 if (GET_CODE (offset) == CONST_INT)
17757 if (SMALL_INT (offset))
17758 return plus_constant (base, INTVAL (offset));
17759 else if (! reload_in_progress && ! reload_completed)
17760 offset = force_reg (Pmode, offset);
17761 else
17763 rtx mem = force_const_mem (Pmode, orig);
17764 return machopic_legitimize_pic_address (mem, Pmode, reg);
17767 return gen_rtx_PLUS (Pmode, base, offset);
17770 /* Fall back on generic machopic code. */
17771 return machopic_legitimize_pic_address (orig, mode, reg);
17774 /* This is just a placeholder to make linking work without having to
17775 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
17776 ever needed for Darwin (not too likely!) this would have to get a
17777 real definition. */
17779 void
17780 toc_section (void)
17784 /* Output a .machine directive for the Darwin assembler, and call
17785 the generic start_file routine. */
17787 static void
17788 rs6000_darwin_file_start (void)
17790 static const struct
17792 const char *arg;
17793 const char *name;
17794 int if_set;
17795 } mapping[] = {
17796 { "ppc64", "ppc64", MASK_64BIT },
17797 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
17798 { "power4", "ppc970", 0 },
17799 { "G5", "ppc970", 0 },
17800 { "7450", "ppc7450", 0 },
17801 { "7400", "ppc7400", MASK_ALTIVEC },
17802 { "G4", "ppc7400", 0 },
17803 { "750", "ppc750", 0 },
17804 { "740", "ppc750", 0 },
17805 { "G3", "ppc750", 0 },
17806 { "604e", "ppc604e", 0 },
17807 { "604", "ppc604", 0 },
17808 { "603e", "ppc603", 0 },
17809 { "603", "ppc603", 0 },
17810 { "601", "ppc601", 0 },
17811 { NULL, "ppc", 0 } };
17812 const char *cpu_id = "";
17813 size_t i;
17815 rs6000_file_start ();
17817 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
17818 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
17819 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
17820 && rs6000_select[i].string[0] != '\0')
17821 cpu_id = rs6000_select[i].string;
17823 /* Look through the mapping array. Pick the first name that either
17824 matches the argument, has a bit set in IF_SET that is also set
17825 in the target flags, or has a NULL name. */
17827 i = 0;
17828 while (mapping[i].arg != NULL
17829 && strcmp (mapping[i].arg, cpu_id) != 0
17830 && (mapping[i].if_set & target_flags) == 0)
17831 i++;
17833 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
17836 #endif /* TARGET_MACHO */
17838 #if TARGET_ELF
17839 static unsigned int
17840 rs6000_elf_section_type_flags (tree decl, const char *name, int reloc)
17842 return default_section_type_flags_1 (decl, name, reloc,
17843 flag_pic || DEFAULT_ABI == ABI_AIX);
17846 /* Record an element in the table of global constructors. SYMBOL is
17847 a SYMBOL_REF of the function to be called; PRIORITY is a number
17848 between 0 and MAX_INIT_PRIORITY.
17850 This differs from default_named_section_asm_out_constructor in
17851 that we have special handling for -mrelocatable. */
17853 static void
17854 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
17856 const char *section = ".ctors";
17857 char buf[16];
17859 if (priority != DEFAULT_INIT_PRIORITY)
17861 sprintf (buf, ".ctors.%.5u",
17862 /* Invert the numbering so the linker puts us in the proper
17863 order; constructors are run from right to left, and the
17864 linker sorts in increasing order. */
17865 MAX_INIT_PRIORITY - priority);
17866 section = buf;
17869 named_section_flags (section, SECTION_WRITE);
17870 assemble_align (POINTER_SIZE);
17872 if (TARGET_RELOCATABLE)
17874 fputs ("\t.long (", asm_out_file);
17875 output_addr_const (asm_out_file, symbol);
17876 fputs (")@fixup\n", asm_out_file);
17878 else
17879 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
17882 static void
17883 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
17885 const char *section = ".dtors";
17886 char buf[16];
17888 if (priority != DEFAULT_INIT_PRIORITY)
17890 sprintf (buf, ".dtors.%.5u",
17891 /* Invert the numbering so the linker puts us in the proper
17892 order; constructors are run from right to left, and the
17893 linker sorts in increasing order. */
17894 MAX_INIT_PRIORITY - priority);
17895 section = buf;
17898 named_section_flags (section, SECTION_WRITE);
17899 assemble_align (POINTER_SIZE);
17901 if (TARGET_RELOCATABLE)
17903 fputs ("\t.long (", asm_out_file);
17904 output_addr_const (asm_out_file, symbol);
17905 fputs (")@fixup\n", asm_out_file);
17907 else
17908 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
17911 void
17912 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
17914 if (TARGET_64BIT)
17916 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
17917 ASM_OUTPUT_LABEL (file, name);
17918 fputs (DOUBLE_INT_ASM_OP, file);
17919 rs6000_output_function_entry (file, name);
17920 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
17921 if (DOT_SYMBOLS)
17923 fputs ("\t.size\t", file);
17924 assemble_name (file, name);
17925 fputs (",24\n\t.type\t.", file);
17926 assemble_name (file, name);
17927 fputs (",@function\n", file);
17928 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
17930 fputs ("\t.globl\t.", file);
17931 assemble_name (file, name);
17932 putc ('\n', file);
17935 else
17936 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
17937 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
17938 rs6000_output_function_entry (file, name);
17939 fputs (":\n", file);
17940 return;
17943 if (TARGET_RELOCATABLE
17944 && !TARGET_SECURE_PLT
17945 && (get_pool_size () != 0 || current_function_profile)
17946 && uses_TOC ())
17948 char buf[256];
17950 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
17952 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17953 fprintf (file, "\t.long ");
17954 assemble_name (file, buf);
17955 putc ('-', file);
17956 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17957 assemble_name (file, buf);
17958 putc ('\n', file);
17961 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
17962 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
17964 if (DEFAULT_ABI == ABI_AIX)
17966 const char *desc_name, *orig_name;
17968 orig_name = (*targetm.strip_name_encoding) (name);
17969 desc_name = orig_name;
17970 while (*desc_name == '.')
17971 desc_name++;
17973 if (TREE_PUBLIC (decl))
17974 fprintf (file, "\t.globl %s\n", desc_name);
17976 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
17977 fprintf (file, "%s:\n", desc_name);
17978 fprintf (file, "\t.long %s\n", orig_name);
17979 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
17980 if (DEFAULT_ABI == ABI_AIX)
17981 fputs ("\t.long 0\n", file);
17982 fprintf (file, "\t.previous\n");
17984 ASM_OUTPUT_LABEL (file, name);
17987 static void
17988 rs6000_elf_end_indicate_exec_stack (void)
17990 if (TARGET_32BIT)
17991 file_end_indicate_exec_stack ();
17993 #endif
17995 #if TARGET_XCOFF
17996 static void
17997 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
17999 fputs (GLOBAL_ASM_OP, stream);
18000 RS6000_OUTPUT_BASENAME (stream, name);
18001 putc ('\n', stream);
18004 static void
18005 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
18006 tree decl ATTRIBUTE_UNUSED)
18008 int smclass;
18009 static const char * const suffix[3] = { "PR", "RO", "RW" };
18011 if (flags & SECTION_CODE)
18012 smclass = 0;
18013 else if (flags & SECTION_WRITE)
18014 smclass = 2;
18015 else
18016 smclass = 1;
18018 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
18019 (flags & SECTION_CODE) ? "." : "",
18020 name, suffix[smclass], flags & SECTION_ENTSIZE);
18023 static void
18024 rs6000_xcoff_select_section (tree decl, int reloc,
18025 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
18027 if (decl_readonly_section_1 (decl, reloc, 1))
18029 if (TREE_PUBLIC (decl))
18030 read_only_data_section ();
18031 else
18032 read_only_private_data_section ();
18034 else
18036 if (TREE_PUBLIC (decl))
18037 data_section ();
18038 else
18039 private_data_section ();
18043 static void
18044 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
18046 const char *name;
18048 /* Use select_section for private and uninitialized data. */
18049 if (!TREE_PUBLIC (decl)
18050 || DECL_COMMON (decl)
18051 || DECL_INITIAL (decl) == NULL_TREE
18052 || DECL_INITIAL (decl) == error_mark_node
18053 || (flag_zero_initialized_in_bss
18054 && initializer_zerop (DECL_INITIAL (decl))))
18055 return;
18057 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
18058 name = (*targetm.strip_name_encoding) (name);
18059 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
18062 /* Select section for constant in constant pool.
18064 On RS/6000, all constants are in the private read-only data area.
18065 However, if this is being placed in the TOC it must be output as a
18066 toc entry. */
18068 static void
18069 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
18070 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
18072 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
18073 toc_section ();
18074 else
18075 read_only_private_data_section ();
18078 /* Remove any trailing [DS] or the like from the symbol name. */
18080 static const char *
18081 rs6000_xcoff_strip_name_encoding (const char *name)
18083 size_t len;
18084 if (*name == '*')
18085 name++;
18086 len = strlen (name);
18087 if (name[len - 1] == ']')
18088 return ggc_alloc_string (name, len - 4);
18089 else
18090 return name;
18093 /* Section attributes. AIX is always PIC. */
18095 static unsigned int
18096 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
18098 unsigned int align;
18099 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
18101 /* Align to at least UNIT size. */
18102 if (flags & SECTION_CODE)
18103 align = MIN_UNITS_PER_WORD;
18104 else
18105 /* Increase alignment of large objects if not already stricter. */
18106 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
18107 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
18108 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
18110 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
18113 /* Output at beginning of assembler file.
18115 Initialize the section names for the RS/6000 at this point.
18117 Specify filename, including full path, to assembler.
18119 We want to go into the TOC section so at least one .toc will be emitted.
18120 Also, in order to output proper .bs/.es pairs, we need at least one static
18121 [RW] section emitted.
18123 Finally, declare mcount when profiling to make the assembler happy. */
18125 static void
18126 rs6000_xcoff_file_start (void)
18128 rs6000_gen_section_name (&xcoff_bss_section_name,
18129 main_input_filename, ".bss_");
18130 rs6000_gen_section_name (&xcoff_private_data_section_name,
18131 main_input_filename, ".rw_");
18132 rs6000_gen_section_name (&xcoff_read_only_section_name,
18133 main_input_filename, ".ro_");
18135 fputs ("\t.file\t", asm_out_file);
18136 output_quoted_string (asm_out_file, main_input_filename);
18137 fputc ('\n', asm_out_file);
18138 if (write_symbols != NO_DEBUG)
18139 private_data_section ();
18140 text_section ();
18141 if (profile_flag)
18142 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
18143 rs6000_file_start ();
18146 /* Output at end of assembler file.
18147 On the RS/6000, referencing data should automatically pull in text. */
18149 static void
18150 rs6000_xcoff_file_end (void)
18152 text_section ();
18153 fputs ("_section_.text:\n", asm_out_file);
18154 data_section ();
18155 fputs (TARGET_32BIT
18156 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
18157 asm_out_file);
18159 #endif /* TARGET_XCOFF */
18161 /* Compute a (partial) cost for rtx X. Return true if the complete
18162 cost has been computed, and false if subexpressions should be
18163 scanned. In either case, *TOTAL contains the cost result. */
18165 static bool
18166 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
18168 enum machine_mode mode = GET_MODE (x);
18170 switch (code)
18172 /* On the RS/6000, if it is valid in the insn, it is free. */
18173 case CONST_INT:
18174 if (((outer_code == SET
18175 || outer_code == PLUS
18176 || outer_code == MINUS)
18177 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
18178 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')))
18179 || (outer_code == AND
18180 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18181 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18182 mode == SImode ? 'L' : 'J'))
18183 || mask_operand (x, mode)
18184 || (mode == DImode
18185 && mask64_operand (x, DImode))))
18186 || ((outer_code == IOR || outer_code == XOR)
18187 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18188 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18189 mode == SImode ? 'L' : 'J'))))
18190 || outer_code == ASHIFT
18191 || outer_code == ASHIFTRT
18192 || outer_code == LSHIFTRT
18193 || outer_code == ROTATE
18194 || outer_code == ROTATERT
18195 || outer_code == ZERO_EXTRACT
18196 || (outer_code == MULT
18197 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
18198 || ((outer_code == DIV || outer_code == UDIV
18199 || outer_code == MOD || outer_code == UMOD)
18200 && exact_log2 (INTVAL (x)) >= 0)
18201 || (outer_code == COMPARE
18202 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
18203 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')))
18204 || (outer_code == EQ
18205 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
18206 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18207 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18208 mode == SImode ? 'L' : 'J'))))
18209 || (outer_code == GTU
18210 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
18211 || (outer_code == LTU
18212 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'P')))
18214 *total = 0;
18215 return true;
18217 else if ((outer_code == PLUS
18218 && reg_or_add_cint_operand (x, VOIDmode))
18219 || (outer_code == MINUS
18220 && reg_or_sub_cint_operand (x, VOIDmode))
18221 || ((outer_code == SET
18222 || outer_code == IOR
18223 || outer_code == XOR)
18224 && (INTVAL (x)
18225 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
18227 *total = COSTS_N_INSNS (1);
18228 return true;
18230 /* FALLTHRU */
18232 case CONST_DOUBLE:
18233 if (mode == DImode
18234 && ((outer_code == AND
18235 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18236 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')
18237 || mask_operand (x, DImode)
18238 || mask64_operand (x, DImode)))
18239 || ((outer_code == IOR || outer_code == XOR)
18240 && CONST_DOUBLE_HIGH (x) == 0
18241 && (CONST_DOUBLE_LOW (x)
18242 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)))
18244 *total = 0;
18245 return true;
18247 else if (mode == DImode
18248 && (outer_code == SET
18249 || outer_code == IOR
18250 || outer_code == XOR)
18251 && CONST_DOUBLE_HIGH (x) == 0)
18253 *total = COSTS_N_INSNS (1);
18254 return true;
18256 /* FALLTHRU */
18258 case CONST:
18259 case HIGH:
18260 case SYMBOL_REF:
18261 case MEM:
18262 /* When optimizing for size, MEM should be slightly more expensive
18263 than generating address, e.g., (plus (reg) (const)).
18264 L1 cache latency is about two instructions. */
18265 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
18266 return true;
18268 case LABEL_REF:
18269 *total = 0;
18270 return true;
18272 case PLUS:
18273 if (mode == DFmode)
18275 if (GET_CODE (XEXP (x, 0)) == MULT)
18277 /* FNMA accounted in outer NEG. */
18278 if (outer_code == NEG)
18279 *total = rs6000_cost->dmul - rs6000_cost->fp;
18280 else
18281 *total = rs6000_cost->dmul;
18283 else
18284 *total = rs6000_cost->fp;
18286 else if (mode == SFmode)
18288 /* FNMA accounted in outer NEG. */
18289 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
18290 *total = 0;
18291 else
18292 *total = rs6000_cost->fp;
18294 else if (GET_CODE (XEXP (x, 0)) == MULT)
18296 /* The rs6000 doesn't have shift-and-add instructions. */
18297 rs6000_rtx_costs (XEXP (x, 0), MULT, PLUS, total);
18298 *total += COSTS_N_INSNS (1);
18300 else
18301 *total = COSTS_N_INSNS (1);
18302 return false;
18304 case MINUS:
18305 if (mode == DFmode)
18307 if (GET_CODE (XEXP (x, 0)) == MULT)
18309 /* FNMA accounted in outer NEG. */
18310 if (outer_code == NEG)
18311 *total = 0;
18312 else
18313 *total = rs6000_cost->dmul;
18315 else
18316 *total = rs6000_cost->fp;
18318 else if (mode == SFmode)
18320 /* FNMA accounted in outer NEG. */
18321 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
18322 *total = 0;
18323 else
18324 *total = rs6000_cost->fp;
18326 else if (GET_CODE (XEXP (x, 0)) == MULT)
18328 /* The rs6000 doesn't have shift-and-sub instructions. */
18329 rs6000_rtx_costs (XEXP (x, 0), MULT, MINUS, total);
18330 *total += COSTS_N_INSNS (1);
18332 else
18333 *total = COSTS_N_INSNS (1);
18334 return false;
18336 case MULT:
18337 if (GET_CODE (XEXP (x, 1)) == CONST_INT
18338 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
18340 if (INTVAL (XEXP (x, 1)) >= -256
18341 && INTVAL (XEXP (x, 1)) <= 255)
18342 *total = rs6000_cost->mulsi_const9;
18343 else
18344 *total = rs6000_cost->mulsi_const;
18346 /* FMA accounted in outer PLUS/MINUS. */
18347 else if ((mode == DFmode || mode == SFmode)
18348 && (outer_code == PLUS || outer_code == MINUS))
18349 *total = 0;
18350 else if (mode == DFmode)
18351 *total = rs6000_cost->dmul;
18352 else if (mode == SFmode)
18353 *total = rs6000_cost->fp;
18354 else if (mode == DImode)
18355 *total = rs6000_cost->muldi;
18356 else
18357 *total = rs6000_cost->mulsi;
18358 return false;
18360 case DIV:
18361 case MOD:
18362 if (FLOAT_MODE_P (mode))
18364 *total = mode == DFmode ? rs6000_cost->ddiv
18365 : rs6000_cost->sdiv;
18366 return false;
18368 /* FALLTHRU */
18370 case UDIV:
18371 case UMOD:
18372 if (GET_CODE (XEXP (x, 1)) == CONST_INT
18373 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
18375 if (code == DIV || code == MOD)
18376 /* Shift, addze */
18377 *total = COSTS_N_INSNS (2);
18378 else
18379 /* Shift */
18380 *total = COSTS_N_INSNS (1);
18382 else
18384 if (GET_MODE (XEXP (x, 1)) == DImode)
18385 *total = rs6000_cost->divdi;
18386 else
18387 *total = rs6000_cost->divsi;
18389 /* Add in shift and subtract for MOD. */
18390 if (code == MOD || code == UMOD)
18391 *total += COSTS_N_INSNS (2);
18392 return false;
18394 case FFS:
18395 *total = COSTS_N_INSNS (4);
18396 return false;
18398 case NOT:
18399 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
18401 *total = 0;
18402 return false;
18404 /* FALLTHRU */
18406 case AND:
18407 case IOR:
18408 case XOR:
18409 case ZERO_EXTRACT:
18410 *total = COSTS_N_INSNS (1);
18411 return false;
18413 case ASHIFT:
18414 case ASHIFTRT:
18415 case LSHIFTRT:
18416 case ROTATE:
18417 case ROTATERT:
18418 /* Handle mul_highpart. */
18419 if (outer_code == TRUNCATE
18420 && GET_CODE (XEXP (x, 0)) == MULT)
18422 if (mode == DImode)
18423 *total = rs6000_cost->muldi;
18424 else
18425 *total = rs6000_cost->mulsi;
18426 return true;
18428 else if (outer_code == AND)
18429 *total = 0;
18430 else
18431 *total = COSTS_N_INSNS (1);
18432 return false;
18434 case SIGN_EXTEND:
18435 case ZERO_EXTEND:
18436 if (GET_CODE (XEXP (x, 0)) == MEM)
18437 *total = 0;
18438 else
18439 *total = COSTS_N_INSNS (1);
18440 return false;
18442 case COMPARE:
18443 case NEG:
18444 case ABS:
18445 if (!FLOAT_MODE_P (mode))
18447 *total = COSTS_N_INSNS (1);
18448 return false;
18450 /* FALLTHRU */
18452 case FLOAT:
18453 case UNSIGNED_FLOAT:
18454 case FIX:
18455 case UNSIGNED_FIX:
18456 case FLOAT_TRUNCATE:
18457 *total = rs6000_cost->fp;
18458 return false;
18460 case FLOAT_EXTEND:
18461 if (mode == DFmode)
18462 *total = 0;
18463 else
18464 *total = rs6000_cost->fp;
18465 return false;
18467 case UNSPEC:
18468 switch (XINT (x, 1))
18470 case UNSPEC_FRSP:
18471 *total = rs6000_cost->fp;
18472 return true;
18474 default:
18475 break;
18477 break;
18479 case CALL:
18480 case IF_THEN_ELSE:
18481 if (optimize_size)
18483 *total = COSTS_N_INSNS (1);
18484 return true;
18486 else if (FLOAT_MODE_P (mode)
18487 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
18489 *total = rs6000_cost->fp;
18490 return false;
18492 break;
18494 case EQ:
18495 case GTU:
18496 case LTU:
18497 /* Carry bit requires mode == Pmode.
18498 NEG or PLUS already counted so only add one. */
18499 if (mode == Pmode
18500 && (outer_code == NEG || outer_code == PLUS))
18502 *total = COSTS_N_INSNS (1);
18503 return true;
18505 if (outer_code == SET)
18507 if (XEXP (x, 1) == const0_rtx)
18509 *total = COSTS_N_INSNS (2);
18510 return true;
18512 else if (mode == Pmode)
18514 *total = COSTS_N_INSNS (3);
18515 return false;
18518 /* FALLTHRU */
18520 case GT:
18521 case LT:
18522 case UNORDERED:
18523 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
18525 *total = COSTS_N_INSNS (2);
18526 return true;
18528 /* CC COMPARE. */
18529 if (outer_code == COMPARE)
18531 *total = 0;
18532 return true;
18534 break;
18536 default:
18537 break;
18540 return false;
18543 /* A C expression returning the cost of moving data from a register of class
18544 CLASS1 to one of CLASS2. */
18547 rs6000_register_move_cost (enum machine_mode mode,
18548 enum reg_class from, enum reg_class to)
18550 /* Moves from/to GENERAL_REGS. */
18551 if (reg_classes_intersect_p (to, GENERAL_REGS)
18552 || reg_classes_intersect_p (from, GENERAL_REGS))
18554 if (! reg_classes_intersect_p (to, GENERAL_REGS))
18555 from = to;
18557 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
18558 return (rs6000_memory_move_cost (mode, from, 0)
18559 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
18561 /* It's more expensive to move CR_REGS than CR0_REGS because of the
18562 shift. */
18563 else if (from == CR_REGS)
18564 return 4;
18566 else
18567 /* A move will cost one instruction per GPR moved. */
18568 return 2 * hard_regno_nregs[0][mode];
18571 /* Moving between two similar registers is just one instruction. */
18572 else if (reg_classes_intersect_p (to, from))
18573 return mode == TFmode ? 4 : 2;
18575 /* Everything else has to go through GENERAL_REGS. */
18576 else
18577 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
18578 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
18581 /* A C expressions returning the cost of moving data of MODE from a register to
18582 or from memory. */
18585 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
18586 int in ATTRIBUTE_UNUSED)
18588 if (reg_classes_intersect_p (class, GENERAL_REGS))
18589 return 4 * hard_regno_nregs[0][mode];
18590 else if (reg_classes_intersect_p (class, FLOAT_REGS))
18591 return 4 * hard_regno_nregs[32][mode];
18592 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
18593 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
18594 else
18595 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
18598 /* Newton-Raphson approximation of single-precision floating point divide n/d.
18599 Assumes no trapping math and finite arguments. */
18601 void
18602 rs6000_emit_swdivsf (rtx res, rtx n, rtx d)
18604 rtx x0, e0, e1, y1, u0, v0, one;
18606 x0 = gen_reg_rtx (SFmode);
18607 e0 = gen_reg_rtx (SFmode);
18608 e1 = gen_reg_rtx (SFmode);
18609 y1 = gen_reg_rtx (SFmode);
18610 u0 = gen_reg_rtx (SFmode);
18611 v0 = gen_reg_rtx (SFmode);
18612 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
18614 /* x0 = 1./d estimate */
18615 emit_insn (gen_rtx_SET (VOIDmode, x0,
18616 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
18617 UNSPEC_FRES)));
18618 /* e0 = 1. - d * x0 */
18619 emit_insn (gen_rtx_SET (VOIDmode, e0,
18620 gen_rtx_MINUS (SFmode, one,
18621 gen_rtx_MULT (SFmode, d, x0))));
18622 /* e1 = e0 + e0 * e0 */
18623 emit_insn (gen_rtx_SET (VOIDmode, e1,
18624 gen_rtx_PLUS (SFmode,
18625 gen_rtx_MULT (SFmode, e0, e0), e0)));
18626 /* y1 = x0 + e1 * x0 */
18627 emit_insn (gen_rtx_SET (VOIDmode, y1,
18628 gen_rtx_PLUS (SFmode,
18629 gen_rtx_MULT (SFmode, e1, x0), x0)));
18630 /* u0 = n * y1 */
18631 emit_insn (gen_rtx_SET (VOIDmode, u0,
18632 gen_rtx_MULT (SFmode, n, y1)));
18633 /* v0 = n - d * u0 */
18634 emit_insn (gen_rtx_SET (VOIDmode, v0,
18635 gen_rtx_MINUS (SFmode, n,
18636 gen_rtx_MULT (SFmode, d, u0))));
18637 /* res = u0 + v0 * y1 */
18638 emit_insn (gen_rtx_SET (VOIDmode, res,
18639 gen_rtx_PLUS (SFmode,
18640 gen_rtx_MULT (SFmode, v0, y1), u0)));
18643 /* Newton-Raphson approximation of double-precision floating point divide n/d.
18644 Assumes no trapping math and finite arguments. */
18646 void
18647 rs6000_emit_swdivdf (rtx res, rtx n, rtx d)
18649 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
18651 x0 = gen_reg_rtx (DFmode);
18652 e0 = gen_reg_rtx (DFmode);
18653 e1 = gen_reg_rtx (DFmode);
18654 e2 = gen_reg_rtx (DFmode);
18655 y1 = gen_reg_rtx (DFmode);
18656 y2 = gen_reg_rtx (DFmode);
18657 y3 = gen_reg_rtx (DFmode);
18658 u0 = gen_reg_rtx (DFmode);
18659 v0 = gen_reg_rtx (DFmode);
18660 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
18662 /* x0 = 1./d estimate */
18663 emit_insn (gen_rtx_SET (VOIDmode, x0,
18664 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
18665 UNSPEC_FRES)));
18666 /* e0 = 1. - d * x0 */
18667 emit_insn (gen_rtx_SET (VOIDmode, e0,
18668 gen_rtx_MINUS (DFmode, one,
18669 gen_rtx_MULT (SFmode, d, x0))));
18670 /* y1 = x0 + e0 * x0 */
18671 emit_insn (gen_rtx_SET (VOIDmode, y1,
18672 gen_rtx_PLUS (DFmode,
18673 gen_rtx_MULT (DFmode, e0, x0), x0)));
18674 /* e1 = e0 * e0 */
18675 emit_insn (gen_rtx_SET (VOIDmode, e1,
18676 gen_rtx_MULT (DFmode, e0, e0)));
18677 /* y2 = y1 + e1 * y1 */
18678 emit_insn (gen_rtx_SET (VOIDmode, y2,
18679 gen_rtx_PLUS (DFmode,
18680 gen_rtx_MULT (DFmode, e1, y1), y1)));
18681 /* e2 = e1 * e1 */
18682 emit_insn (gen_rtx_SET (VOIDmode, e2,
18683 gen_rtx_MULT (DFmode, e1, e1)));
18684 /* y3 = y2 + e2 * y2 */
18685 emit_insn (gen_rtx_SET (VOIDmode, y3,
18686 gen_rtx_PLUS (DFmode,
18687 gen_rtx_MULT (DFmode, e2, y2), y2)));
18688 /* u0 = n * y3 */
18689 emit_insn (gen_rtx_SET (VOIDmode, u0,
18690 gen_rtx_MULT (DFmode, n, y3)));
18691 /* v0 = n - d * u0 */
18692 emit_insn (gen_rtx_SET (VOIDmode, v0,
18693 gen_rtx_MINUS (DFmode, n,
18694 gen_rtx_MULT (DFmode, d, u0))));
18695 /* res = u0 + v0 * y3 */
18696 emit_insn (gen_rtx_SET (VOIDmode, res,
18697 gen_rtx_PLUS (DFmode,
18698 gen_rtx_MULT (DFmode, v0, y3), u0)));
18701 /* Return an RTX representing where to find the function value of a
18702 function returning MODE. */
18703 static rtx
18704 rs6000_complex_function_value (enum machine_mode mode)
18706 unsigned int regno;
18707 rtx r1, r2;
18708 enum machine_mode inner = GET_MODE_INNER (mode);
18709 unsigned int inner_bytes = GET_MODE_SIZE (inner);
18711 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
18712 regno = FP_ARG_RETURN;
18713 else
18715 regno = GP_ARG_RETURN;
18717 /* 32-bit is OK since it'll go in r3/r4. */
18718 if (TARGET_32BIT && inner_bytes >= 4)
18719 return gen_rtx_REG (mode, regno);
18722 if (inner_bytes >= 8)
18723 return gen_rtx_REG (mode, regno);
18725 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
18726 const0_rtx);
18727 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
18728 GEN_INT (inner_bytes));
18729 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
18732 /* Define how to find the value returned by a function.
18733 VALTYPE is the data type of the value (as a tree).
18734 If the precise function being called is known, FUNC is its FUNCTION_DECL;
18735 otherwise, FUNC is 0.
18737 On the SPE, both FPs and vectors are returned in r3.
18739 On RS/6000 an integer value is in r3 and a floating-point value is in
18740 fp1, unless -msoft-float. */
18743 rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
18745 enum machine_mode mode;
18746 unsigned int regno;
18748 /* Special handling for structs in darwin64. */
18749 if (rs6000_darwin64_abi
18750 && TYPE_MODE (valtype) == BLKmode
18751 && TREE_CODE (valtype) == RECORD_TYPE
18752 && int_size_in_bytes (valtype) > 0)
18754 CUMULATIVE_ARGS valcum;
18755 rtx valret;
18757 valcum.words = 0;
18758 valcum.fregno = FP_ARG_MIN_REG;
18759 valcum.vregno = ALTIVEC_ARG_MIN_REG;
18760 /* Do a trial code generation as if this were going to be passed as
18761 an argument; if any part goes in memory, we return NULL. */
18762 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
18763 if (valret)
18764 return valret;
18765 /* Otherwise fall through to standard ABI rules. */
18768 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
18770 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
18771 return gen_rtx_PARALLEL (DImode,
18772 gen_rtvec (2,
18773 gen_rtx_EXPR_LIST (VOIDmode,
18774 gen_rtx_REG (SImode, GP_ARG_RETURN),
18775 const0_rtx),
18776 gen_rtx_EXPR_LIST (VOIDmode,
18777 gen_rtx_REG (SImode,
18778 GP_ARG_RETURN + 1),
18779 GEN_INT (4))));
18782 if ((INTEGRAL_TYPE_P (valtype)
18783 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
18784 || POINTER_TYPE_P (valtype))
18785 mode = TARGET_32BIT ? SImode : DImode;
18786 else
18787 mode = TYPE_MODE (valtype);
18789 if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
18790 regno = FP_ARG_RETURN;
18791 else if (TREE_CODE (valtype) == COMPLEX_TYPE
18792 && targetm.calls.split_complex_arg)
18793 return rs6000_complex_function_value (mode);
18794 else if (TREE_CODE (valtype) == VECTOR_TYPE
18795 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
18796 && ALTIVEC_VECTOR_MODE (mode))
18797 regno = ALTIVEC_ARG_RETURN;
18798 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
18799 && (mode == DFmode || mode == DCmode))
18800 return spe_build_register_parallel (mode, GP_ARG_RETURN);
18801 else
18802 regno = GP_ARG_RETURN;
18804 return gen_rtx_REG (mode, regno);
18807 /* Define how to find the value returned by a library function
18808 assuming the value has mode MODE. */
18810 rs6000_libcall_value (enum machine_mode mode)
18812 unsigned int regno;
18814 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
18816 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
18817 return gen_rtx_PARALLEL (DImode,
18818 gen_rtvec (2,
18819 gen_rtx_EXPR_LIST (VOIDmode,
18820 gen_rtx_REG (SImode, GP_ARG_RETURN),
18821 const0_rtx),
18822 gen_rtx_EXPR_LIST (VOIDmode,
18823 gen_rtx_REG (SImode,
18824 GP_ARG_RETURN + 1),
18825 GEN_INT (4))));
18828 if (GET_MODE_CLASS (mode) == MODE_FLOAT
18829 && TARGET_HARD_FLOAT && TARGET_FPRS)
18830 regno = FP_ARG_RETURN;
18831 else if (ALTIVEC_VECTOR_MODE (mode)
18832 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
18833 regno = ALTIVEC_ARG_RETURN;
18834 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
18835 return rs6000_complex_function_value (mode);
18836 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
18837 && (mode == DFmode || mode == DCmode))
18838 return spe_build_register_parallel (mode, GP_ARG_RETURN);
18839 else
18840 regno = GP_ARG_RETURN;
18842 return gen_rtx_REG (mode, regno);
18845 /* Define the offset between two registers, FROM to be eliminated and its
18846 replacement TO, at the start of a routine. */
18847 HOST_WIDE_INT
18848 rs6000_initial_elimination_offset (int from, int to)
18850 rs6000_stack_t *info = rs6000_stack_info ();
18851 HOST_WIDE_INT offset;
18853 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
18854 offset = info->push_p ? 0 : -info->total_size;
18855 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
18857 offset = info->push_p ? 0 : -info->total_size;
18858 if (FRAME_GROWS_DOWNWARD)
18859 offset += info->fixed_size + info->vars_size + info->parm_size;
18861 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
18862 offset = FRAME_GROWS_DOWNWARD
18863 ? info->fixed_size + info->vars_size + info->parm_size
18864 : 0;
18865 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
18866 offset = info->total_size;
18867 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
18868 offset = info->push_p ? info->total_size : 0;
18869 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
18870 offset = 0;
18871 else
18872 gcc_unreachable ();
18874 return offset;
18877 /* Return true if TYPE is a SPE or AltiVec opaque type. */
18879 static bool
18880 rs6000_is_opaque_type (tree type)
18882 return (type == opaque_V2SI_type_node
18883 || type == opaque_V2SF_type_node
18884 || type == opaque_p_V2SI_type_node
18885 || type == opaque_V4SI_type_node);
18888 static rtx
18889 rs6000_dwarf_register_span (rtx reg)
18891 unsigned regno;
18893 if (TARGET_SPE
18894 && (SPE_VECTOR_MODE (GET_MODE (reg))
18895 || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
18897 else
18898 return NULL_RTX;
18900 regno = REGNO (reg);
18902 /* The duality of the SPE register size wreaks all kinds of havoc.
18903 This is a way of distinguishing r0 in 32-bits from r0 in
18904 64-bits. */
18905 return
18906 gen_rtx_PARALLEL (VOIDmode,
18907 BYTES_BIG_ENDIAN
18908 ? gen_rtvec (2,
18909 gen_rtx_REG (SImode, regno + 1200),
18910 gen_rtx_REG (SImode, regno))
18911 : gen_rtvec (2,
18912 gen_rtx_REG (SImode, regno),
18913 gen_rtx_REG (SImode, regno + 1200)));
18916 /* Map internal gcc register numbers to DWARF2 register numbers. */
18918 unsigned int
18919 rs6000_dbx_register_number (unsigned int regno)
18921 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
18922 return regno;
18923 if (regno == MQ_REGNO)
18924 return 100;
18925 if (regno == LINK_REGISTER_REGNUM)
18926 return 108;
18927 if (regno == COUNT_REGISTER_REGNUM)
18928 return 109;
18929 if (CR_REGNO_P (regno))
18930 return regno - CR0_REGNO + 86;
18931 if (regno == XER_REGNO)
18932 return 101;
18933 if (ALTIVEC_REGNO_P (regno))
18934 return regno - FIRST_ALTIVEC_REGNO + 1124;
18935 if (regno == VRSAVE_REGNO)
18936 return 356;
18937 if (regno == VSCR_REGNO)
18938 return 67;
18939 if (regno == SPE_ACC_REGNO)
18940 return 99;
18941 if (regno == SPEFSCR_REGNO)
18942 return 612;
18943 /* SPE high reg number. We get these values of regno from
18944 rs6000_dwarf_register_span. */
18945 gcc_assert (regno >= 1200 && regno < 1232);
18946 return regno;
18949 /* target hook eh_return_filter_mode */
18950 static enum machine_mode
18951 rs6000_eh_return_filter_mode (void)
18953 return TARGET_32BIT ? SImode : word_mode;
18956 /* Target hook for vector_mode_supported_p. */
18957 static bool
18958 rs6000_vector_mode_supported_p (enum machine_mode mode)
18961 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
18962 return true;
18964 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
18965 return true;
18967 else
18968 return false;
18971 /* Target hook for invalid_arg_for_unprototyped_fn. */
18972 static const char *
18973 invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
18975 return (!rs6000_darwin64_abi
18976 && typelist == 0
18977 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
18978 && (funcdecl == NULL_TREE
18979 || (TREE_CODE (funcdecl) == FUNCTION_DECL
18980 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
18981 ? N_("AltiVec argument passed to unprototyped function")
18982 : NULL;
18985 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
18986 setup by using __stack_chk_fail_local hidden function instead of
18987 calling __stack_chk_fail directly. Otherwise it is better to call
18988 __stack_chk_fail directly. */
18990 static tree
18991 rs6000_stack_protect_fail (void)
18993 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
18994 ? default_hidden_stack_protect_fail ()
18995 : default_external_stack_protect_fail ();
18998 #include "gt-rs6000.h"